Do not manually reset HttpObjectDecoder in HttpObjectAggregator.handleOversizedMessage(...) (#9017) (#9156)

Motivation:

We did manually call HttpObjectDecoder.reset() in HttpObjectAggregator.handleOversizedMessage(...) which is incorrect and will prevent correct parsing of the next message.

Modifications:

- Remove call to HttpObjectDecoder.reset()
- Add unit test

Result:

Verify that we can correctly parse the next request after we rejected a request.
This commit is contained in:
Norman Maurer 2019-05-17 21:18:03 +02:00 committed by GitHub
parent 1672b6d12c
commit c565805f1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 7 deletions

View File

@ -271,13 +271,6 @@ public class HttpObjectAggregator
} }
}); });
} }
// If an oversized request was handled properly and the connection is still alive
// (i.e. rejected 100-continue). the decoder should prepare to handle a new message.
HttpObjectDecoder decoder = ctx.pipeline().get(HttpObjectDecoder.class);
if (decoder != null) {
decoder.reset();
}
} else if (oversized instanceof HttpResponse) { } else if (oversized instanceof HttpResponse) {
ctx.close(); ctx.close();
throw new TooLongFrameException("Response entity too large: " + oversized); throw new TooLongFrameException("Response entity too large: " + oversized);

View File

@ -144,6 +144,57 @@ public class HttpObjectAggregatorTest {
assertFalse(embedder.finish()); assertFalse(embedder.finish());
} }
@Test
public void testOversizedRequestWithContentLengthAndDecoder() {
EmbeddedChannel embedder = new EmbeddedChannel(new HttpRequestDecoder(), new HttpObjectAggregator(4, false));
assertFalse(embedder.writeInbound(Unpooled.copiedBuffer(
"PUT /upload HTTP/1.1\r\n" +
"Content-Length: 5\r\n\r\n", CharsetUtil.US_ASCII)));
assertNull(embedder.readInbound());
FullHttpResponse response = embedder.readOutbound();
assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status());
assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH));
assertTrue(embedder.isOpen());
assertFalse(embedder.writeInbound(Unpooled.wrappedBuffer(new byte[] { 1, 2, 3, 4 })));
assertFalse(embedder.writeInbound(Unpooled.wrappedBuffer(new byte[] { 5 })));
assertNull(embedder.readOutbound());
assertFalse(embedder.writeInbound(Unpooled.copiedBuffer(
"PUT /upload HTTP/1.1\r\n" +
"Content-Length: 2\r\n\r\n", CharsetUtil.US_ASCII)));
assertEquals(HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE, response.status());
assertEquals("0", response.headers().get(HttpHeaderNames.CONTENT_LENGTH));
assertThat(response, instanceOf(LastHttpContent.class));
ReferenceCountUtil.release(response);
assertTrue(embedder.isOpen());
assertFalse(embedder.writeInbound(Unpooled.copiedBuffer(new byte[] { 1 })));
assertNull(embedder.readOutbound());
assertTrue(embedder.writeInbound(Unpooled.copiedBuffer(new byte[] { 2 })));
assertNull(embedder.readOutbound());
FullHttpRequest request = embedder.readInbound();
assertEquals(HttpVersion.HTTP_1_1, request.protocolVersion());
assertEquals(HttpMethod.PUT, request.method());
assertEquals("/upload", request.uri());
assertEquals(2, HttpUtil.getContentLength(request));
byte[] actual = new byte[request.content().readableBytes()];
request.content().readBytes(actual);
assertArrayEquals(new byte[] { 1, 2 }, actual);
request.release();
assertFalse(embedder.finish());
}
@Test @Test
public void testOversizedRequestWithoutKeepAlive() { public void testOversizedRequestWithoutKeepAlive() {
// send a HTTP/1.0 request with no keep-alive header // send a HTTP/1.0 request with no keep-alive header