Skip to content

Commit

Permalink
Fix isOriginForm and isAsteriskForm (#12568)
Browse files Browse the repository at this point in the history
Motivation:

These methods would always return false using the previously implementation (URI#getSchemeSpecificPart is [documented](https://docs.oracle.com/javase/8/docs/api/java/net/URI.html#getSchemeSpecificPart--) to *never* return `null`). They also had other implementation errors.

Modification:

Edit methods to conform with RFC 7230.

Result:

Methods handle the basic examples provided in RFC 7230. More test cases can be added as needed.
  • Loading branch information
jkjk822 committed Jul 8, 2022
1 parent c949fa6 commit 2f7234b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
24 changes: 18 additions & 6 deletions codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java
Expand Up @@ -49,19 +49,31 @@ private HttpUtil() { }
* <a href="https://tools.ietf.org/html/rfc7230#section-5.3">rfc7230, 5.3</a>.
*/
public static boolean isOriginForm(URI uri) {
return uri.getScheme() == null && uri.getSchemeSpecificPart() == null &&
uri.getHost() == null && uri.getAuthority() == null;
return isOriginForm(uri.toString());
}

/**
* Determine if a string uri is in origin-form according to
* <a href="https://tools.ietf.org/html/rfc7230#section-5.3">rfc7230, 5.3</a>.
*/
public static boolean isOriginForm(String uri) {
return uri.startsWith("/");
}

/**
* Determine if a uri is in asterisk-form according to
* <a href="https://tools.ietf.org/html/rfc7230#section-5.3">rfc7230, 5.3</a>.
*/
public static boolean isAsteriskForm(URI uri) {
return "*".equals(uri.getPath()) &&
uri.getScheme() == null && uri.getSchemeSpecificPart() == null &&
uri.getHost() == null && uri.getAuthority() == null && uri.getQuery() == null &&
uri.getFragment() == null;
return isAsteriskForm(uri.toString());
}

/**
* Determine if a string uri is in asterisk-form according to
* <a href="https://tools.ietf.org/html/rfc7230#section-5.3">rfc7230, 5.3</a>.
*/
public static boolean isAsteriskForm(String uri) {
return "*".equals(uri);
}

/**
Expand Down
Expand Up @@ -22,6 +22,7 @@

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -38,6 +39,29 @@

public class HttpUtilTest {

@Test
public void testRecognizesOriginForm() {
// Origin form: https://tools.ietf.org/html/rfc7230#section-5.3.1
assertTrue(HttpUtil.isOriginForm(URI.create("/where?q=now")));
// Absolute form: https://tools.ietf.org/html/rfc7230#section-5.3.2
assertFalse(HttpUtil.isOriginForm(URI.create("http://www.example.org/pub/WWW/TheProject.html")));
// Authority form: https://tools.ietf.org/html/rfc7230#section-5.3.3
assertFalse(HttpUtil.isOriginForm(URI.create("www.example.com:80")));
// Asterisk form: https://tools.ietf.org/html/rfc7230#section-5.3.4
assertFalse(HttpUtil.isOriginForm(URI.create("*")));
}

@Test public void testRecognizesAsteriskForm() {
// Asterisk form: https://tools.ietf.org/html/rfc7230#section-5.3.4
assertTrue(HttpUtil.isAsteriskForm(URI.create("*")));
// Origin form: https://tools.ietf.org/html/rfc7230#section-5.3.1
assertFalse(HttpUtil.isAsteriskForm(URI.create("/where?q=now")));
// Absolute form: https://tools.ietf.org/html/rfc7230#section-5.3.2
assertFalse(HttpUtil.isAsteriskForm(URI.create("http://www.example.org/pub/WWW/TheProject.html")));
// Authority form: https://tools.ietf.org/html/rfc7230#section-5.3.3
assertFalse(HttpUtil.isAsteriskForm(URI.create("www.example.com:80")));
}

@Test
public void testRemoveTransferEncodingIgnoreCase() {
HttpMessage message = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
Expand Down
Expand Up @@ -49,6 +49,8 @@
import static io.netty.handler.codec.http.HttpResponseStatus.parseLine;
import static io.netty.handler.codec.http.HttpScheme.HTTP;
import static io.netty.handler.codec.http.HttpScheme.HTTPS;
import static io.netty.handler.codec.http.HttpUtil.isAsteriskForm;
import static io.netty.handler.codec.http.HttpUtil.isOriginForm;
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
import static io.netty.handler.codec.http2.Http2Exception.streamError;
Expand Down Expand Up @@ -434,8 +436,7 @@ public static Http2Headers toHttp2Headers(HttpMessage in, boolean validateHeader
if (in instanceof HttpRequest) {
HttpRequest request = (HttpRequest) in;
String host = inHeaders.getAsString(HttpHeaderNames.HOST);
if (request.uri().startsWith("/") || "*".equals(request.uri())) {
// Origin or asterisk form
if (isOriginForm(request.uri()) || isAsteriskForm(request.uri())) {
out.path(new AsciiString(request.uri()));
setHttp2Scheme(inHeaders, out);
} else {
Expand Down

0 comments on commit 2f7234b

Please sign in to comment.