[#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 b6099bc193
commit 8269e0f046
2 changed files with 41 additions and 5 deletions

View File

@ -98,8 +98,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(HttpHeaderNames.CONTENT_LENGTH);
headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
headers.remove(HttpHeaderNames.CONTENT_LENGTH);
headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.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

@ -422,7 +422,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));
@ -449,7 +449,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));
@ -484,7 +512,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) {
@ -494,6 +522,10 @@ public class HttpContentDecoderTest {
b.readBytes(receivedContent, readCount, readableBytes);
readCount += readableBytes;
}
if (o instanceof HttpMessage) {
assertEquals(hasTransferEncoding,
((HttpMessage) o).headers().contains(HttpHeaderNames.TRANSFER_ENCODING));
}
}
return receivedContent;
}