[#1007] HttpObjectAggregator should only throw one TooLongFrameException per full HTTP message
This commit is contained in:
parent
985b450182
commit
23a919cdcd
@ -59,7 +59,7 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
|
|||||||
|
|
||||||
private final int maxContentLength;
|
private final int maxContentLength;
|
||||||
private HttpMessage currentMessage;
|
private HttpMessage currentMessage;
|
||||||
|
private boolean tooLongFrameFound;
|
||||||
private ChannelHandlerContext ctx;
|
private ChannelHandlerContext ctx;
|
||||||
|
|
||||||
private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS;
|
private int maxCumulationBufferComponents = DEFAULT_MAX_COMPOSITEBUFFER_COMPONENTS;
|
||||||
@ -122,6 +122,7 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
|
|||||||
|
|
||||||
if (msg instanceof HttpMessage) {
|
if (msg instanceof HttpMessage) {
|
||||||
HttpMessage m = (HttpMessage) msg;
|
HttpMessage m = (HttpMessage) msg;
|
||||||
|
tooLongFrameFound = false;
|
||||||
|
|
||||||
// Handle the 'Expect: 100-continue' header if necessary.
|
// Handle the 'Expect: 100-continue' header if necessary.
|
||||||
// TODO: Respond with 413 Request Entity Too Large
|
// TODO: Respond with 413 Request Entity Too Large
|
||||||
@ -150,16 +151,21 @@ public class HttpChunkAggregator extends SimpleChannelUpstreamHandler implements
|
|||||||
"received " + HttpChunk.class.getSimpleName() +
|
"received " + HttpChunk.class.getSimpleName() +
|
||||||
" without " + HttpMessage.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.
|
// Merge the received chunk into the content of the current message.
|
||||||
HttpChunk chunk = (HttpChunk) msg;
|
|
||||||
ChannelBuffer content = currentMessage.getContent();
|
ChannelBuffer content = currentMessage.getContent();
|
||||||
|
|
||||||
if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) {
|
if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) {
|
||||||
// TODO: Respond with 413 Request Entity Too Large
|
tooLongFrameFound = true;
|
||||||
// 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.
|
|
||||||
throw new TooLongFrameException(
|
throw new TooLongFrameException(
|
||||||
"HTTP content length exceeded " + maxContentLength +
|
"HTTP content length exceeded " + maxContentLength +
|
||||||
" bytes.");
|
" bytes.");
|
||||||
|
@ -108,8 +108,17 @@ public class HttpChunkAggregatorTest {
|
|||||||
DecoderEmbedder<HttpMessage> embedder = new DecoderEmbedder<HttpMessage>(aggr);
|
DecoderEmbedder<HttpMessage> embedder = new DecoderEmbedder<HttpMessage>(aggr);
|
||||||
HttpMessage message = new DefaultHttpMessage(HttpVersion.HTTP_1_1);
|
HttpMessage message = new DefaultHttpMessage(HttpVersion.HTTP_1_1);
|
||||||
message.setChunked(true);
|
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 chunk1 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test", CharsetUtil.US_ASCII));
|
||||||
HttpChunk chunk2 = new DefaultHttpChunk(ChannelBuffers.copiedBuffer("test2", 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(message));
|
||||||
assertFalse(embedder.offer(chunk1));
|
assertFalse(embedder.offer(chunk1));
|
||||||
try {
|
try {
|
||||||
@ -118,6 +127,19 @@ public class HttpChunkAggregatorTest {
|
|||||||
} catch (CodecEmbedderException e) {
|
} catch (CodecEmbedderException e) {
|
||||||
assertTrue(e.getCause() instanceof TooLongFrameException);
|
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)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
Loading…
Reference in New Issue
Block a user