[#5892] Correct handle HttpMessage that is EOF terminated

Motivation:

We need to ensure we not add the Transfer-Encoding header if the HttpMessage is EOF terminated.

Modifications:

Only add the Transfer-Encoding header if an Content-Length header is present.

Result:

Correctly handle HttpMessage that is EOF terminated.
This commit is contained in:
Norman Maurer 2016-10-10 08:43:27 +02:00
parent a5feee596b
commit 9e8e4d2da3
2 changed files with 41 additions and 5 deletions

View File

@ -96,8 +96,12 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder<HttpObj
// the correct value can be set only after all chunks are processed/decoded.
// If buffering is not an issue, add HttpObjectAggregator down the chain, it will set the header.
// Otherwise, rely on LastHttpContent message.
headers.remove(HttpHeaders.Names.CONTENT_LENGTH);
headers.set(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
if (headers.contains(HttpHeaders.Names.CONTENT_LENGTH)) {
headers.remove(HttpHeaders.Names.CONTENT_LENGTH);
headers.set(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED);
}
// Either it is already chunked or EOF terminated.
// See https://github.com/netty/netty/issues/5892
// set new content encoding,
CharSequence targetContentEncoding = getTargetContentEncoding(contentEncoding);

View File

@ -425,7 +425,7 @@ public class HttpContentDecoderTest {
int contentLength = 0;
contentLength = calculateContentLength(req, contentLength);
byte[] receivedContent = readContent(req, contentLength);
byte[] receivedContent = readContent(req, contentLength, true);
assertEquals(HELLO_WORLD, new String(receivedContent, CharsetUtil.US_ASCII));
@ -452,7 +452,35 @@ public class HttpContentDecoderTest {
int contentLength = 0;
contentLength = calculateContentLength(resp, contentLength);
byte[] receivedContent = readContent(resp, contentLength);
byte[] receivedContent = readContent(resp, contentLength, true);
assertEquals(HELLO_WORLD, new String(receivedContent, CharsetUtil.US_ASCII));
assertHasInboundMessages(channel, true);
assertHasOutboundMessages(channel, false);
assertFalse(channel.finish());
}
// See https://github.com/netty/netty/issues/5892
@Test
public void testFullHttpResponseEOF() {
// test that ContentDecoder can be used after the ObjectAggregator
HttpResponseDecoder decoder = new HttpResponseDecoder(4096, 4096, 5);
HttpContentDecoder decompressor = new HttpContentDecompressor();
EmbeddedChannel channel = new EmbeddedChannel(decoder, decompressor);
String headers = "HTTP/1.1 200 OK\r\n" +
"Content-Encoding: gzip\r\n" +
"\r\n";
assertTrue(channel.writeInbound(Unpooled.copiedBuffer(headers.getBytes(), GZ_HELLO_WORLD)));
// This should terminate it.
assertTrue(channel.finish());
Queue<Object> resp = channel.inboundMessages();
assertTrue(resp.size() > 1);
int contentLength = 0;
contentLength = calculateContentLength(resp, contentLength);
byte[] receivedContent = readContent(resp, contentLength, false);
assertEquals(HELLO_WORLD, new String(receivedContent, CharsetUtil.US_ASCII));
@ -487,7 +515,7 @@ public class HttpContentDecoderTest {
return output;
}
private static byte[] readContent(Queue<Object> req, int contentLength) {
private static byte[] readContent(Queue<Object> req, int contentLength, boolean hasTransferEncoding) {
byte[] receivedContent = new byte[contentLength];
int readCount = 0;
for (Object o : req) {
@ -497,6 +525,10 @@ public class HttpContentDecoderTest {
b.readBytes(receivedContent, readCount, readableBytes);
readCount += readableBytes;
}
if (o instanceof HttpMessage) {
assertEquals(hasTransferEncoding,
((HttpMessage) o).headers().contains(HttpHeaders.Names.TRANSFER_ENCODING));
}
}
return receivedContent;
}