diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java index 6ca638d537..a398f07bc9 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.TooLongFrameException; +import org.jboss.netty.handler.codec.http.HttpMessageDecoder.State; import org.jboss.netty.handler.codec.replay.ReplayingDecoder; import java.util.List; @@ -98,7 +99,7 @@ import java.util.List; * implement all abstract methods properly. * @apiviz.landmark */ -public abstract class HttpMessageDecoder extends ReplayingDecoder { +public abstract class HttpMessageDecoder extends ReplayingDecoder { private final int maxInitialLineLength; private final int maxHeaderSize; @@ -126,7 +127,8 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder 0) { + // Keep on consuming as otherwise we may trigger an DecoderException, + // other handler will replace this codec with the upgraded protocol codec to + // take the traffic over at some point then. + // See https://github.com/netty/netty/issues/2173 + return buffer.readBytes(actualReadableBytes()); + } else { + return null; + } + } default: { throw new Error("Shouldn't reach here."); } @@ -439,6 +453,14 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder ch = new DecoderEmbedder(new HttpResponseDecoder()); + ch.offer(ChannelBuffers.wrappedBuffer(data)); + + HttpResponse res = (HttpResponse) ch.poll(); + assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1)); + assertThat(res.getStatus(), is(HttpResponseStatus.SWITCHING_PROTOCOLS)); + assertThat(res.getContent().readableBytes(), is(16)); + + assertThat(ch.finish(), is(false)); + + assertThat(ch.poll(), is(nullValue())); + } + + // See https://github.com/netty/netty/issues/2173 + @Test + public void testWebSocketResponseWithDataFollowing() { + byte[] data = ("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" + + "Upgrade: WebSocket\r\n" + + "Connection: Upgrade\r\n" + + "Sec-WebSocket-Origin: http://localhost:8080\r\n" + + "Sec-WebSocket-Location: ws://localhost/some/path\r\n" + + "\r\n" + + "1234567812345678").getBytes(); + byte[] otherData = {1, 2, 3, 4}; + + DecoderEmbedder ch = new DecoderEmbedder(new HttpResponseDecoder()); + ch.offer(ChannelBuffers.wrappedBuffer(data, otherData)); + + HttpResponse res = (HttpResponse) ch.poll(); + assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1)); + assertThat(res.getStatus(), is(HttpResponseStatus.SWITCHING_PROTOCOLS)); + assertThat(res.getContent().readableBytes(), is(16)); + + assertThat(ch.finish(), is(true)); + + assertEquals(ch.poll(), ChannelBuffers.wrappedBuffer(otherData)); + } +}