Fix HttpUtil.isKeepAlive to behave correctly when Connection is a comma separated list (#8924)

Motivation:

According to the specification, the "Connection" header's syntax is:

"
The Connection header field's value has the following grammar:

     Connection        = 1#connection-option
     connection-option = token

Connection options are case-insensitive.
"
https://tools.ietf.org/html/rfc7230#section-6.1

This means that Connection's value can have at least one element or
a comma separated list with elements
When calculating whether the connection can remain open,
HttpUtil.isKeepAlive(HttpMessage) should take this into account.

Modifications:

- Check for "close" and "keep-alive" in a comma separated list
- Add unit test

Result:

HttpUtil.isKeepAlive(HttpMessage) works correctly when "Connection: Upgrade, close"
This commit is contained in:
violetagg 2019-03-13 15:28:28 +02:00 committed by Norman Maurer
parent 047cae8edc
commit a44c33136f
2 changed files with 24 additions and 10 deletions

View File

@ -67,16 +67,9 @@ public final class HttpUtil {
* {@link HttpVersion#isKeepAliveDefault()}. * {@link HttpVersion#isKeepAliveDefault()}.
*/ */
public static boolean isKeepAlive(HttpMessage message) { public static boolean isKeepAlive(HttpMessage message) {
CharSequence connection = message.headers().get(HttpHeaderNames.CONNECTION); return !message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE, true) &&
if (HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection)) { (message.protocolVersion().isKeepAliveDefault() ||
return false; message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE, true));
}
if (message.protocolVersion().isKeepAliveDefault()) {
return !HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection);
} else {
return HttpHeaderValues.KEEP_ALIVE.contentEqualsIgnoreCase(connection);
}
} }
/** /**

View File

@ -317,4 +317,25 @@ public class HttpUtilTest {
"http:localhost/http_1_0"); "http:localhost/http_1_0");
assertFalse(HttpUtil.isKeepAlive(http10Message)); assertFalse(HttpUtil.isKeepAlive(http10Message));
} }
@Test
public void testKeepAliveIfConnectionHeaderMultipleValues() {
HttpMessage http11Message = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
"http:localhost/http_1_1");
http11Message.headers().set(
HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE + ", " + HttpHeaderValues.CLOSE);
assertFalse(HttpUtil.isKeepAlive(http11Message));
http11Message.headers().set(
HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE + ", Close");
assertFalse(HttpUtil.isKeepAlive(http11Message));
http11Message.headers().set(
HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE + ", " + HttpHeaderValues.UPGRADE);
assertFalse(HttpUtil.isKeepAlive(http11Message));
http11Message.headers().set(
HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE + ", " + HttpHeaderValues.KEEP_ALIVE);
assertTrue(HttpUtil.isKeepAlive(http11Message));
}
} }