From 757671b7cc494cdd25e50c3a3d94c27f83bb201c Mon Sep 17 00:00:00 2001 From: Roelof Naude Date: Thu, 7 May 2015 08:53:34 +0200 Subject: [PATCH] Support empty http responses when using compression Motivation: Found a bug in that netty would generate a 20 byte body when returing a response to an HTTP HEAD. the 20 bytes seems to be related to the compression footer. RFC2616, section 9.4 states that responses to an HTTP HEAD MUST not return a message body in the response. Netty's own client implementation expected an empty response. The extra bytes lead to a 2nd response with an error decoder result: java.lang.IllegalArgumentException: invalid version format: 14 Modifications: Track the HTTP request method. When processing the response we determine if the response is passthru unnchanged. This decision now takes into account the request method and passthru responses related to HTTP HEAD requests. Result: Netty's http client works and better RFC conformance. --- .../codec/http/HttpContentEncoder.java | 44 ++++++--- .../codec/http/HttpContentEncoderTest.java | 90 +++++++++++++++++++ 2 files changed, 121 insertions(+), 13 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java index 6b3778ed09..7e34465bb3 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpContentEncoder.java @@ -56,8 +56,11 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec acceptEncodingQueue = new ArrayDeque(); - private String acceptEncoding; + private static final CharSequence ZERO_LENGTH_HEAD = "HEAD"; + private static final CharSequence ZERO_LENGTH_CONNECT = "CONNECT"; + + private final Queue acceptEncodingQueue = new ArrayDeque(); + private CharSequence acceptEncoding; private EmbeddedChannel encoder; private State state = State.AWAIT_HEADERS; @@ -69,10 +72,18 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec out) throws Exception { - String acceptedEncoding = msg.headers().get(HttpHeaderNames.ACCEPT_ENCODING); + CharSequence acceptedEncoding = msg.headers().get(HttpHeaderNames.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpContentDecoder.IDENTITY; } + + HttpMethod meth = msg.method(); + if (meth == HttpMethod.HEAD) { + acceptedEncoding = ZERO_LENGTH_HEAD; + } else if (meth == HttpMethod.CONNECT) { + acceptedEncoding = ZERO_LENGTH_CONNECT; + } + acceptEncodingQueue.add(acceptedEncoding); out.add(ReferenceCountUtil.retain(msg)); } @@ -87,12 +98,24 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec