[#1007] HttpObjectAggregator should only throw one TooLongFrameException per full HTTP message

This commit is contained in:
Norman Maurer 2013-05-09 19:44:39 +02:00
parent 80f4c0b334
commit 268b059ebb
2 changed files with 31 additions and 8 deletions

View File

@ -53,6 +53,7 @@ public class HttpObjectAggregator extends MessageToMessageDecoder<HttpObject> {
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<HttpObject> {
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<HttpObject> {
} 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.");

View File

@ -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)