Support of Expect: 100-continue for small requests in HttpMessageDecoder
bgranvea
boris at granveaud.com
Wed Aug 31 04:55:45 EDT 2011
Hi,
I've got a problem with the support of Expect: 100-Continue HTTP header. It
works only if I send a large request. For small requests, the client doesn't
receive the 100 Continue response. In fact, it is received but AFTER posting
the whole request.
Note: I'm using *Netty extension 1.1.9* for the moment, so I'm not sure if
this problem still exists in Netty 4.0.0
I've set up my pipeline like this:
pipeline.addLast("httpDecoder", new HttpRequestDecoder());
pipeline.addLast("httpEncoder", new HttpResponseEncoder());
pipeline.addLast("httpParser", new MyHttpRequestParser());
pipeline.addLast("executionHandler", new
OrderedMemoryAwareThreadPoolExecutor(100, 0, 0));
pipeline.addLast("serviceRequestHandler", new MyBusinessLogicHandler());
In MyHttpRequestParser, I've added this to write a 100 Continue when needed:
public class MyHttpRequestParserextends SimpleChannelUpstreamHandler {
private void send100Continue(MessageEvent e) {
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
HttpResponseStatus.CONTINUE);
e.getChannel().write(response);
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
if (!readingChunks) {
HttpRequest request = (HttpRequest) e.getMessage();
boolean is100ContinueExpected =
Values.CONTINUE.equalsIgnoreCase(request.getHeader(Names.EXPECT));
if (is100ContinueExpected) {
send100Continue(e);
}
...
On the client side, I'm using HTTPClient 3.1 like this:
PostMethod post = new PostMethod(url);
post.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE,
true);
RequestEntity entity = new StringRequestEntity(data, "application/xml",
"UTF-8");
post.setRequestEntity(entity);
I can see by enabling HTTPClient logging that if the request entity is too
small, HTTPClient times out waiting for 100 Continue, but if request entity
is large enough (>8000 bytes), everything works as expected.
>From what I understand, the problem is here in HttpMessageDecoder:
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer, State state) throws Exception {
...
switch (nextState) {
case READ_FIXED_LENGTH_CONTENT:
if (contentLength > maxChunkSize) {
// Generate HttpMessage first. HttpChunks will
follow.
checkpoint(State.READ_FIXED_LENGTH_CONTENT_AS_CHUNKS);
message.setChunked(true);
// chunkSize will be decreased as the
READ_FIXED_LENGTH_CONTENT_AS_CHUNKS
// state reads data chunk by chunk.
chunkSize = HttpHeaders.getContentLength(message,
-1);
return message;
}
break;
When contentLength is less than maxChunkSize (8192 by default), no
HttpRequest message is sent in the pipeline, so my handler doesn't know it
must respond something. And when it receives an HttpRequest because
HTTPClient timed out and sent the rest of the data, it is too late. In this
case, HTTP Client logs this:
2011-08-31 10:45:02,215 [main] DEBUG h.w.header:{Wire.java:70} - >> "Expect:
100-continue[\r][\n]"
2011-08-31 10:45:02,215 [main] DEBUG h.w.header:{Wire.java:70} - >>
"Content-Length: 1268[\r][\n]"
2011-08-31 10:45:02,215 [main] DEBUG h.w.header:{Wire.java:70} - >>
"[\r][\n]"
2011-08-31 10:45:05,215 [main] INFO
o.a.c.h.HttpMethodBase:{HttpMethodBase.java:2102} - 100 (continue) read
timeout. Resume sending the request
2011-08-31 10:45:05,215 [main] DEBUG
o.a.c.h.m.EntityEnclosingMethod:{EntityEnclosingMethod.java:508} - Request
body sent
2011-08-31 10:45:05,231 [main] DEBUG h.w.header:{Wire.java:70} - <<
"HTTP/1.1 100 Continue[\r][\n]"
2011-08-31 10:45:05,231 [main] DEBUG h.w.header:{Wire.java:70} - <<
"HTTP/1.1 100 Continue[\r][\n]"
2011-08-31 10:45:05,231 [main] DEBUG h.w.header:{Wire.java:70} - <<
"[\r][\n]"
2011-08-31 10:45:05,231 [main] INFO
o.a.c.h.HttpMethodBase:{HttpMethodBase.java:1743} - Discarding unexpected
response: HTTP/1.1 100 Continue
I know it is not very common to use a Expect: 100-continue with small
requests :) In fact I found out this problem only because I'm doing an
integration test to check that my server handles correctly this type of
requests.
Boris.
--
View this message in context: http://netty-forums-and-mailing-lists.685743.n2.nabble.com/Support-of-Expect-100-continue-for-small-requests-in-HttpMessageDecoder-tp6745676p6745676.html
Sent from the Netty User Group mailing list archive at Nabble.com.
More information about the netty-users
mailing list