diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessageDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessageDecoder.java index 43fcdaca50..7310db7966 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessageDecoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpMessageDecoder.java @@ -106,6 +106,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder maxChunkSize) { + toRead = maxChunkSize; + } + if (!message.isChunked()) { + message.setChunked(true); + return new Object[] {message, new DefaultHttpChunk(buffer.readBytes(toRead))}; + } else { + return new DefaultHttpChunk(buffer.readBytes(toRead)); } - //this will cause a replay error until the channel is closed where this will read what's left in the buffer - content.writeBytes(buffer.readBytes(buffer.readableBytes())); - return reset(); } case READ_VARIABLE_LENGTH_CONTENT_AS_CHUNKS: { // Keep reading data as a chunk until the end of connection is reached. - int chunkSize = Math.min(maxChunkSize, buffer.readableBytes()); - HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes(chunkSize)); + int toRead = actualReadableBytes(); + if (toRead > maxChunkSize) { + toRead = maxChunkSize; + } + HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes(toRead)); if (!buffer.readable()) { // Reached to the end of the connection. @@ -258,19 +266,23 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder maxChunkSize) { - chunk = new DefaultHttpChunk(buffer.readBytes(maxChunkSize)); - chunkSize -= maxChunkSize; + assert this.chunkSize <= Integer.MAX_VALUE; + int chunkSize = (int) this.chunkSize; + int readLimit = actualReadableBytes(); + int toRead = chunkSize; + if (toRead > maxChunkSize) { + toRead = maxChunkSize; + } + if (toRead > readLimit) { + toRead = readLimit; + } + HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes(toRead)); + if (chunkSize > toRead) { + chunkSize -= toRead; } else { - assert chunkSize <= Integer.MAX_VALUE; - chunk = new DefaultHttpChunk(buffer.readBytes((int) chunkSize)); chunkSize = 0; } this.chunkSize = chunkSize; @@ -310,14 +322,20 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder maxChunkSize) { - chunk = new DefaultHttpChunk(buffer.readBytes(maxChunkSize)); - chunkSize -= maxChunkSize; + assert this.chunkSize <= Integer.MAX_VALUE; + int chunkSize = (int) this.chunkSize; + int readLimit = actualReadableBytes(); + int toRead = chunkSize; + if (toRead > maxChunkSize) { + toRead = maxChunkSize; + } + if (toRead > readLimit) { + toRead = readLimit; + } + HttpChunk chunk = new DefaultHttpChunk(buffer.readBytes(toRead)); + if (chunkSize > toRead) { + chunkSize -= toRead; } else { - assert chunkSize <= Integer.MAX_VALUE; - chunk = new DefaultHttpChunk(buffer.readBytes((int) chunkSize)); chunkSize = 0; } this.chunkSize = chunkSize; @@ -414,15 +432,29 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder actualReadableBytes()) { + toRead = actualReadableBytes(); + } + contentRead = contentRead + toRead; + if (length < contentRead) { + if (!message.isChunked()) { + message.setChunked(true); + return new Object[] {message, new DefaultHttpChunk(buffer.readBytes(toRead))}; + } else { + return new DefaultHttpChunk(buffer.readBytes(toRead)); + } + } if (content == null) { content = buffer.readBytes((int) length); } else { content.writeBytes(buffer.readBytes((int) length)); } + return reset(); } private State readHeaders(ChannelBuffer buffer) throws TooLongFrameException {