Remove 'Content-Length' header from a chunked HTTP response

Related: #3076

Motivation:

When a user writes a chunked HTTP response with a Content-Length header,
the HttpContentEncoder should remove the Content-Length header because
the length of the encoded content is supposed to be different from the
original one.

Actually, HttpContentEncoder currently never touches the Content-Length
header when the response is chunked.

Modifications:

- Remove the Content-Length header when an HTTP response being encoded
  is chunked
- Add a test case

Result:

HttpContentEncoder sanitizes the Content-Length header properly.
This commit is contained in:
Trustin Lee 2014-10-30 19:39:38 +09:00
parent ee168cc97c
commit d5264ebe85
2 changed files with 42 additions and 1 deletions

View File

@ -116,7 +116,9 @@ public abstract class HttpContentEncoder extends SimpleChannelHandler
HttpHeaders.Names.CONTENT_ENCODING,
getTargetContentEncoding(acceptEncoding));
if (!m.isChunked()) {
if (m.isChunked()) {
m.headers().remove(HttpHeaders.Names.CONTENT_LENGTH);
} else {
ChannelBuffer content = m.getContent();
// Encode the content.
content = ChannelBuffers.wrappedBuffer(

View File

@ -62,6 +62,45 @@ public class HttpContentEncoderTest {
}
}
@Test
public void testSanitization() throws Exception {
HttpContentEncoderEmbedder e = new HttpContentEncoderEmbedder();
e.fireMessageReceived(new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"));
HttpResponse res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
res.setChunked(true);
// Add an incorrect content-length header to ensure that it is removed when a message is chunked.
res.headers().set(Names.CONTENT_LENGTH, 42);
e.offer(res);
e.offer(new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(new byte[1])));
e.offer(HttpChunk.LAST_CHUNK);
Object o = e.poll();
assertThat(o, is(instanceOf(HttpRequest.class)));
o = e.poll();
assertThat(o, is(instanceOf(HttpResponse.class)));
res = (HttpResponse) o;
assertThat(res.isChunked(), is(true));
assertThat(res.getContent().readableBytes(), is(0));
assertThat(res.headers().get(Names.TRANSFER_ENCODING), is(nullValue()));
assertThat(res.headers().get(Names.CONTENT_LENGTH), is(nullValue()));
assertThat(res.headers().get(Names.CONTENT_ENCODING), is("test"));
HttpChunk chunk;
chunk = (HttpChunk) e.poll();
assertThat(chunk.getContent().toString(CharsetUtil.US_ASCII), is("1"));
chunk = (HttpChunk) e.poll();
assertThat(chunk, is(instanceOf(HttpChunkTrailer.class)));
assertThat(e.poll(), is(nullValue()));
}
@Test
public void testSplitContent() throws Exception {
HttpContentEncoderEmbedder e = new HttpContentEncoderEmbedder();