Skip to content
Permalink
Browse files
RFC 3986 conformance: corrected handling of path segments by `URIUtil…
…s#normalizeSyntax`; optimized path segment operations
  • Loading branch information
ok2c committed Sep 27, 2020
1 parent 6395fa7 commit 918ac1535f37c47a2230f14b6404d411ee7df91e
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 30 deletions.
@@ -115,8 +115,8 @@ public static URI normalize(final URI requestUri) throws URISyntaxException {
}
}
builder.setFragment(null);
if (builder.getPath() == null) {
builder.setPath("/");
if (builder.isPathEmpty()) {
builder.setPathSegments("");
}
return builder.build();
}
@@ -382,7 +382,7 @@ public void testIntermidateDotDotSegementsAreEquivalent() {
public void testIntermidateEncodedDotDotSegementsAreEquivalent() {
final HttpHost host = new HttpHost("foo.example.com");
final HttpRequest req1 = new BasicHttpRequest("GET", "/home.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2F../home.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/../home.html");
Assert.assertEquals(extractor.generateKey(host, req1), extractor.generateKey(host, req2));
}

@@ -406,15 +406,15 @@ public void testEquivalentPathEncodingsAreEquivalent() {
public void testEquivalentExtraPathEncodingsAreEquivalent() {
final HttpHost host = new HttpHost("foo.example.com");
final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2Fhome.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/home.html");
Assert.assertEquals(extractor.generateKey(host, req1), extractor.generateKey(host, req2));
}

@Test
public void testEquivalentExtraPathEncodingsWithPercentAreEquivalent() {
final HttpHost host = new HttpHost("foo.example.com");
final HttpRequest req1 = new BasicHttpRequest("GET", "/~smith/home%20folder.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith%2Fhome%20folder.html");
final HttpRequest req2 = new BasicHttpRequest("GET", "/%7Esmith/home%20folder.html");
Assert.assertEquals(extractor.generateKey(host, req1), extractor.generateKey(host, req2));
}
}
@@ -45,7 +45,6 @@
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.net.URIBuilder;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TextUtils;

/**
* Default implementation of {@link RedirectStrategy}.
@@ -119,9 +118,8 @@ protected URI createLocationURI(final String location) throws ProtocolException
if (host != null) {
b.setHost(host.toLowerCase(Locale.ROOT));
}
final String path = b.getPath();
if (TextUtils.isEmpty(path)) {
b.setPath("/");
if (b.isPathEmpty()) {
b.setPathSegments("");
}
return b.build();
} catch (final URISyntaxException ex) {
@@ -133,8 +133,8 @@ public static URI rewriteURI(final URI uri) throws URISyntaxException {
if (uribuilder.getUserInfo() != null) {
uribuilder.setUserInfo(null);
}
if (TextUtils.isEmpty(uribuilder.getPath())) {
uribuilder.setPath("/");
if (uribuilder.isPathEmpty()) {
uribuilder.setPathSegments("");
}
if (uribuilder.getHost() != null) {
uribuilder.setHost(uribuilder.getHost().toLowerCase(Locale.ROOT));
@@ -203,30 +203,30 @@ static URI normalizeSyntax(final URI uri) throws URISyntaxException {
}
Args.check(uri.isAbsolute(), "Base URI must be absolute");
final URIBuilder builder = new URIBuilder(uri);
final String path = builder.getPath();
if (path != null && !path.equals("/")) {
final String[] inputSegments = path.split("/");
if (!builder.isPathEmpty()) {
final List<String> inputSegments = builder.getPathSegments();
final Stack<String> outputSegments = new Stack<>();
for (final String inputSegment : inputSegments) {
if ((inputSegment.isEmpty()) || (".".equals(inputSegment))) {
// Do nothing
} else if ("..".equals(inputSegment)) {
if (!outputSegments.isEmpty()) {
outputSegments.pop();
if (!inputSegment.isEmpty() && !".".equals(inputSegment)) {
if ("..".equals(inputSegment)) {
if (!outputSegments.isEmpty()) {
outputSegments.pop();
}
} else {
outputSegments.push(inputSegment);
}
} else {
outputSegments.push(inputSegment);
}
}
final StringBuilder outputBuffer = new StringBuilder();
for (final String outputSegment : outputSegments) {
outputBuffer.append('/').append(outputSegment);
}
if (path.lastIndexOf('/') == path.length() - 1) {
// path.endsWith("/") || path.equals("")
outputBuffer.append('/');
if (!inputSegments.isEmpty()) {
final String lastSegment = inputSegments.get(inputSegments.size() - 1);
if (lastSegment.isEmpty()) {
outputSegments.push("");
}
}
builder.setPath(outputBuffer.toString());
builder.setPathSegments(outputSegments);
}
if (builder.isPathEmpty()) {
builder.setPathSegments("");
}
if (builder.getScheme() != null) {
builder.setScheme(builder.getScheme().toLowerCase(Locale.ROOT));
@@ -108,7 +108,7 @@ public void testNormalization() {
Assert.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
Assert.assertEquals("http://www.example.com/%3C", URIUtils.resolve(this.baseURI, "http://www.example.com/%3c").toString());
Assert.assertEquals("http://www.example.com/", URIUtils.resolve(this.baseURI, "HTTP://www.EXAMPLE.com/").toString());
Assert.assertEquals("http://www.example.com/a/", URIUtils.resolve(this.baseURI, "http://www.example.com/a%2f").toString());
Assert.assertEquals("http://www.example.com/a%2F", URIUtils.resolve(this.baseURI, "http://www.example.com/a%2f").toString());
Assert.assertEquals("http://www.example.com/?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/?q=%26").toString());
Assert.assertEquals("http://www.example.com/%23?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/%23?q=%26").toString());
Assert.assertEquals("http://www.example.com/blah-%28%20-blah-%20%26%20-blah-%20%29-blah/",

0 comments on commit 918ac15

Please sign in to comment.