diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java index 87f67f13d0..62c7e8bff5 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpObjectAggregator.java @@ -53,6 +53,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { private final int maxContentLength; private FullHttpMessage currentMessage; + private boolean tooLongFrameFound; private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS; private ChannelHandlerContext ctx; @@ -111,6 +112,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { FullHttpMessage currentMessage = this.currentMessage; if (msg instanceof HttpMessage) { + tooLongFrameFound = false; assert currentMessage == null; HttpMessage m = (HttpMessage) msg; @@ -150,15 +152,19 @@ public class HttpObjectAggregator extends MessageToMessageDecoder { } else if (msg instanceof HttpContent) { assert currentMessage != null; + if (tooLongFrameFound) { + this.currentMessage = null; + // already detect the too long frame so just discard the content + return; + } + // Merge the received chunk into the content of the current message. HttpContent chunk = (HttpContent) msg; CompositeByteBuf content = (CompositeByteBuf) currentMessage.content(); if (content.readableBytes() > maxContentLength - chunk.content().readableBytes()) { - // TODO: Respond with 413 Request Entity Too Large - // and discard the traffic or close the connection. - // No need to notify the upstream handlers - just log. - // If decoding a response, just throw an exception. + tooLongFrameFound = true; + throw new TooLongFrameException( "HTTP content length exceeded " + maxContentLength + " bytes."); diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java index 8ee047ffd6..8a1826aefb 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpObjectAggregatorTest.java @@ -102,7 +102,7 @@ public class HttpObjectAggregatorTest { assertNull(embedder.readInbound()); } - @Test(expected = TooLongFrameException.class) + @Test public void testTooLongFrameException() { HttpObjectAggregator aggr = new HttpObjectAggregator(4); EmbeddedMessageChannel embedder = new EmbeddedMessageChannel(aggr); @@ -110,10 +110,27 @@ public class HttpObjectAggregatorTest { HttpMethod.GET, "http://localhost"); HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("test", CharsetUtil.US_ASCII)); HttpContent chunk2 = new DefaultHttpContent(Unpooled.copiedBuffer("test2", CharsetUtil.US_ASCII)); + HttpContent chunk3 = new DefaultHttpContent(Unpooled.copiedBuffer("test3", CharsetUtil.US_ASCII)); + assertFalse(embedder.writeInbound(message)); - assertFalse(embedder.writeInbound(chunk1)); - embedder.writeInbound(chunk2); - fail(); + assertFalse(embedder.writeInbound(chunk1.copy())); + try { + embedder.writeInbound(chunk2.copy()); + fail(); + } catch (TooLongFrameException e) { + // expected + } + assertFalse(embedder.writeInbound(chunk3.copy())); + + assertFalse(embedder.writeInbound(message)); + assertFalse(embedder.writeInbound(chunk1.copy())); + try { + embedder.writeInbound(chunk2.copy()); + fail(); + } catch (TooLongFrameException e) { + // expected + } + assertFalse(embedder.writeInbound(chunk3.copy())); } @Test(expected = IllegalArgumentException.class)