package com.mastfrog.url; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URLEncoder; import java.util.Arrays; import org.junit.Test; import static org.junit.Assert.*; import org.netbeans.validation.api.InvalidInputException; import org.netbeans.validation.api.Problems; /** * * @author Tim Boudreau */ public class URLTest { @Test public void testHostEquality() { Label l1 = new Label("one"); Label l2 = new Label("one"); Label l3 = new Label("ONE"); Label l4 = new Label("oNe"); assertEquals(l1, l2); assertEquals(l2, l3); assertEquals(l3, l4); assertEquals(l1, l4); assertEquals(l2, l4); Host one = Host.parse("WWW.Test.CoM"); Host two = Host.parse("www.test.com"); assertEquals(one, two); } @Test(expected = InvalidInputException.class) public void testUrlWithNoHostIsInvalid() { URL url = URL.builder().addPathElement("invalid").create(); assertFalse(url.isValid()); assertNotNull(url.getProblems()); assertTrue(url.getProblems().hasFatal()); url.getProblems().throwIfFatalPresent(); } @Test public void testNormalization() { URLBuilder builder = new URLBuilder(); builder.setProtocol(Protocols.HTTP); builder.setHost(Host.builder().add("com").add("timboudreau").add("www").create()); builder.setPath(Path.builder().add("path").add("to").add("stuff.html").create()); builder.setUserName("tim"); builder.setPassword("monkey"); builder.setQuery((ParsedParameters) Parameters.builder().add(new ParametersElement("foo", "bar")).add(new ParametersElement("moo", "goo")).create()); URL url = builder.create(); assertNotNull(url); builder = new URLBuilder(); builder.setProtocol(Protocols.HTTP); builder.setHost("WWW.TIMBOUDREAU.COM"); builder.setPath("path/to/stuff.html"); builder.setQuery((ParsedParameters) Parameters.builder().add(new ParametersElement("foo", "bar")).add(new ParametersElement("moo", "goo")).create()); builder.setUserName("tim"); builder.setPassword("monkey"); URL url2 = builder.create(); assertNotNull(url2); assertEquals(url, url2); assertEquals(url.toString(), url2.toString()); assertEquals("http://tim:monkey@www.timboudreau.com/path/to/stuff.html?moo=goo&foo=bar", url.toString()); assertTrue(url2.isValid()); assertFalse(url2.isSecure()); } @Test public void testInferFileReference() { Path a = Path.parse("com/foo/index.html"); Path b = Path.parse("com/foo/"); assertTrue(a.isProbableFileReference()); assertFalse(b.isProbableFileReference()); URLBuilder builder = new URLBuilder(); builder = new URLBuilder(); builder.setProtocol(Protocols.HTTP); builder.setHost("WWW.TIMBOUDREAU.COM"); builder.setPath("path/to/stuff.html"); assertTrue(builder.create().getPath().isProbableFileReference()); assertFalse(builder.create().getPath().toString().endsWith("/")); assertFalse(builder.create().toString().endsWith("/")); builder = new URLBuilder(); builder.setProtocol(Protocols.HTTP); builder.setHost("WWW.TIMBOUDREAU.COM"); builder.setPath("path/to/stuff"); assertFalse(builder.create().getPath().isProbableFileReference()); } @Test public void testValidity() { URLBuilder b = new URLBuilder(); b.setProtocol("foo"); b.setHost("-foo.com"); assertFalse(b.create().isValid()); assertFalse(b.create().isKnownProtocol()); } @Test public void testPasswordValidity() { URLBuilder b = new URLBuilder(); b.setProtocol(Protocols.HTTPS); assertFalse(b.create().isValid()); b.setHost(Host.builder().add("com").add("timboudreau").add("www").create()); assertTrue(b.create().isValid()); b.setUserName("foo"); assertTrue(b.create().isValid()); b.setPassword("illegal password"); assertFalse(b.create().isValid()); assertTrue(b.create().isSecure()); assertTrue(b.create().isKnownProtocol()); } @Test public void testIllegalCharactersValidity() { URLBuilder b = new URLBuilder(); b.setProtocol(Protocols.HTTPS); b.setHost("foo.テテ.טעסט"); assertFalse(b.create().isValid()); assertNotNull(b.create().getInvalidComponent()); assertTrue(b.create().getInvalidComponent() instanceof Label); } @Test public void testHighAsciiCharactersInPath() { PathElement el = new PathElement("foo"); assertTrue(el.isValid()); el = new PathElement(createHighAsciiString()); assertTrue(el.isValid()); } @Test public void testHighAsciiCharactersInLabel() { Label lbl = new Label("foo"); assertTrue(lbl.isValid()); lbl = new Label(createHighAsciiString()); assertFalse(lbl.isValid()); } private static String createHighAsciiString() { return createHighAsciiString(5); } private static String createHighAsciiString(int len) { char[] c = new char[5]; char b = 128; for (int i = 0; i < c.length; i++) { b++; c[i] = b; assertTrue(URLBuilder.isEncodableInLatin1(c[i])); } return new String(c); } @Test public void testHighAsciiCharactersValidity() { URLBuilder b = new URLBuilder(); b.setProtocol(Protocols.HTTP); b.setHost(Host.builder().add("com").add("foo").create()); assertTrue(b.create().isValid()); b = new URLBuilder(Protocols.HTTP); b.setHost(Host.builder().add("com").add("foo").create()); b.setPath(Path.builder().add("foo").add(createHighAsciiString()).create()); assertNull(b.create().getInvalidComponent()); for (URLComponent c : b.create().allComponents()) { assertTrue(c + " (" + c.getClass().getName() + ")", c.isValid()); } assertTrue(b.create().getPath().isValid()); assertTrue("Invalid comp " + b.create().getInvalidComponent(), b.create().isValid()); } @Test public void testCharactersAbove256AreInvalid() { URLBuilder b = new URLBuilder(); b.setProtocol(Protocols.HTTP); char[] c = new char[5]; for (int i = 0; i < c.length; i++) { c[i] = (char) (256 + i); } b.setHost(Host.builder().add("com").add(new String(c)).create()); assertFalse(b.create().isValid()); } @Test public void testHostParse() { Host h = Host.parse("COM.FOO.BAR"); assertNotNull(h); assertEquals("com.foo.bar", h.toString()); assertTrue(h.isValid()); h = Host.parse("C M.FOO.BAR"); assertNotNull(h); assertEquals("c m.foo.bar", h.toString()); assertFalse(h.isValid()); h = Host.parse("COM..foo...bar"); assertEquals("com..foo...bar", h.toString()); assertFalse(h.isValid()); } @Test public void testPathConversion() { Path p1 = Path.parse("com/foo/bar/baz/index.html"); Path p2 = Path.parse("com/foo/bar/baz"); Path p3 = Path.parse("com/foo/bar/baz"); assertFalse("".equals(p1.toString())); assertFalse("".equals(p2.toString())); assertFalse("".equals(p3.toString())); assertTrue(p2.isParentOf(p1)); assertTrue(p1.isChildOf(p2)); assertFalse(p2 + " should not be a child of " + p1, p2.isChildOf(p1)); assertFalse(p1 + " should not be a parent of " + p2, p1.isParentOf(p2)); assertEquals(p2, p1.getParentPath()); assertTrue(p3 + " should be a parent of " + p1, p3.isParentOf(p1)); assertTrue(p1 + " should be a child of " + p3, p1.isChildOf(p3)); assertFalse(p3 + " should not be a child of " + p1, p3.isChildOf(p1)); assertFalse(p1 + " should not be a parent of " + p3, p1.isParentOf(p3)); assertEquals(p3, p1.getParentPath()); } @Test public void testUrlConversion() throws MalformedURLException { java.net.URL url = url("http://timboudreau.com/stuff/index.html?bar=baz;foo=bar#anchor"); URL real = URL.fromJavaUrl(url); assertEquals(url.toString(), real.toString()); url = url("http://tim:password@timboudreau.com/stuff/index.html?bar=baz;foo=bar#anchor"); real = URL.fromJavaUrl(url); assertEquals("Expected\n;" + url + " but got " + real, url.toString(), real.toString()); } @Test public void testUnescape2() { StringBuilder sb = new StringBuilder(); for (char c = 0; c < 5; c++) { sb.append(c); } String unescaped = sb.toString(); String escaped = URLBuilder.escape(unescaped); String re_unescaped = URLBuilder.unescape(escaped); assertEquals(unescaped, re_unescaped); } @Test public void testUnescape3() { StringBuilder sb = new StringBuilder(); for (char c = 5; c < 25; c++) { sb.append(c); } String unescaped = sb.toString(); String escaped = URLBuilder.escape(unescaped); String re_unescaped = URLBuilder.unescape(escaped); assertEquals(unescaped, re_unescaped); } @Test public void testUnescapeMangled() { String mangled = "x%20%%y%%20zqr%20hello%20world%0g52rp"; String expect = "x %%y% zqr hello world%0g52rp"; assertEquals(expect, URLBuilder.unescape(mangled)); } @Test public void testParseInvalidURLs() throws MalformedURLException { test("foo/bar/baz/"); test("foo/bar/baz/" + URLBuilder.escape(")*(&#@FAIUSHFH;()@##") + "/"); } @Test public void testParse() throws Exception { test("http://www.sun.com/"); test("http://url.timboudreau.com/"); test("http://url.timboudreau.com/stuff/"); test("http://url.timboudreau.com/stuff/index.html"); test("http://url.timboudreau.com/stuff/index.html#anchor"); test("http://url.timboudreau.com/stuff/index.html?bar=baz;foo=bar"); // test ("http://url.timboudreau.com/stuff/index.html?bar=baz;foo=bar;"); test("http://url.timboudreau.com/stuff/index.html?bar=baz;foo=bar#anchor"); test("http://url.timboudreau.com/stuff/index.html?bar=baz&foo=bar"); // test ("http://url.timboudreau.com/stuff/index.html?bar=baz&foo=bar&"); test("http://url.timboudreau.com/stuff/index.html?bar=baz&foo=bar#anchor"); test("http://url.timboudreau.com/stuff/#anchor"); } @Test public void testParseWithCredentials() throws Exception { test("http://tim:password@url.timboudreau.com/"); test("http://tim:password@url.timboudreau.com/stuff/"); test("http://tim:password@url.timboudreau.com/stuff/index.html"); test("http://tim:password@url.timboudreau.com/stuff/index.html#anchor"); test("http://tim:password@url.timboudreau.com/stuff/index.html?bar=baz;foo=bar#anchor"); // test ("http://tim:password@url.timboudreau.com/stuff/index.html?bar=baz;foo=bar;#anchor"); test("http://tim:password@url.timboudreau.com/stuff/index.html?bar=baz;foo=bar#anchor"); test("http://tim:password@url.timboudreau.com/stuff/#anchor"); } @Test public void testParseParameters() { ParsedParameters p; ParametersElement pe = ParametersElement.parse("foo=bar"); assertEquals("foo=bar", pe.toString()); pe = ParametersElement.parse("bar=baz"); assertEquals("bar=baz", pe.toString()); p = (ParsedParameters) Parameters.parse("foo=bar;bar=baz"); p = (ParsedParameters) Parameters.parse(""); assertNull(p); p = (ParsedParameters) Parameters.parse("=bar"); assertNull("Key should be null but is " + p.getElements()[0].getKey(), p.getElements()[0].getKey()); assertEquals("bar", p.getElements()[0].getValue()); assertEquals("Got '" + p.toString() + "'", "?=bar", p.toString()); p = (ParsedParameters) Parameters.parse("foo"); assertEquals("?foo", p.toString()); assertEquals("foo", p.getElements()[0].getKey()); assertNull(p.getElements()[0].getValue()); } @Test public void testHostParents() { Host h = Host.parse("www.timboudreau.com"); assertEquals(Host.parse("timboudreau.com"), h.getParentDomain()); Label[] l = h.getLabels(); assertEquals(new Label("com"), l[0]); assertEquals(new Label("timboudreau"), l[1]); assertEquals(new Label("www"), l[2]); assertEquals(new Label("com"), h.getTopLevelDomain()); assertEquals(new Label("timboudreau"), h.getDomain()); } @Test public void testSameDomain() { Host h = Host.parse("weblogs.java.net"); assertTrue(h.isDomain("java.net")); assertTrue(h.isDomain("weblogs.java.net")); assertFalse(h.isDomain("bubble.java.net")); assertFalse(h.isDomain("java.com")); } @Test public void testAddedLabelsAreUsed() { URLBuilder builder = URL.builder(Protocols.HTTP); builder.addDomain("www"); builder.addDomain("goofball"); builder.addDomain("com"); assertEquals("http://www.goofball.com/", builder.create().toString()); } @Test public void testValidation() { URLBuilder builder = URL.builder(Protocols.HTTP); builder.addDomain("www"); builder.addDomain("goofball"); builder.addDomain("com"); assertTrue(builder.create().getHost().isValid()); builder = URL.builder(Protocols.HTTP); builder.addDomain("www"); builder.addDomain("goofball"); builder.addDomain("com"); Host h = Host.parse("x%20%%y%%20zqr%20hello%20world%0g52rp.foo.com"); assertFalse(h.isValid()); assertNotNull(h.getProblems()); assertTrue(h.getProblems().hasFatal()); builder = URL.builder(Protocols.HTTP).setHost(h).addPathElement("foo").addPathElement("bar"); assertNotNull(builder.create().getProblems()); assertTrue(builder.create().getProblems().hasFatal()); assertFalse(builder.create().isValid()); builder = URL.builder(Protocols.HTTP).setHost(Host.parse("..wwwaa ..hoo.com")).addPathElement("stuff"); assertNotNull(builder.create().getProblems()); assertTrue(builder.create().getProblems().hasFatal()); assertFalse(builder.create().isValid()); } @Test public void testBadPathParsing() { String shouldKeepTrailingSlash = "bad/stuff/"; Path p = Path.parse(shouldKeepTrailingSlash); assertTrue(p.toString().endsWith("/")); String bad = "bad///stuff"; p = Path.parse(bad); assertEquals(bad, p.toString()); p = Path.parse("relative/path/../../stuff/"); assertEquals("stuff/", p.normalize().toString()); p = Path.parse("local/path/./././stuff"); assertEquals("local/path/stuff", p.normalize().toString()); p = Path.parse("local/path/./././stuff/"); assertEquals("local/path/stuff/", p.normalize().toString()); p = Path.parse("bad/path/../../../../stuff"); assertFalse(p.normalize().isValid()); assertEquals("bad/path/../../../../stuff", p.normalize().toString()); } @Test public void testLocalhost() { Host a = Host.parse(""); Host b = Host.parse("localhost"); Host c = Host.parse("127.0.0.1"); assertTrue(a.isLocalhost()); assertTrue(b.isLocalhost()); assertTrue(c.isLocalhost()); assertEquals(a, b); assertEquals(b, c); assertEquals(a, c); URL u1 = URL.parse("file:///x/y/z.txt"); URL u2 = URL.parse("file://localhost/x/y/z.txt"); // assertEquals (u1.toString(), u2.toString()); assertEquals(u1, u2); u1 = URL.parse("file:///c:/WINDOWS/clock.avi"); assertEquals("file:///c:/WINDOWS/clock.avi", u1.toString()); assertNotNull(u1.getHost()); assertTrue(u1.getHost().isLocalhost()); assertEquals("c:/WINDOWS/clock.avi", u1.getPath().toString()); } @Test public void testParseFileURLs() throws Exception { test("http://foo.com/Users/tim/someFile.html?bar=baz;foo=bar#stuff"); test("file:///Users/tim/#stuff"); test("file:///Users/tim/someFile.html#stuff"); URL url = URL.parse("file://somehost/path/to/stuff"); assertNotNull(url.getHost()); assertEquals("somehost", url.getHost().toString()); } private void test(String urlString) throws MalformedURLException { URL url = URL.parse(urlString); assertTrue("Expected\n" + urlString + " but got \n" + url, urlString.equals(url.toString())); try { java.net.URL u = url(urlString); String uString = u.toExternalForm(); if (uString.startsWith("file:/") && !uString.startsWith("file:///")) { uString = "file:///" + uString.substring(6); } URL real = URL.fromJavaUrl(u); assertEquals("Expected\n'" + uString + "' but got \n'" + real + "'", uString, real.toString()); } catch (MalformedURLException mue) { } } private java.net.URL url(String s) throws MalformedURLException { return new java.net.URL(s); } @Test public void testUnescape() { assertEquals("hello world", URLBuilder.unescape("hello%20world")); assertEquals(" ", URLBuilder.unescape("%20")); StringBuilder sb = new StringBuilder(); for (char c = 0; c < 255; c++) { if (c == 25) { continue; } sb.append(c); } String unescaped = sb.toString(); String escaped = URLBuilder.escape(unescaped); String re_unescaped = URLBuilder.unescape(escaped); assertEquals(examine(unescaped, re_unescaped), unescaped, re_unescaped); } private String examine(String a, String b) { StringBuilder sb = new StringBuilder(); if (a.length() != b.length()) { sb.append("Lengths different: ").append(a.length()).append(",").append(b.length()); } for (int i = 0; i < Math.min(a.length(), b.length()); i++) { if (a.charAt(i) != b.charAt(i)) { sb.append("\nMismatch at ").append(i).append(": ").append(a.charAt(i)).append(",").append(b.charAt(i)); } } sb.append("\n").append(a); sb.append("\n").append(b); sb.append("\n"); return sb.toString(); } @Test public void testDifferentiateIPandNot() { URL url = URL.parse("http://127.0.0.1:8080/foo.txt"); Host h = url.getHost(); assertTrue(h + " claims it is not an IP address and has " + h.getLabels().length + " labels: " + Arrays.asList(h.getLabels()), h.isIpAddress()); assertNull("Domain should be null but is " + h.getDomain(), h.getDomain()); url = URL.parse("http://foo.com:8080/foo.txt"); h = url.getHost(); assertFalse(h.isIpAddress()); assertNotNull(h.getDomain()); } @Test public void testAccuracy() { testUrlToString("http://127.0.0.1:8080/?kind=anything&recipient=moe%40foo.com&url=http://food.com/food.com", "http://127.0.0.1:8080/?kind=anything&recipient=moe@foo.com&url=http://food.com/food.com"); //should always append a trailing slash to host-only URLs testUrlToString("http://food.com/", "http://food.com"); //host only URLs w/ trailing slash should not be altered testUrlToString("http://food.com/"); testUrlToString("http://food.com/boo/"); testUrlToString("http://food.com/boo/bar"); //Ensure parameters parsing creates something reproducible testUrlToString("http://food.com/boo/foo.html?q=x?a=3"); testUrlToString("http://www.quirksmode.org/css/textoverflow.html"); // testUrlToString("http://stackoverflow.com/questions/868288/getting%2dthe%2dvisible%2drect%2dof%2dan%2duiscrollviews%2dcontent", "http://stackoverflow.com/questions/868288/getting-the-visible-rect-of-an-uiscrollviews-content"); testUrlToString("http://stackoverflow.com/questions/868288/getting-the-visible-rect-of-an-uiscrollviews-content", "http://stackoverflow.com/questions/868288/getting-the-visible-rect-of-an-uiscrollviews-content"); testUrlToString("http://www.google.com/search?hl=en&client=safari&rls=en&q=javascript+get+bounding+rectangle+of+the+window&aq=f&aqi=&aql=&oq=&gs%5frfai=", "http://www.google.com/search?hl=en&client=safari&rls=en&q=javascript+get+bounding+rectangle+of+the+window&aq=f&aqi=&aql=&oq=&gs_rfai="); testUrlToString("http://www.p01.org/releases/Drawing%5flines%5fin%5fJavaScript/", "http://www.p01.org/releases/Drawing_lines_in_JavaScript/"); testUrlToString("http://www.p01.org/releases/Drawing%5flines%5fin%5fJavaScript/x.html#", "http://www.p01.org/releases/Drawing_lines_in_JavaScript/x.html#"); URL url = URL.parse("http://www.p01.org/releases/Drawing_lines_in_JavaScript/x.html#"); assertNotNull(url.getAnchor()); testUrlToString("http://food.com/badpath/////stuff"); testUrlToString("http://food.com/stuff", "http://food.com/relative/path/../../stuff"); testUrlToString("http://food.com/stuff", "http://food.com/relative/path/../.././././stuff"); testUrlToString("http://food.com/relative/path/stuff", "http://food.com/relative/path/./././stuff"); //should not try to normalize invalid paths testUrlToString("http://food.com/relative/path/stuff/../../../../../../../../..", "http://food.com/relative/path/stuff/../../../../../../../../.."); testUrlToString("http://food.com/relative/", "http://food.com/relative/path/stuff/../.."); //ensure unparseable parameters are handled as-is testUrlToString("http://food.com/boo/foo.html?q=x?a=3????z=q=b=4;??;a?e==f"); } private void testUrlToString(String expect) { testUrlToString(expect, expect); } private void testUrlToString(String expect, String u) { URL url = URL.parse(u); String s = url.toString(); assertEquals(s, url.toString()); assertEquals("Expected '" + expect + "' got '" + url.toString() + "' - " + decombobulate(url, expect), expect, url.toString()); if ("http://food.com".equals(u)) { u = "http://food.com/"; } if (!u.contains("/..") && !u.contains("/.") && !url.getHost().isLocalhost()) { assertEquals(decombobulate(url, expect), u, url.toUnescapedForm()); } if (!u.contains("/../../../../../../../../..")) { assertValid(u); } } @Test public void validity() { assertInvalid("http:///a/b/c"); assertInvalid("http://x/a/b/c"); assertInvalid("http://127.z.b.32/a/b/c"); assertInvalid("http://127.z.b.32/a/b/c"); StringBuilder lng = new StringBuilder(); for (int i = 0; i < 270; i++) { lng.append('a'); } lng.append(".com"); assertInvalid("http://" + lng + "/x.txt"); assertInvalid("http://"); assertInvalid("http://foo"); assertInvalid("a"); assertInvalid("a:b"); assertInvalid("a:b:c"); assertInvalid("a:b:2308"); assertInvalid("http://foo.com:00badPort/x.html"); assertInvalid("http://foo.com:00badPort/"); assertInvalid("http://foo.com:00badPort"); URL url = URL.parse("http://localhost:8080/?kind=anything&recipient=moe@foo.com&url=http://food.com/food.com"); assertEquals("127.0.0.1", url.getHost().toString()); assertTrue(url.getHost().isIpAddress()); assertEquals(Host.parse("127.0.0.1"), url.getHost()); assertNull(url.getHost().getTopLevelDomain()); assertNull(url.getHost().getDomain()); assertEquals("8080", url.getPort().toString()); assertTrue(url.isValid()); assertNull("Problems should be null but is " + url.getProblems(), url.getProblems()); } private void assertValid(String ur) { URL url = URL.parse(ur); testValidity(ur); assertTrue("'" + url + "' should be valid but reports isValid " + url.isValid() + " with problems '" + url.getProblems() + "'", url.isValid()); } private void assertInvalid(String ur) { URL url = URL.parse(ur); assertFalse("'" + url + "' should be invalid", url.isValid()); testValidity(ur); } private void testValidity(String ur) { URL url = URL.parse(ur); Problems p = url.getProblems(); boolean contradiction = (p == null) != url.isValid(); String msg = "URL '" + url + "' reports problems " + p + " with contradictory value of isValid() " + url.isValid(); assertFalse(msg, contradiction); } private static String decombobulate(URL url, String expect) { StringBuilder sb = new StringBuilder(); for (URLComponent c : url.components()) { if (sb.length() > 0) { sb.append(','); } sb.append(c.getComponentName()).append("=").append(c.toString()); } sb.append('\n'); sb.append(expect); sb.append('\n').append(url).append('\n'); return sb.toString(); } @Test public void testProblematic() { String s = "http://www.p01.org/releases/Drawing_lines_in_JavaScript/x.html#"; URL url = URL.parse(s); assertTrue(s + " should be valid", url.isValid()); } @Test public void testEquality() { URL a = URL.parse("http://goofball.com/"); URL b = URL.parse("http://goofball.com/"); URLComponent[] ac = a.allComponents(); URLComponent[] bc = b.allComponents(); for (int i = 0; i < ac.length; i++) { assertEquals(i + ": " + ac[i] + " (" + ac[i].getComponentName() + " - " + ac[i].getClass().getName() + ") equal? " + ac[i].equals(bc[i]), ac[i], bc[i]); } ac = a.components(); bc = b.components(); for (int i = 0; i < ac.length; i++) { assertEquals(i + ": " + ac[i] + " (" + ac[i].getComponentName() + " - " + ac[i].getClass().getName() + ") equal? " + ac[i].equals(bc[i]), ac[i], bc[i]); } URL c = URL.parse("http://goofball.com"); assertEquals(a, b); assertEquals(a, c); URL d = URL.parse("http://foo.com"); assertFalse(a.equals(d)); a = URL.parse("http://goofball.com/"); b = URL.parse("http://goofball.com:80/"); assertEquals(a, b); a = URL.parse("https://goofball.com/"); assertFalse(a.equals(b)); b = URL.parse("https://goofball.com:443"); assertEquals(a, b); b = URL.parse("https://goofball.com:443/"); assertEquals(a, b); b = URL.parse("https://goofball.com:/ "); //XXX legal? a = URL.parse("https://goofball.com/%20"); assertEquals(a, b); } @Test public void testHorriblyMangledURLsDoNotThrowExceptions() { char[] c = new char[1024]; c[512] = ':'; c[513] = ':'; URL u = URL.parse(new String(c)); u = URL.parse(""); assertFalse(u.isValid()); u = URL.parse(" "); assertFalse(u.isValid()); u = URL.parse(" "); assertFalse(u.isValid()); u = URL.parse(" :"); assertFalse(u.isValid()); u = URL.parse(" /:"); assertFalse(u.isValid()); u = URL.parse(" :/:"); assertFalse(u.isValid()); u = URL.parse("/:"); assertFalse(u.isValid()); u = URL.parse(":/:"); assertFalse(u.isValid()); u = URL.parse("///:"); assertFalse(u.isValid()); u = URL.parse("/:/:"); assertFalse(u.isValid()); u = URL.parse(":"); assertFalse(u.isValid()); u = URL.parse("/"); assertFalse(u.isValid()); u = URL.parse("h"); assertFalse(u.isValid()); u = URL.parse("1"); assertFalse(u.isValid()); u = URL.parse("12"); assertFalse(u.isValid()); u = URL.parse(":12"); assertFalse(u.isValid()); u = URL.parse(":12/"); assertFalse(u.isValid()); u = URL.parse("::::::::::::::::::::::::::::::::::::::::::::::::::"); assertFalse(u.isValid()); u = URL.parse(".................................................."); assertFalse(u.isValid()); u = URL.parse("//////////////////////////"); assertFalse(u.isValid()); u = URL.parse("http://////////////////////////"); assertFalse(u.isValid()); u = URL.parse("http:foo@bar//////////////////////////"); assertFalse(u.isValid()); u = URL.parse("http:foo@//////////////////////////"); assertFalse(u.isValid()); u = URL.parse(":./:./:./:./:"); assertFalse(u.isValid()); long l = Integer.MAX_VALUE + 1; u = URL.parse("http://goofball.com:" + l); assertFalse(u.isValid()); } @Test public void testTrailingSlashes() { URL a = URL.parse("http://foo.com"); URL b = URL.parse("http://foo.com/"); assertEquals(a, b); URLBuilder ab = URL.builder(a); URLBuilder bb = URL.builder(b); URL a1 = ab.add("hey").create(); URL b1 = bb.add("hey").create(); assertEquals(a1, b1); URL a2 = URL.builder(a).add("foo").add("bar").create(); URL b2 = URL.builder(a).add("/foo").add("bar").create(); assertEquals(a2, b2); URL a3 = URL.builder(a).add("foo").add("bar").add("").add("/").create(); URL b3 = URL.builder(a).add("/foo").add("bar").create(); assertEquals(a3, b3); } @Test public void testValidityAndEscaping() { URL a = URL.parse("http://foo.com/stuff-here/more-stuff.foo"); assertTrue(a.getProblems() + "", a.isValid()); URL b = URL.builder(Protocols.HTTP).setHost("foo.com").add("stuff-here").add("more-stuff.foo").add("with spaces").create(); assertTrue(b.getProblems() + "", b.isValid()); } @Test public void testHyphens() { URL a = URL.parse("proto-http+more://foo.com/stuff-here"); assertEquals("proto-http+more", a.getProtocol().toString()); assertTrue(a.isValid()); } @Test public void testCyrillic() { URL a = URL.parse("http://www.socialskidka.com.ua/%D0%A7%D0%B5%D1%80%D0%BA%D0%B0%D1%81%D1%81%D1%8B"); String s = a.toUnescapedForm(); URL b = URL.parse(s); assertEquals(a, b); } @Test public void testFileURLs() throws Exception { File tmp = new File(System.getProperty("java.io.tmpdir")); // If tmp was a symlink, the test below was failing, so resolve it here tmp = tmp.getCanonicalFile(); File f = new File(tmp, getClass().getName() + "test"); java.net.URL url = f.toURI().toURL(); URL mine = URL.parse(url.toString()); assertEquals (url, mine.toJavaURL()); URL other = URL.fromJavaUrl(url); assertEquals (url, other.toJavaURL()); File f1 = new File (mine.toJavaURL().toURI()).getCanonicalFile(); File f2 = new File (other.toJavaURL().toURI()).getCanonicalFile(); assertEquals (f, f1); assertEquals (f, f2); f = new File (new java.net.URL("file:/tmp/1294067737125_0/ev1NYGFiVryRzOrUB3iZ2Pn8Tn0=").toURI()); URL x = URL.fromJavaUrl(new java.net.URL("file:/tmp/1294067737125_0/ev1NYGFiVryRzOrUB3iZ2Pn8Tn0=")); assertEquals ("file:///tmp/1294067737125%5f0/ev1NYGFiVryRzOrUB3iZ2Pn8Tn0=", x.toString()); URLBuilder b = URL.builder(x); b.addPathElement("xyz"); URL y = b.create(); assertTrue (y.getProblems() + "", y.isValid()); f = new File("/tmp/spaces in name"); url = f.toURI().toURL(); mine = URL.parse("file:/tmp/spaces in name"); assertEquals (url, mine.toJavaURL()); } // // @Test // public void testSpaces() { // URL a = URL.parse("http://foo.com/hey+you"); // URL b = URL.parse("http://foo.com/hey%20you"); // URL c = URL.parse("http://foo.com/hey you"); // assertEquals(a, b); // assertEquals(b, c); // assertEquals(a, c); // } @Test public void testPathDecoding() throws UnsupportedEncodingException { if (true) { return; } String orig = "path/to/My Image-small.gif"; String encoded = "path/to/" + URLEncoder.encode("My Image-small.gif", "UTF-8").replace("+", "%20").replace("-", "%2d"); assertNotEquals(orig, encoded); Path p = Path.parse(orig); assertEquals(encoded, p.toString()); Path p2 = Path.parse(encoded, true); assertEquals(orig, p2.toString()); assertEquals (p, p2); } @Test public void testAddParameters() throws Throwable { URL url = URL.parse("http://foo.com/foo/bar"); url = url.withParameter("baz", "quux"); assertEquals("http://foo.com/foo/bar?baz=quux", url.toString()); url = URL.parse("http://foo.com/foo/bar?monkey=beetle"); url = url.withParameter("baz", "quux"); assertEquals("http://foo.com/foo/bar?monkey=beetle&baz=quux", url.toString()); } @Test public void testHyphenatedHost() throws Throwable { Label l = new Label("mail-vm"); assertTrue(l.isValid()); Host host = Host.parse("mail-vm.timboudreau.org"); assertTrue(host.isValid()); assertNull(host.getProblems()); } @Test public void testHyphenation() throws Throwable { URL url = URL.parse("http://mail-vm.timboudreau.org/blog/api-list"); assertNull(url.getProblems()); assertTrue(url.isValid()); } @Test public void testParameters() throws Throwable { URL url = URL.builder(Protocols.HTTP).addDomain("timboudreau") .addDomain("com").addPathElement("foo").addPathElement("bar") .addQueryPair("quux", "baz").addQueryPair("money", "gone").create(); String q = url.getPathAndQuery(); assertEquals("/foo/bar?quux=baz&money=gone", q); assertEquals("http://timboudreau.com/foo/bar?quux=baz&money=gone", url.toString()); } }