HTTPCLIENT-2271: Do not optimize the path component of the resolved URI by default.

This commit is contained in:
Oleg Kalnichevski 2023-04-27 17:13:53 +02:00
parent 48e4229843
commit 3e38a5e5ec
4 changed files with 53 additions and 36 deletions

View File

@ -115,10 +115,7 @@ public final class HttpCacheSupport {
}
}
builder.setFragment(null);
if (builder.isPathEmpty()) {
builder.setPathSegments("");
}
return builder.build();
return builder.normalizeSyntax().build();
}
/**

View File

@ -210,9 +210,15 @@ public class URIUtils {
return uri;
}
final URIBuilder builder = new URIBuilder(uri);
builder.normalizeSyntax();
if (builder.getScheme() == null) {
final String scheme = builder.getScheme();
if (scheme == null) {
builder.setScheme(URIScheme.HTTP.id);
} else {
builder.setScheme(TextUtils.toLowerCase(scheme));
}
final String host = builder.getHost();
if (host != null) {
builder.setHost(TextUtils.toLowerCase(host));
}
if (builder.isPathEmpty()) {
builder.setPathSegments("");

View File

@ -223,4 +223,30 @@ public class TestDefaultRedirectStrategy {
redirectStrategy.createLocationURI(":::::::"));
}
@Test
public void testResolveRelativeLocation() throws Exception {
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
final HttpClientContext context = HttpClientContext.create();
final HttpGet request = new HttpGet("http://localhost/");
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
response.addHeader("Location", "/foo;bar=baz");
final URI locationURI = redirectStrategy.getLocationURI(request, response, context);
Assertions.assertEquals(URI.create("http://localhost/foo;bar=baz"), locationURI);
}
@Test
public void testUseAbsoluteLocation() throws Exception {
final DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
final HttpClientContext context = HttpClientContext.create();
final HttpGet request = new HttpGet("http://localhost/");
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_MOVED_TEMPORARILY, "Redirect");
response.addHeader("Location", "http://localhost/foo;bar=baz");
final URI locationURI = redirectStrategy.getLocationURI(request, response, context);
Assertions.assertEquals(URI.create("http://localhost/foo;bar=baz"), locationURI);
}
}

View File

@ -43,18 +43,6 @@ public class TestURIUtils {
private final URI baseURI = URI.create("http://a/b/c/d;p?q");
@Test
public void testNormalization() {
Assertions.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
Assertions.assertEquals("http://www.example.com/%3C", URIUtils.resolve(this.baseURI, "http://www.example.com/%3c").toString());
Assertions.assertEquals("http://www.example.com/", URIUtils.resolve(this.baseURI, "HTTP://www.EXAMPLE.com/").toString());
Assertions.assertEquals("http://www.example.com/a%2F", URIUtils.resolve(this.baseURI, "http://www.example.com/a%2f").toString());
Assertions.assertEquals("http://www.example.com/?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/?q=%26").toString());
Assertions.assertEquals("http://www.example.com/%23?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/%23?q=%26").toString());
Assertions.assertEquals("http://www.example.com/blah-%28%20-blah-%20%26%20-blah-%20%29-blah/",
URIUtils.resolve(this.baseURI, "http://www.example.com/blah-%28%20-blah-%20&%20-blah-%20)-blah/").toString());
}
@Test
public void testResolve() {
Assertions.assertEquals("g:h", URIUtils.resolve(this.baseURI, "g:h").toString());
@ -67,16 +55,16 @@ public class TestURIUtils {
Assertions.assertEquals("http://a/b/c/d;p?y#f", URIUtils.resolve(this.baseURI, "?y#f")
.toString());
Assertions.assertEquals("http://a/b/c/g?y", URIUtils.resolve(this.baseURI, "g?y").toString());
Assertions.assertEquals("http://a/b/c/d%3Bp?q#s", URIUtils.resolve(this.baseURI, "#s")
Assertions.assertEquals("http://a/b/c/d;p?q#s", URIUtils.resolve(this.baseURI, "#s")
.toString());
Assertions.assertEquals("http://a/b/c/g#s", URIUtils.resolve(this.baseURI, "g#s").toString());
Assertions.assertEquals("http://a/b/c/g?y#s", URIUtils.resolve(this.baseURI, "g?y#s")
.toString());
Assertions.assertEquals("http://a/b/c/%3Bx", URIUtils.resolve(this.baseURI, ";x").toString());
Assertions.assertEquals("http://a/b/c/g%3Bx", URIUtils.resolve(this.baseURI, "g;x").toString());
Assertions.assertEquals("http://a/b/c/g%3Bx?y#s", URIUtils.resolve(this.baseURI, "g;x?y#s")
Assertions.assertEquals("http://a/b/c/;x", URIUtils.resolve(this.baseURI, ";x").toString());
Assertions.assertEquals("http://a/b/c/g;x", URIUtils.resolve(this.baseURI, "g;x").toString());
Assertions.assertEquals("http://a/b/c/g;x?y#s", URIUtils.resolve(this.baseURI, "g;x?y#s")
.toString());
Assertions.assertEquals("http://a/b/c/d%3Bp?q", URIUtils.resolve(this.baseURI, "").toString());
Assertions.assertEquals("http://a/b/c/d;p?q", URIUtils.resolve(this.baseURI, "").toString());
Assertions.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, ".").toString());
Assertions.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, "./").toString());
Assertions.assertEquals("http://a/b/", URIUtils.resolve(this.baseURI, "..").toString());
@ -85,11 +73,11 @@ public class TestURIUtils {
Assertions.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../..").toString());
Assertions.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../../").toString());
Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../g").toString());
Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../g").toString());
Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../../g")
Assertions.assertEquals("http://a/../g", URIUtils.resolve(this.baseURI, "../../../g").toString());
Assertions.assertEquals("http://a/../../g", URIUtils.resolve(this.baseURI, "../../../../g")
.toString());
Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/./g").toString());
Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/../g").toString());
Assertions.assertEquals("http://a/./g", URIUtils.resolve(this.baseURI, "/./g").toString());
Assertions.assertEquals("http://a/../g", URIUtils.resolve(this.baseURI, "/../g").toString());
Assertions.assertEquals("http://a/b/c/g.", URIUtils.resolve(this.baseURI, "g.").toString());
Assertions.assertEquals("http://a/b/c/.g", URIUtils.resolve(this.baseURI, ".g").toString());
Assertions.assertEquals("http://a/b/c/g..", URIUtils.resolve(this.baseURI, "g..").toString());
@ -98,32 +86,32 @@ public class TestURIUtils {
Assertions.assertEquals("http://a/b/c/g/", URIUtils.resolve(this.baseURI, "./g/.").toString());
Assertions.assertEquals("http://a/b/c/g/h", URIUtils.resolve(this.baseURI, "g/./h").toString());
Assertions.assertEquals("http://a/b/c/h", URIUtils.resolve(this.baseURI, "g/../h").toString());
Assertions.assertEquals("http://a/b/c/g%3Bx%3D1/y", URIUtils.resolve(this.baseURI, "g;x=1/./y")
Assertions.assertEquals("http://a/b/c/g;x=1/y", URIUtils.resolve(this.baseURI, "g;x=1/./y")
.toString());
Assertions.assertEquals("http://a/b/c/y", URIUtils.resolve(this.baseURI, "g;x=1/../y")
.toString());
Assertions.assertEquals("http://a/b/c/g?y%2F.%2Fx", URIUtils.resolve(this.baseURI, "g?y/./x")
Assertions.assertEquals("http://a/b/c/g?y/./x", URIUtils.resolve(this.baseURI, "g?y/./x")
.toString());
Assertions.assertEquals("http://a/b/c/g?y%2F..%2Fx", URIUtils.resolve(this.baseURI, "g?y/../x")
Assertions.assertEquals("http://a/b/c/g?y/../x", URIUtils.resolve(this.baseURI, "g?y/../x")
.toString());
Assertions.assertEquals("http://a/b/c/g#s%2F.%2Fx", URIUtils.resolve(this.baseURI, "g#s/./x")
Assertions.assertEquals("http://a/b/c/g#s/./x", URIUtils.resolve(this.baseURI, "g#s/./x")
.toString());
Assertions.assertEquals("http://a/b/c/g#s%2F..%2Fx", URIUtils.resolve(this.baseURI, "g#s/../x")
Assertions.assertEquals("http://a/b/c/g#s/../x", URIUtils.resolve(this.baseURI, "g#s/../x")
.toString());
Assertions.assertEquals("http:g", URIUtils.resolve(this.baseURI, "http:g").toString());
// examples from section 5.2.4
Assertions.assertEquals("http://s/a/g", URIUtils.resolve(this.baseURI,
Assertions.assertEquals("http://s/a/b/c/./../../g", URIUtils.resolve(this.baseURI,
"http://s/a/b/c/./../../g").toString());
Assertions.assertEquals("http://s/mid/6", URIUtils.resolve(this.baseURI,
Assertions.assertEquals("http://s/mid/content=5/../6", URIUtils.resolve(this.baseURI,
"http://s/mid/content=5/../6").toString());
}
@Test
public void testResolveOpaque() {
Assertions.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
Assertions.assertEquals("example://a/./b/../b/%63/%7bfoo%7d", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
Assertions.assertEquals("file://localhost/etc/fstab", URIUtils.resolve(this.baseURI, "file://localhost/etc/fstab").toString());
Assertions.assertEquals("file:///etc/fstab", URIUtils.resolve(this.baseURI, "file:///etc/fstab").toString());
Assertions.assertEquals("file://localhost/c%3A/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file://localhost/c:/WINDOWS/clock.avi").toString());
Assertions.assertEquals("file://localhost/c:/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file://localhost/c:/WINDOWS/clock.avi").toString());
Assertions.assertEquals("file:///c:/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file:///c:/WINDOWS/clock.avi").toString());
Assertions.assertEquals("file://hostname/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file://hostname/path/to/the%20file.txt").toString());
Assertions.assertEquals("file:///c:/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file:///c:/path/to/the%20file.txt").toString());