Allow to have an empty path when convert a CONNECT request (#11108)

Motivation:

CONNECT requests have no path defined as stated in the HTTP/2 spec, at the moment we will throw an exception if we try to convert such a request to HTTP/1.1

Modifications:

- Don't throw an exception if we try to convert a HTTP/2 CONNECT request that has no path
- Add unit test

Result:

Related to https://github.com/netty/netty-incubator-codec-http3/pull/112.
This commit is contained in:
Norman Maurer 2021-03-24 10:46:53 +01:00 committed by GitHub
parent 1c9fe6cb38
commit d5208096e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 4 deletions

View File

@ -268,6 +268,17 @@ public final class HttpConversionUtil {
return toFullHttpRequest(streamId, http2Headers, alloc.buffer(), validateHttpHeaders);
}
private static String extractPath(CharSequence method, Http2Headers headers) {
if (HttpMethod.CONNECT.asciiName().contentEqualsIgnoreCase(method)) {
// See https://tools.ietf.org/html/rfc7231#section-4.3.6
return checkNotNull(headers.authority(),
"authority header cannot be null in the conversion to HTTP/1.x").toString();
} else {
return checkNotNull(headers.path(),
"path header cannot be null in conversion to HTTP/1.x").toString();
}
}
/**
* Create a new object to contain the request data
*
@ -286,8 +297,7 @@ public final class HttpConversionUtil {
// HTTP/2 does not define a way to carry the version identifier that is included in the HTTP/1.1 request line.
final CharSequence method = checkNotNull(http2Headers.method(),
"method header cannot be null in conversion to HTTP/1.x");
final CharSequence path = checkNotNull(http2Headers.path(),
"path header cannot be null in conversion to HTTP/1.x");
final CharSequence path = extractPath(method, http2Headers);
FullHttpRequest msg = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(method
.toString()), path.toString(), content, validateHttpHeaders);
try {
@ -319,8 +329,7 @@ public final class HttpConversionUtil {
// HTTP/2 does not define a way to carry the version identifier that is included in the HTTP/1.1 request line.
final CharSequence method = checkNotNull(http2Headers.method(),
"method header cannot be null in conversion to HTTP/1.x");
final CharSequence path = checkNotNull(http2Headers.path(),
"path header cannot be null in conversion to HTTP/1.x");
final CharSequence path = extractPath(method, http2Headers);
HttpRequest msg = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(method.toString()),
path.toString(), validateHttpHeaders);
try {

View File

@ -17,6 +17,8 @@ package io.netty.handler.codec.http2;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.AsciiString;
import org.junit.Test;
@ -33,11 +35,25 @@ import static io.netty.handler.codec.http.HttpHeaderValues.GZIP;
import static io.netty.handler.codec.http.HttpHeaderValues.TRAILERS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class HttpConversionUtilTest {
@Test
public void connectNoPath() throws Exception {
String authority = "netty.io:80";
Http2Headers headers = new DefaultHttp2Headers();
headers.authority(authority);
headers.method(HttpMethod.CONNECT.asciiName());
HttpRequest request = HttpConversionUtil.toHttpRequest(0, headers, true);
assertNotNull(request);
assertEquals(authority, request.uri());
assertEquals(authority, request.headers().get(HOST));
}
@Test
public void setHttp2AuthorityWithoutUserInfo() {
Http2Headers headers = new DefaultHttp2Headers();