
I just spent a few hours debugging a performance problem with my app. It came down to a default setting inside
Apache HttpClient 4.0.3.
Don't get me wrong,
HttpClient is an awesome piece of work and a fantastic contribution to the community - I use it in lots of my projects and it's very useful. So my thanks to the HttpClient team for all their hard work.
However, by default HttpClient 4.0.3 adds a...
Expect: 100-continue
...header to every
POST request. This appears to interact badly with Tomcat's (and JBoss', and possibly other containers)
FormAuthenticator. Specifically somewhere around...
request.getParameter( Constants.FORM_USERNAME )
...
FormAuthenticator disappears into a hole (during
Request.parseParameters) for some 2 seconds before emerging with the parameters. It appears to be 'lazy loading' the request body during this time? According to the
HTTP spec the header "allows a client that is sending a request message with a request body to determine if the origin server is willing to accept the request before the client sends the request body".
If you're using HttpClient to log in to your Java EE server (say, for
black box testing) this can be a significant performance hit. Removing the
Expect header logs you in in about 8ms,
some 250 times faster.
You can remove the
Expect header by doing:
client.removeRequestInterceptorByClass( RequestExpectContinue.class );
I've put together a sample WAR to reproduce the problem, along with deployment instructions, under
this issue here.
Update: it appears this is actually a bug in Tomcat 6. Now tracking under this issue here.