Correctly handle responses with status 205 and payload. (#7891)

Motivation:

HTTP responses with status of 205 should not contain a payload. We should enforce this.

Modifications:

Correctly handle responses with status 205 and payload by set Content-Length: 0 header and stripping out the content.

Result:

Fixes https://github.com/netty/netty/issues/7888
This commit is contained in:
Norman Maurer 2018-05-03 11:25:06 +02:00 committed by GitHub
parent bd800fa7e7
commit c60263e8a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 1 deletions

View File

@ -53,6 +53,14 @@ public class HttpResponseEncoder extends HttpObjectEncoder<HttpResponse> {
// Stripping Transfer-Encoding:
// See https://tools.ietf.org/html/rfc7230#section-3.3.1
msg.headers().remove(HttpHeaderNames.TRANSFER_ENCODING);
} else if (status.code() == HttpResponseStatus.RESET_CONTENT.code()) {
// Stripping Transfer-Encoding:
msg.headers().remove(HttpHeaderNames.TRANSFER_ENCODING);
// Set Content-Length: 0
// https://httpstatuses.com/205
msg.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, 0);
}
}
}
@ -74,6 +82,7 @@ public class HttpResponseEncoder extends HttpObjectEncoder<HttpResponse> {
return true;
}
return status.code() == HttpResponseStatus.NO_CONTENT.code() ||
status.code() == HttpResponseStatus.NOT_MODIFIED.code();
status.code() == HttpResponseStatus.NOT_MODIFIED.code() ||
status.code() == HttpResponseStatus.RESET_CONTENT.code();
}
}

View File

@ -353,4 +353,48 @@ public class HttpResponseEncoderTest {
lastContent.release();
assertFalse(channel.finish());
}
@Test
public void testStatusResetContentTransferContentLength() {
testStatusResetContentTransferContentLength0(HttpHeaderNames.CONTENT_LENGTH, Unpooled.buffer().writeLong(8));
}
@Test
public void testStatusResetContentTransferEncoding() {
testStatusResetContentTransferContentLength0(HttpHeaderNames.TRANSFER_ENCODING, Unpooled.buffer().writeLong(8));
}
private static void testStatusResetContentTransferContentLength0(CharSequence headerName, ByteBuf content) {
EmbeddedChannel channel = new EmbeddedChannel(new HttpResponseEncoder());
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.RESET_CONTENT);
if (HttpHeaderNames.CONTENT_LENGTH.contentEqualsIgnoreCase(headerName)) {
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
} else {
response.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
}
assertTrue(channel.writeOutbound(response));
assertTrue(channel.writeOutbound(new DefaultHttpContent(content)));
assertTrue(channel.writeOutbound(LastHttpContent.EMPTY_LAST_CONTENT));
StringBuilder responseText = new StringBuilder();
responseText.append(HttpVersion.HTTP_1_1.toString()).append(' ')
.append(HttpResponseStatus.RESET_CONTENT.toString()).append("\r\n");
responseText.append(HttpHeaderNames.CONTENT_LENGTH).append(": 0\r\n");
responseText.append("\r\n");
StringBuilder written = new StringBuilder();
for (;;) {
ByteBuf buffer = channel.readOutbound();
if (buffer == null) {
break;
}
written.append(buffer.toString(CharsetUtil.US_ASCII));
buffer.release();
}
assertEquals(responseText.toString(), written.toString());
assertFalse(channel.finish());
}
}