diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java index 64d7695264..b97852d258 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectDecoder.java @@ -21,7 +21,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPipeline; import io.netty.channel.MessageList; import io.netty.handler.codec.DecoderResult; -import io.netty.handler.codec.PrematureChannelClosureException; import io.netty.handler.codec.ReplayingDecoder; import io.netty.handler.codec.TooLongFrameException; @@ -436,11 +435,7 @@ public abstract class HttpObjectDecoder extends ReplayingDecoder= 0 && actualContentLength != expectedContentLength; } - if (prematureClosure) { - message.setDecoderResult(DecoderResult.failure(new PrematureChannelClosureException())); + if (!prematureClosure) { + if (actualContentLength == 0) { + out.add(LastHttpContent.EMPTY_LAST_CONTENT); + } else { + out.add(new DefaultLastHttpContent(content)); + } } } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java index 5c84ddb38c..1cd8e4202a 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpResponseDecoderTest.java @@ -25,7 +25,7 @@ import static org.junit.Assert.*; public class HttpResponseDecoderTest { @Test - public void testEmptyHeaderAndEmptyContent() { + public void testLastResponseWithEmptyHeaderAndEmptyContent() { EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder()); ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.1 200 OK\r\n\r\n", CharsetUtil.US_ASCII)); @@ -41,4 +41,26 @@ public class HttpResponseDecoderTest { assertThat(ch.readInbound(), is(nullValue())); } + + @Test + public void testLastResponseWithoutContentLengthHeader() { + EmbeddedChannel ch = new EmbeddedChannel(new HttpResponseDecoder()); + ch.writeInbound(Unpooled.copiedBuffer("HTTP/1.1 200 OK\r\n\r\n", CharsetUtil.US_ASCII)); + + HttpResponse res = (HttpResponse) ch.readInbound(); + assertThat(res.getProtocolVersion(), sameInstance(HttpVersion.HTTP_1_1)); + assertThat(res.getStatus(), is(HttpResponseStatus.OK)); + assertThat(ch.readInbound(), is(nullValue())); + + ch.writeInbound(Unpooled.wrappedBuffer(new byte[1024])); + HttpContent content = (HttpContent) ch.readInbound(); + assertThat(content.content().readableBytes(), is(1024)); + + assertThat(ch.finish(), is(true)); + + LastHttpContent lastContent = (LastHttpContent) ch.readInbound(); + assertThat(lastContent.content().isReadable(), is(false)); + + assertThat(ch.readInbound(), is(nullValue())); + } } diff --git a/transport/src/main/java/io/netty/channel/MessageList.java b/transport/src/main/java/io/netty/channel/MessageList.java index d6ba0b5287..cba1c8c054 100644 --- a/transport/src/main/java/io/netty/channel/MessageList.java +++ b/transport/src/main/java/io/netty/channel/MessageList.java @@ -184,6 +184,18 @@ public final class MessageList implements Iterable { return elements[index]; } + /** + * Sets the message on the given index. + */ + public MessageList set(int index, T value) { + checkExclusive(index); + if (value == null) { + throw new NullPointerException("value"); + } + elements[index] = value; + return this; + } + /** * Add the message to this {@link MessageList} and return itself. */ diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java index 251c5aa319..4b90cb8662 100755 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java @@ -280,6 +280,15 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty long expectedWrittenBytes = 0; for (int i = index; i < size; i++) { ByteBuf buf = bufs.get(i); + if (!buf.isDirect()) { + int readableBytes = buf.readableBytes(); + ByteBuf directBuf = alloc().directBuffer(readableBytes); + directBuf.writeBytes(buf, buf.readerIndex(), readableBytes); + buf.release(); + bufs.set(i, directBuf); + buf = directBuf; + } + int count = buf.nioBufferCount(); if (count == 1) { if (nioBufferCnt == nioBuffers.length) {