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

This commit is contained in:
Norman Maurer 2013-05-09 20:03:02 +02:00
parent 985b450182
commit 23a919cdcd
2 changed files with 34 additions and 6 deletions

View File

@ -59,7 +59,7 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
private final int maxContentLength;
private HttpMessage currentMessage;
private boolean tooLongFrameFound;
private ChannelHandlerContext ctx;
private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS;
@ -122,6 +122,7 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
if (msg instanceof HttpMessage) {
HttpMessage m = (HttpMessage) msg;
tooLongFrameFound = false;
// Handle the 'Expect: 100-continue' header if necessary.
// TODO: Respond with 413 Request Entity Too Large
@ -150,16 +151,21 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
"received " + HttpChunk.class.getSimpleName() +
" without " + HttpMessage.class.getSimpleName());
}
HttpChunk chunk = (HttpChunk) msg;
if (tooLongFrameFound) {
if (chunk.isLast()) {
this.currentMessage = null;
}
return;
}
// Merge the received chunk into the content of the current message.
HttpChunk chunk = (HttpChunk) msg;
ChannelBuffer content = currentMessage.getContent();
if (content.readableBytes() > maxContentLength - chunk.getContent().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

@ -108,8 +108,17 @@ public class HttpChunkAggregatorTest {
DecoderEmbedder<HttpMessage> embedder = new DecoderEmbedder<HttpMessage>(aggr);
HttpMessage message = new DefaultHttpMessage(HttpVersion.HTTP_1_1);
message.setChunked(true);
HttpMessage message2= new DefaultHttpMessage(HttpVersion.HTTP_1_1);
message2.setChunked(true);
HttpChunk chunk1 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test", CharsetUtil.US_ASCII));
HttpChunk chunk2 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test2", CharsetUtil.US_ASCII));
HttpChunk chunk3 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test3", CharsetUtil.US_ASCII));
HttpChunk chunk4 = HttpChunk.LAST_CHUNK;
HttpChunk chunk5 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test", CharsetUtil.US_ASCII));
HttpChunk chunk6 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test2", CharsetUtil.US_ASCII));
HttpChunk chunk7 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test3", CharsetUtil.US_ASCII));
HttpChunk chunk8 = HttpChunk.LAST_CHUNK;
assertFalse(embedder.offer(message));
assertFalse(embedder.offer(chunk1));
try {
@ -118,6 +127,19 @@ public class HttpChunkAggregatorTest {
} catch (CodecEmbedderException e) {
assertTrue(e.getCause() instanceof TooLongFrameException);
}
assertFalse(embedder.offer(chunk3));
assertFalse(embedder.offer(chunk4));
assertFalse(embedder.offer(message2));
assertFalse(embedder.offer(chunk5));
try {
embedder.offer(chunk6);
fail();
} catch (CodecEmbedderException e) {
assertTrue(e.getCause() instanceof TooLongFrameException);
}
assertFalse(embedder.offer(chunk7));
assertFalse(embedder.offer(chunk8));
}
@Test(expected = IllegalArgumentException.class)