From e9f12b29725c567cdb4de98b3302a61ca9d41280 Mon Sep 17 00:00:00 2001 From: Stephane Landelle Date: Mon, 28 Aug 2017 10:50:57 +0200 Subject: [PATCH] Don't be tricked by anchors containing a question mark, close #1455 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Motivation: AHC can be tricked into connecting to a different host. Modification: * Make sure we don’t interpret `?` in the anchor as the beginning of the query and the end of the path. * Update tests to check org.asynchttpclient.uri.Uri returns the same results as java.net.URI. Result: AHC no longer tricked by anchors containing question mark. --- .../org/asynchttpclient/uri/UriParser.java | 184 +++++++------- .../asynchttpclient/uri/UriParserTest.java | 125 +++++----- .../java/org/asynchttpclient/uri/UriTest.java | 225 +++++------------- 3 files changed, 211 insertions(+), 323 deletions(-) diff --git a/client/src/main/java/org/asynchttpclient/uri/UriParser.java b/client/src/main/java/org/asynchttpclient/uri/UriParser.java index 45eaa2c5c8..2ff07d6a70 100644 --- a/client/src/main/java/org/asynchttpclient/uri/UriParser.java +++ b/client/src/main/java/org/asynchttpclient/uri/UriParser.java @@ -25,24 +25,27 @@ final class UriParser { public String path; public String userInfo; - private int start, end = 0; - private String urlWithoutQuery; + private String originalUrl; + private int start, end, currentIndex = 0; - private void trimRight(String originalUrl) { - end = originalUrl.length(); - while (end > 0 && originalUrl.charAt(end - 1) <= ' ') - end--; - } - - private void trimLeft(String originalUrl) { - while (start < end && originalUrl.charAt(start) <= ' ') + private void trimLeft() { + while (start < end && originalUrl.charAt(start) <= ' ') { start++; + } - if (originalUrl.regionMatches(true, start, "url:", 0, 4)) + if (originalUrl.regionMatches(true, start, "url:", 0, 4)) { start += 4; + } } - private boolean isFragmentOnly(String originalUrl) { + private void trimRight() { + end = originalUrl.length(); + while (end > 0 && originalUrl.charAt(end - 1) <= ' ') { + end--; + } + } + + private boolean isFragmentOnly() { return start < originalUrl.length() && originalUrl.charAt(start) == '#'; } @@ -52,8 +55,9 @@ private boolean isValidProtocolChar(char c) { private boolean isValidProtocolChars(String protocol) { for (int i = 1; i < protocol.length(); i++) { - if (!isValidProtocolChar(protocol.charAt(i))) + if (!isValidProtocolChar(protocol.charAt(i))) { return false; + } } return true; } @@ -62,32 +66,34 @@ private boolean isValidProtocol(String protocol) { return protocol.length() > 0 && Character.isLetter(protocol.charAt(0)) && isValidProtocolChars(protocol); } - private void computeInitialScheme(String originalUrl) { - for (int i = start; i < end; i++) { + private void computeInitialScheme() { + for (int i = currentIndex; i < end; i++) { char c = originalUrl.charAt(i); if (c == ':') { - String s = originalUrl.substring(start, i); + String s = originalUrl.substring(currentIndex, i); if (isValidProtocol(s)) { - scheme = s.toLowerCase(); - start = i + 1; + scheme = s.toLowerCase(); + currentIndex = i + 1; } break; - } else if (c == '/') + } else if (c == '/') { break; + } } } - private boolean overrideWithContext(Uri context, String originalUrl) { + private boolean overrideWithContext(Uri context) { boolean isRelative = false; - // only use context if the schemes match + // use context only if schemes match if (context != null && (scheme == null || scheme.equalsIgnoreCase(context.getScheme()))) { // see RFC2396 5.2.3 String contextPath = context.getPath(); - if (isNonEmpty(contextPath) && contextPath.charAt(0) == '/') - scheme = null; + if (isNonEmpty(contextPath) && contextPath.charAt(0) == '/') { + scheme = null; + } if (scheme == null) { scheme = context.getScheme(); @@ -101,8 +107,13 @@ private boolean overrideWithContext(Uri context, String originalUrl) { return isRelative; } - private void computeFragment(String originalUrl) { - int charpPosition = originalUrl.indexOf('#', start); + private int findWithinCurrentRange(char c) { + int pos = originalUrl.indexOf(c, currentIndex); + return pos > end ? -1 : pos; + } + + private void trimFragment() { + int charpPosition = findWithinCurrentRange('#'); if (charpPosition >= 0) { end = charpPosition; } @@ -110,45 +121,43 @@ private void computeFragment(String originalUrl) { private void inheritContextQuery(Uri context, boolean isRelative) { // see RFC2396 5.2.2: query and fragment inheritance - if (isRelative && start == end) { + if (isRelative && currentIndex == end) { query = context.getQuery(); } } - private boolean splitUrlAndQuery(String originalUrl) { - boolean queryOnly = false; - urlWithoutQuery = originalUrl; - if (start < end) { - int askPosition = originalUrl.indexOf('?'); - queryOnly = askPosition == start; - if (askPosition != -1 && askPosition < end) { + private boolean computeQuery() { + if (currentIndex < end) { + int askPosition = findWithinCurrentRange('?'); + if (askPosition != -1) { query = originalUrl.substring(askPosition + 1, end); - if (end > askPosition) + if (end > askPosition) { end = askPosition; - urlWithoutQuery = originalUrl.substring(0, askPosition); + } + return askPosition == currentIndex; } } - - return queryOnly; + return false; } private boolean currentPositionStartsWith4Slashes() { - return urlWithoutQuery.regionMatches(start, "////", 0, 4); + return originalUrl.regionMatches(currentIndex, "////", 0, 4); } private boolean currentPositionStartsWith2Slashes() { - return urlWithoutQuery.regionMatches(start, "//", 0, 2); + return originalUrl.regionMatches(currentIndex, "//", 0, 2); } private void computeAuthority() { - int authorityEndPosition = urlWithoutQuery.indexOf('/', start); - if (authorityEndPosition < 0) { - authorityEndPosition = urlWithoutQuery.indexOf('?', start); - if (authorityEndPosition < 0) + int authorityEndPosition = findWithinCurrentRange('/'); + if (authorityEndPosition == -1) { + authorityEndPosition = findWithinCurrentRange('?'); + if (authorityEndPosition == -1) { authorityEndPosition = end; + } } - host = authority = urlWithoutQuery.substring(start, authorityEndPosition); - start = authorityEndPosition; + host = authority = originalUrl.substring(currentIndex, authorityEndPosition); + currentIndex = authorityEndPosition; } private void computeUserInfo() { @@ -156,8 +165,9 @@ private void computeUserInfo() { if (atPosition != -1) { userInfo = authority.substring(0, atPosition); host = authority.substring(atPosition + 1); - } else + } else { userInfo = null; + } } private boolean isMaybeIPV6() { @@ -179,14 +189,16 @@ private void computeIPV6() { if (host.length() > portPosition) { port = Integer.parseInt(host.substring(portPosition)); } - } else + } else { throw new IllegalArgumentException("Invalid authority field: " + authority); + } } host = host.substring(0, positionAfterClosingSquareBrace); - } else + } else { throw new IllegalArgumentException("Invalid authority field: " + authority); + } } private void computeRegularHostPort() { @@ -218,39 +230,44 @@ private void removeEmbedded2Dots() { } else if (end == 0) { break; } - } else + } else { i = i + 3; + } } } private void removeTailing2Dots() { while (path.endsWith("/..")) { end = path.lastIndexOf('/', path.length() - 4); - if (end >= 0) + if (end >= 0) { path = path.substring(0, end + 1); - else + } else { break; + } } } private void removeStartingDot() { - if (path.startsWith("./") && path.length() > 2) + if (path.startsWith("./") && path.length() > 2) { path = path.substring(2); + } } private void removeTrailingDot() { - if (path.endsWith("/.")) + if (path.endsWith("/.")) { path = path.substring(0, path.length() - 1); + } } private void handleRelativePath() { int lastSlashPosition = path.lastIndexOf('/'); - String pathEnd = urlWithoutQuery.substring(start, end); + String pathEnd = originalUrl.substring(currentIndex, end); - if (lastSlashPosition == -1) + if (lastSlashPosition == -1) { path = authority != null ? "/" + pathEnd : pathEnd; - else + } else { path = path.substring(0, lastSlashPosition + 1) + pathEnd; + } } private void handlePathDots() { @@ -265,36 +282,37 @@ private void handlePathDots() { private void parseAuthority() { if (!currentPositionStartsWith4Slashes() && currentPositionStartsWith2Slashes()) { - start += 2; + currentIndex += 2; computeAuthority(); computeUserInfo(); if (host != null) { - if (isMaybeIPV6()) + if (isMaybeIPV6()) { computeIPV6(); - else + } else { computeRegularHostPort(); + } } - if (port < -1) + if (port < -1) { throw new IllegalArgumentException("Invalid port number :" + port); + } // see RFC2396 5.2.4: ignore context path if authority is defined - if (isNonEmpty(authority)) + if (isNonEmpty(authority)) { path = ""; + } } } private void computeRegularPath() { - if (urlWithoutQuery.charAt(start) == '/') - path = urlWithoutQuery.substring(start, end); - - else if (isNonEmpty(path)) + if (originalUrl.charAt(currentIndex) == '/') { + path = originalUrl.substring(currentIndex, end); + } else if (isNonEmpty(path)) { handleRelativePath(); - - else { - String pathEnd = urlWithoutQuery.substring(start, end); + } else { + String pathEnd = originalUrl.substring(currentIndex, end); path = isNonEmpty(pathEnd) && pathEnd.charAt(0) != '/' ? "/" + pathEnd : pathEnd; } handlePathDots(); @@ -307,29 +325,31 @@ private void computeQueryOnlyPath() { private void computePath(boolean queryOnly) { // Parse the file path if any - if (start < end) + if (currentIndex < end) { computeRegularPath(); - else if (queryOnly && path != null) + } else if (queryOnly && path != null) { computeQueryOnlyPath(); - else if (path == null) + } else if (path == null) { path = ""; + } } public void parse(Uri context, final String originalUrl) { assertNotNull(originalUrl, "orginalUri"); - - boolean isRelative = false; - - trimRight(originalUrl); - trimLeft(originalUrl); - if (!isFragmentOnly(originalUrl)) - computeInitialScheme(originalUrl); - overrideWithContext(context, originalUrl); - computeFragment(originalUrl); + this.originalUrl = originalUrl; + this.end = originalUrl.length(); + + trimLeft(); + trimRight(); + currentIndex = start; + if (!isFragmentOnly()) { + computeInitialScheme(); + } + boolean isRelative = overrideWithContext(context); + trimFragment(); inheritContextQuery(context, isRelative); - - boolean queryOnly = splitUrlAndQuery(originalUrl); + boolean queryOnly = computeQuery(); parseAuthority(); computePath(queryOnly); } diff --git a/client/src/test/java/org/asynchttpclient/uri/UriParserTest.java b/client/src/test/java/org/asynchttpclient/uri/UriParserTest.java index 2f33996262..8b1fe21661 100644 --- a/client/src/test/java/org/asynchttpclient/uri/UriParserTest.java +++ b/client/src/test/java/org/asynchttpclient/uri/UriParserTest.java @@ -15,124 +15,109 @@ import static org.testng.Assert.*; +import java.net.MalformedURLException; +import java.net.URI; + import org.testng.annotations.Test; public class UriParserTest { + private static void assertUriEquals(UriParser parser, URI uri) { + assertEquals(parser.scheme, uri.getScheme()); + assertEquals(parser.userInfo, uri.getUserInfo()); + assertEquals(parser.host, uri.getHost()); + assertEquals(parser.port, uri.getPort()); + assertEquals(parser.path, uri.getPath()); + assertEquals(parser.query, uri.getQuery()); + } + + private static void validateAgainstAbsoluteURI(String url) throws MalformedURLException { + UriParser parser = new UriParser(); + parser.parse(null, url); + assertUriEquals(parser, URI.create(url)); + } + + @Test + public void testUrlWithPathAndQuery() throws MalformedURLException { + validateAgainstAbsoluteURI("http://example.com:8080/test?q=1"); + } + + @Test + public void testFragmentTryingToTrickAuthorityAsBasicAuthCredentials() throws MalformedURLException { + validateAgainstAbsoluteURI("http://1.2.3.4:81#@5.6.7.8:82/aaa/b?q=xxx"); + } + @Test public void testUrlHasLeadingAndTrailingWhiteSpace() { UriParser parser = new UriParser(); - parser.parse(null, " http://user@example.com:8080/test?q=1 "); - assertEquals(parser.authority, "user@example.com:8080", "Incorrect authority assigned by the parse method"); - assertEquals(parser.host, "example.com", "Incorrect host assigned by the parse method"); - assertEquals(parser.path, "/test", "Incorrect path assigned by the parse method"); - assertEquals(parser.port, 8080, "Incorrect port assigned by the parse method"); - assertEquals(parser.query, "q=1", "Incorrect query assigned by the parse method"); - assertEquals(parser.scheme, "http", "Incorrect scheme assigned by the parse method"); - assertEquals(parser.userInfo, "user", "Incorrect userInfo assigned by the parse method"); + String url = " http://user@example.com:8080/test?q=1 "; + parser.parse(null, url); + assertUriEquals(parser, URI.create(url.trim())); + } + + private static void validateAgainstRelativeURI(Uri uriContext, String urlContext, String url) { + UriParser parser = new UriParser(); + parser.parse(uriContext, url); + assertUriEquals(parser, URI.create(urlContext).resolve(URI.create(url))); } @Test - public void testSchemeTakenFromUrlWhenValid() { + public void testResolveAbsoluteUriAgainstContext() { Uri context = new Uri("https", null, "example.com", 80, "/path", ""); - UriParser parser = new UriParser(); - parser.parse(context, "http://example.com/path"); - assertEquals(parser.scheme, "http", "If URL has a valid scheme it should be given priority than the scheme in the context"); + validateAgainstRelativeURI(context, "https://example.com:80/path", "http://example.com/path"); } @Test - public void testRelativeURL() { + public void testRootRelativePath() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "/relativeUrl"); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/relativeUrl", "Path should be equal to the relative URL passed to the parse method"); - assertEquals(parser.query, null, "Query should be empty if the relative URL did not have a query"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "/relativeUrl"); } @Test - public void testUrlFragment() { + public void testCurrentDirRelativePath() { + Uri context = new Uri("https", null, "example.com", 80, "/foo/bar", "q=2"); + validateAgainstRelativeURI(context, "https://example.com:80/foo/bar?q=2", "relativeUrl"); + } + + @Test + public void testFragmentOnly() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "#test"); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a URL fragment"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a URL fragment"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a URL fragment"); - assertEquals(parser.path, "/path", "Path should be taken from the context when parsing a URL fragment"); - assertEquals(parser.query, null, "Query should be empty when parsing a URL fragment"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "#test"); } @Test public void testRelativeUrlWithQuery() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "/relativePath?q=3"); - assertEquals(parser.host, "example.com", "Host should be taken from the contenxt when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/relativePath", "Path should be same as relativePath passed to the parse method"); - assertEquals(parser.query, "q=3", "Query should be taken from the relative URL"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "/relativePath?q=3"); } @Test public void testRelativeUrlWithQueryOnly() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "?q=3"); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the conxt when parsing a relative URL"); - assertEquals(parser.path, "/", "Path should be '/' for a relative URL with only query"); - assertEquals(parser.query, "q=3", "Query should be same as specified in the relative URL"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "?q=3"); } @Test public void testRelativeURLWithDots() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "./relative/./url"); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/relative/url", "Path should be equal to the path in the relative URL with dots removed"); - assertEquals(parser.query, null, "Query should be null if the relative URL did not have a query"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/./url"); } @Test public void testRelativeURLWithTwoEmbeddedDots() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "./relative/../url"); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/url", "Path should be equal to the relative URL path with the embedded dots appropriately removed"); - assertEquals(parser.query, null, "Query should be null if the relative URL does not have a query"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/../url"); } @Test public void testRelativeURLWithTwoTrailingDots() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "./relative/url/.."); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/relative/", "Path should be equal to the relative URL path with the trailing dots appropriately removed"); - assertEquals(parser.query, null, "Query should be null if the relative URL does not have a query"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/url/.."); } @Test public void testRelativeURLWithOneTrailingDot() { Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2"); - UriParser parser = new UriParser(); - parser.parse(context, "./relative/url/."); - assertEquals(parser.host, "example.com", "Host should be taken from the context when parsing a relative URL"); - assertEquals(parser.port, 80, "Port should be taken from the context when parsing a relative URL"); - assertEquals(parser.scheme, "https", "Scheme should be taken from the context when parsing a relative URL"); - assertEquals(parser.path, "/relative/url/", "Path should be equal to the relative URL path with the trailing dot appropriately removed"); - assertEquals(parser.query, null, "Query should be null if the relative URL does not have a query"); + validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/url/."); } } diff --git a/client/src/test/java/org/asynchttpclient/uri/UriTest.java b/client/src/test/java/org/asynchttpclient/uri/UriTest.java index 92685358f3..2cf79e2c00 100644 --- a/client/src/test/java/org/asynchttpclient/uri/UriTest.java +++ b/client/src/test/java/org/asynchttpclient/uri/UriTest.java @@ -14,231 +14,114 @@ import static org.testng.Assert.*; +import java.net.MalformedURLException; +import java.net.URI; + import org.testng.annotations.Test; public class UriTest { - @Test - public void testSimpleParsing() { - Uri url = Uri.create("https://graph.facebook.com/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + private static void assertUriEquals(Uri uri, URI javaUri) { + assertEquals(uri.getScheme(), uri.getScheme()); + assertEquals(uri.getUserInfo(), uri.getUserInfo()); + assertEquals(uri.getHost(), uri.getHost()); + assertEquals(uri.getPort(), uri.getPort()); + assertEquals(uri.getPath(), uri.getPath()); + assertEquals(uri.getQuery(), uri.getQuery()); } - @Test - public void testRootRelativeURIWithRootContext() { - - Uri context = Uri.create("https://graph.facebook.com"); - - Uri url = Uri.create(context, "/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + private static void validateAgainstAbsoluteURI(String url) throws MalformedURLException { + assertUriEquals(Uri.create(url), URI.create(url)); + } - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + private static void validateAgainstRelativeURI(String context, String url) throws MalformedURLException { + assertUriEquals(Uri.create(Uri.create(context), url), URI.create(context).resolve(URI.create(url))); } @Test - public void testRootRelativeURIWithNonRootContext() { - - Uri context = Uri.create("https://graph.facebook.com/foo/bar"); - - Uri url = Uri.create(context, "/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + public void testSimpleParsing() throws MalformedURLException { + validateAgainstAbsoluteURI("https://graph.facebook.com/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testNonRootRelativeURIWithNonRootContext() { - - Uri context = Uri.create("https://graph.facebook.com/foo/bar"); - - Uri url = Uri.create(context, "750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/foo/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + public void testRootRelativeURIWithRootContext() throws MalformedURLException { + validateAgainstRelativeURI("https://graph.facebook.com", "/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testNonRootRelativeURIWithRootContext() { - - Uri context = Uri.create("https://graph.facebook.com"); - - Uri url = Uri.create(context, "750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + public void testRootRelativeURIWithNonRootContext() throws MalformedURLException { + validateAgainstRelativeURI("https://graph.facebook.com/foo/bar", "/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testAbsoluteURIWithContext() { - - Uri context = Uri.create("https://hello.com/foo/bar"); - - Uri url = Uri.create(context, "https://graph.facebook.com/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "graph.facebook.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/750198471659552/accounts/test-users"); - assertEquals(url.getQuery(), "method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); + public void testNonRootRelativeURIWithNonRootContext() throws MalformedURLException { + validateAgainstRelativeURI("https://graph.facebook.com/foo/bar", "750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testRelativeUriWithDots() { - Uri context = Uri.create("https://hello.com/level1/level2/"); - - Uri url = Uri.create(context, "../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/level1/other/content/img.png"); - assertNull(url.getQuery()); + public void testNonRootRelativeURIWithRootContext() throws MalformedURLException { + validateAgainstRelativeURI("https://graph.facebook.com", "750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testRelativeUriWithDotsAboveRoot() { - Uri context = Uri.create("https://hello.com/level1"); - - Uri url = Uri.create(context, "../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../other/content/img.png"); - assertNull(url.getQuery()); + public void testAbsoluteURIWithContext() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/foo/bar", + "https://graph.facebook.com/750198471659552/accounts/test-users?method=get&access_token=750198471659552lleveCvbUu_zqBa9tkT3tcgaPh4"); } @Test - public void testRelativeUriWithAbsoluteDots() { - Uri context = Uri.create("https://hello.com/level1/"); - - Uri url = Uri.create(context, "/../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithDots() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2/", "../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDots() { - Uri context = Uri.create("https://hello.com/level1/level2/"); - - Uri url = Uri.create(context, "../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithDotsAboveRoot() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1", "../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDotsAboveRoot() { - Uri context = Uri.create("https://hello.com/level1/level2"); - - Uri url = Uri.create(context, "../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithAbsoluteDots() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/", "/../other/content/img.png"); } @Test - public void testRelativeUriWithAbsoluteConsecutiveDots() { - Uri context = Uri.create("https://hello.com/level1/level2/"); - - Uri url = Uri.create(context, "/../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithConsecutiveDots() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2/", "../../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDotsFromRoot() { - Uri context = Uri.create("https://hello.com/"); - - Uri url = Uri.create(context, "../../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../../../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithConsecutiveDotsAboveRoot() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2", "../../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDotsFromRootResource() { - Uri context = Uri.create("https://hello.com/level1"); - - Uri url = Uri.create(context, "../../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../../../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithAbsoluteConsecutiveDots() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2/", "/../../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDotsFromSubrootResource() { - Uri context = Uri.create("https://hello.com/level1/level2"); - - Uri url = Uri.create(context, "../../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithConsecutiveDotsFromRoot() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/", "../../../other/content/img.png"); } @Test - public void testRelativeUriWithConsecutiveDotsFromLevel3Resource() { - Uri context = Uri.create("https://hello.com/level1/level2/level3"); - - Uri url = Uri.create(context, "../../../other/content/img.png"); - - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "hello.com"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/../other/content/img.png"); - assertNull(url.getQuery()); + public void testRelativeUriWithConsecutiveDotsFromRootResource() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1", "../../../other/content/img.png"); } @Test - public void testRelativeUriWithNoScheme() { - Uri context = Uri.create("https://hello.com/level1"); + public void testRelativeUriWithConsecutiveDotsFromSubrootResource() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2", "../../../other/content/img.png"); + } - Uri url = Uri.create(context, "//world.org/content/img.png"); + @Test + public void testRelativeUriWithConsecutiveDotsFromLevel3Resource() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1/level2/level3", "../../../other/content/img.png"); + } - assertEquals(url.getScheme(), "https"); - assertEquals(url.getHost(), "world.org"); - assertEquals(url.getPort(), -1); - assertEquals(url.getPath(), "/content/img.png"); - assertNull(url.getQuery()); + @Test + public void testRelativeUriWithNoScheme() throws MalformedURLException { + validateAgainstRelativeURI("https://hello.com/level1", "//world.org/content/img.png"); } @Test