From 41b0080fcc8fcace7cd62d238f6a932e79ec8bb1 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 52bf5f1f3a..111621bb52 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 @@ -58,8 +58,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; @@ -71,10 +74,18 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec out) throws Exception { - String acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); + CharSequence acceptedEncoding = msg.headers().get(HttpHeaders.Names.ACCEPT_ENCODING); if (acceptedEncoding == null) { acceptedEncoding = HttpHeaders.Values.IDENTITY; } + + HttpMethod meth = msg.getMethod(); + 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)); } @@ -89,12 +100,24 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec