Implementing If-Match HTTP Header in Spring - java

The ShallowEtagHeaderFilter which is part of Spring processes the If-None-Match header on an Http request. As part of the Http 1.1 spec this returns an Http status of 304 - Not Modified if the contents of the If-None-Match header sent on the request is the same as the Etag header. This is helpful for caching as it means that if the Etag is the same on the client and server then the contents will be identical.
This is fine.
However my question is this - does Spring have support for the If-Match header (again part of HTTP 1.1) rather than If-None-Match because as far as the docs go it looks like the ShallowEtagHeaderFilter only processes the If-None-Match header. I need the If-Match header to prevent simultaneous requests from overwriting the previous one. IE I only want the request to be processed if the Etags are the same and hence they have the latest version of the entity.

It doesn't look like the ShallowEtagHeaderFilter supports If-Match:
curl "Accept: application/json" -H 'If-Match: "somevalue"' -i http://localhost:8080/rest-sec/api/resources/1
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: "03cb37ca667706c68c0aad4cb04c3a211"
Content-Type: application/json;charset=UTF-8
Content-Length: 56
Date: Fri, 11 Jan 2013 14:58:40 GMT
I opened a JIRA issue to track this:
https://jira.springsource.org/browse/SPR-10164

Related

Tracing timestamp of XML request/responses with JAX-WS

We have created a JAX-WS webservice, this service is being invoked by multiple clients. Some clients have configured timeout for API response. Even after sending success response, some client are stating that request is being timed out.
So is there any way to track, at what time a particular request hits the server and what time server responded back ?
I've enable http traces in weblogic server by using below properties
-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
And request and response are appearing like below, where timestamp is missing
---[HTTP request - ]---
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
---[HTTP response 200]---
null: HTTP/1.1 200 OK
Content-Length: 521
Content-Type: text/xml;charset=UTF-8
Weblogic Version is - 12.2.1

How can I get Jetty to return an error response instead of assuming an HTTP/0.9 request?

A broken HTTP client sent some requests to our Jetty-based HTTP server with a newline in the URL. Jetty sees this as an HTTP/0.9 request, truncates the URL at the newline, ignores the request headers, and sends back a response with no headers or status line.
I believe this is mostly correct according to spec, although Jetty doesn't require CRLF and will happily do this for requests other than GET. But newer specs note that HTTP/0.9 requests mainly indicate confused clients. In our case, the client (and we) could have avoided some confused troubleshooting if an error message had been sent instead.
How can I get Jetty to return an error response to requests with a newline in the URL? I'm happy to use either Jetty-level configuration or webapp-level code.
First, support for HTTP/0.9 has been completely removed in Jetty 9.3+.
Lets see what the behavior is ...
Jetty Distribution 9.2.7.v20150116, running demo-base:
Normal HTTP/1.0 Request:
$ printf "GET / HTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Server: Jetty(9.2.7.v20150116)
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
Got the headers there, looks like HTTP/1.0 response headers too.
Normal HTTP/1.1 Request:
$ printf "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Connection: close
Server: Jetty(9.2.7.v20150116)
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
Looks normal as well.
Even includes the HTTP/1.1 specific headers.
Now lets try HTTP/1.0 with embedded CRLF:
$ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
No response headers.
Why is this happening?
Well, there's no HTTP Version that Jetty can determine, so there's no valid set of headers it can respond with. So it responds with no headers. Which surprisingly is how HTTP spec prior to 1.0 behaved.
Now lets try Jetty Distribution 9.3.x, and the demo-base configuration with the same CRLF issue.
$ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 400 HTTP/0.9 not supported
Content-Length: 0
Connection: close
Server: Jetty(9.3.0-SNAPSHOT)
Now, in the modern era, with HTTP/2 just around the corner, this makes a lot more sense.
HttpServletRequest#getProtocol() will return an empty String for HTTP/0.9 requests in Jetty 8. Thus a simple filter can return a Bad Request response for such requests.
As the other answer indicates, HTTP/0.9 requests are no longer supported in recent versions of Jetty 9.

Transfer-encoding header already present error in JMeter HTTP Request

I keep getting the following error in my Response data tab in jmeter:
org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:481)
at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:298)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1105)
at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1094)
at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:429)
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:257)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.http.ProtocolException: Transfer-encoding header already present
at org.apache.http.protocol.RequestContent.process(RequestContent.java:93)
at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:109)
at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:176)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:518)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
... 9 more
My test script was created via the JMeter Proxy. The test is sending multipart data (a jpg image) to a REST API resource via a POST. The HTTP Header Manager auto created by the Recording Controller in JMeter has the following:
Transfer-Encoding : chunked
Accept : application/json
Accept-Encoding : gzip, deflate
Any idea why the Response is getting an error?
Request:
POST http://localhost:8080/email/v2/client/user/name/loadtest1#test.net/
POST data:
--oYtJU-XXTgMSkyaIrRBYNXw8AfMA2nMQSzJ20bJr--
Cookie Data:
JSESSIONID=b3bb843e-dafd-4cc5-8b0b-045c490736f8
Request Headers:
Connection: keep-alive
Transfer-Encoding: chunked
Accept: application/json
Accept-Encoding: gzip, deflate
Try removing from HTTP Header Manager the Transfer-Encoding header.
Can you show you Http Request in your Question ? and the Header Manager in it ?
What is the status of the following parameters of the http request which is failing:
Use multipart/form-data for HTTP POST
Browser-compatible headers
You don't have any HTTP Header Manager instances elsewhere in you test plan, do you? As if yes it may interfere as HTTP Header Manager's scope isn't limited to one sampler only when it is not added as a child.
Your post request details doesn't look like file upload request. Take a look into Upload and Download Scenarios with Apache JMeter guide to see whether you missed anything important.
Never run load generator and application under test on the same machine. Even when developing or debugging your test.

CXF REST service is returning more than 1 http code

When I run my service, which is just a simple POST, I'm getting an HTTP 100 followed by a 200.
Is there any way to get it to just return an HTTP 200?
curl -D- -X POST -H "Content-Type: application/json" -d #input.json http://myserver/contxt/services/rest/service/notify
Returns:
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Date: Thu, 17 Jul 2014 14:20:05 GMT
Content-Type: text/plain
Content-Length: 2
The status code 100 is not the response to the whole request. The server is telling that he has received the headers and the client should proceed sending the request body. Sending the entity with e.g. a Content-Type the server won't accept anyway would be just a waste of bandwidth.
The server should only send the status 100 if he has received the header Expect: 100-continue. cURL is sending this header "for POSTs with unknown sizes". This may be the case for big files.
You can try to explicitly overwrite this header:
curl -H "Expect:" ...

Could not complete the operation due to error c00ce56e

I've upgraded from rich faces 3.3 to rich faces 4.2 because ajax didn't work for IE9. Now it still not works.
After receiving the Response IE gets an JS error "SCRIPT58734: Der Vorgang konnte aufgrund des folgenden Fehlers nicht fortgesetzt werden: c00ce56e." while trying
data.responseText=request.responseText
on jsf.js.html?ln=javax.faces&conversationContext=2, Line 1 Row 21747
I think it's because of an incorrecct HTTP header
Content-Type: text/xml;charset=UTF8
should be
Content-Type: text/xml;charset=UTF-8
Here The raw-response of the server
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: JSF/2.0
Cache-Control: no-cache
Content-Type: text/xml;charset=UTF8
Content-Length: 293
Date: Tue, 17 Apr 2012 15:25:22 GMT
<?xml version='1.0' encoding='UTF8'?>
<partial-response><changes><update id="outtest"><![CDATA[<span id="outtest"><span class="outhello">Hello !</span></span>]]></update><update id="javax.faces.ViewState"><![CDATA[2809980525147413088:295565165947012503]]></update></changes></partial-response>
i'm usinng
javaee-web-api 6
myfaces-orchestra-core 1.4
Hibernate 4.1
Spring 3.1.1
Richfaces 4.2.0
Primefaces 3.2
jsf-api+impl 2.1.7
jstl 1.2
and running on tomcat 7
EDIT:
of now i'm sure its the header. I set a breakpoint in charles-proxy and edited the response header manually, with the edited http header IE9 showed the right result without any errors
Your analysis is correct. The charset attribute in the Content-Type header is wrong and IE9 chokes on that with error c00ce56e.
JSF uses by default the one as obtained from ServletRequest#getCharacterEncoding(). This normally defaults to the client-specified one, or null if there's none (which is often the case). This is normally overrideable by some custom filter which calls request.setCharacterEncoding().
Given the incorrect charset, this can only mean that your web application is somewhere calling request.setCharacterEncoding() with "UTF8" instead of "UTF-8".
I'd start checking all filters and their configuration.
i got similar error but the problem was with the response headers content length. We had 24kb of data on the request header and we have to reduce it to half. That fixed the issue. i hope this helps someone.

Categories