You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2013/03/01 12:07:54 UTC

git commit: WICKET-5065 Improve UrlRenderer to be able to render urls without scheme and/or host

Updated Branches:
  refs/heads/master 4f7d2e474 -> b1e68de91


WICKET-5065 Improve UrlRenderer to be able to render urls without scheme and/or host

Update Url's javadoc that it could be full url. (this is true since a long time).
Improve Url#toString(StringMode.FULL) to be able to render urls without protocol (e.g. '//hostname/path')


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/b1e68de9
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/b1e68de9
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/b1e68de9

Branch: refs/heads/master
Commit: b1e68de911c0ccb71df58a6744bf3ad18c2f265d
Parents: 4f7d2e4
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Fri Mar 1 13:06:17 2013 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Fri Mar 1 13:06:17 2013 +0200

----------------------------------------------------------------------
 .../http/servlet/ServletWebRequestTest.java        |    8 +-
 .../main/java/org/apache/wicket/request/Url.java   |   71 +++++++++------
 .../java/org/apache/wicket/request/UrlTest.java    |   30 ++++++-
 3 files changed, 75 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/b1e68de9/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebRequestTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebRequestTest.java b/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebRequestTest.java
index 132b424..8e3cfe1 100644
--- a/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebRequestTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebRequestTest.java
@@ -49,20 +49,20 @@ public class ServletWebRequestTest extends Assert
 	public void wicket3599()
 	{
 		MockHttpServletRequest httpRequest = new MockHttpServletRequest(null, null, null);
-		httpRequest.setURL("/" + httpRequest.getContextPath() + "/request/Uri");
+		httpRequest.setURL(httpRequest.getContextPath() + "/request/Uri");
 		httpRequest.setParameter("some", "parameter");
 
-		ServletWebRequest webRequest = new ServletWebRequest(httpRequest, "/");
+		ServletWebRequest webRequest = new ServletWebRequest(httpRequest, "");
 		Url clientUrl = webRequest.getClientUrl();
 		assertEquals("request/Uri?some=parameter", clientUrl.toString());
 
 		// simulates a request that has errors metadata
 		httpRequest.setAttribute("javax.servlet.error.request_uri",
-			"/" + httpRequest.getContextPath() + "/any/source/of/error");
+			httpRequest.getContextPath() + "/any/source/of/error");
 		ServletWebRequest errorWebRequest = new ServletWebRequest(httpRequest, "/");
 		Url errorClientUrl = errorWebRequest.getClientUrl();
 
-		assertEquals("/any/source/of/error", errorClientUrl.toString());
+		assertEquals("any/source/of/error", errorClientUrl.toString());
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/wicket/blob/b1e68de9/wicket-request/src/main/java/org/apache/wicket/request/Url.java
----------------------------------------------------------------------
diff --git a/wicket-request/src/main/java/org/apache/wicket/request/Url.java b/wicket-request/src/main/java/org/apache/wicket/request/Url.java
index 191ebbe..12ca5f0 100755
--- a/wicket-request/src/main/java/org/apache/wicket/request/Url.java
+++ b/wicket-request/src/main/java/org/apache/wicket/request/Url.java
@@ -33,27 +33,36 @@ import org.apache.wicket.util.string.StringValue;
 import org.apache.wicket.util.string.Strings;
 
 /**
- * Represents the URL part <b>after Wicket Filter</b>. For example if Wicket Filter is mapped to
- * <code>/app/*</code> then with URL <code>/app/my/url</code> the {@link Url} object would represent
- * part <code>my/url</code>. If Wicket Filter is mapped to <code>/*</code> then with URL
- * <code>/my/url</code> the {@link Url} object would represent <code>my/url</code> (without leading
- * the slash).
- * <p>
- * URL consists of segments and query parameters.
+ * Represents the URL to an external resource or internal resource/component.
  * <p>
+ * A url could be:
+ * <ul>
+ *     <li>full - consists of an optional protocol/scheme, a host name, an optional port,
+ * optional segments and and optional query parameters.</li>
+ *      <li>non-full:
+ *      <ul>
+ *          <li>absolute - a url relative to the host name. Such url may escape from the application by using
+ *          different context path and/or different filter path. For example: <code>/foo/bar</code></li>
+ *          <li>relative - a url relative to the current base url. The base url is the url of the currently rendered page.
+ *          For example: <code>foo/bar</code>, <code>../foo/bar</code></li>
+ *      </ul>
+ * </ul>
+ *
+ * </p>
+ *
  * Example URLs:
  * 
- * <pre>
- * foo/bar/baz?a=1&amp;b=5    - segments: [&quot;foo&quot;,&quot;bar,&quot;baz], query parameters: [&quot;a&quot;=&quot;1&quot;, &quot;b&quot;=&quot;5&quot;]
- * foo/bar//baz?=4&amp;6      - segments: [&quot;foo&quot;, &quot;bar&quot;, &quot;&quot;, &quot;baz&quot;], query parameters: [&quot;&quot;=&quot;4&quot;, &quot;6&quot;=&quot;&quot;]
- * /foo/bar/              - segments: [&quot;&quot;, &quot;foo&quot;, &quot;bar&quot;, &quot;&quot;]
- * foo/bar//              - segments: [&quot;foo&quot;, &quot;bar&quot;, &quot;&quot;, &quot;&quot;]
- * ?a=b                   - segments: [ ], query parameters: [&quot;a&quot;=&quot;b&quot;]
- * /                      - segments: [&quot;&quot;, &quot;&quot;]   (note that Url represents part after Wicket Filter 
- *                                                - so if Wicket filter is mapped to /* this would be
- *                                                an additional slash, i.e. //
- * </pre>
- * 
+ * <ul>
+ *     <li>http://hostname:1234/foo/bar?a=b - protocol: http, host: hostname, port: 1234, segments: [&quot;foo&quot;,&quot;bar&quot;] </li>
+ *     <li>//hostname:1234/foo/bar?a=b - protocol: null, host: hostname, port: 1234, segments: [&quot;foo&quot;,&quot;bar&quot;] </li>
+ *     <li>foo/bar/baz?a=1&amp;b=5    - segments: [&quot;foo&quot;,&quot;bar&quot;,&quot;baz&quot;], query parameters: [&quot;a&quot;=&quot;1&quot;, &quot;b&quot;=&quot;5&quot;]</li>
+ *     <li>foo/bar//baz?=4&amp;6      - segments: [&quot;foo&quot;, &quot;bar&quot;, &quot;&quot;, &quot;baz&quot;], query parameters: [&quot;&quot;=&quot;4&quot;, &quot;6&quot;=&quot;&quot;]</li>
+ *     <li>/foo/bar/              - segments: [&quot;&quot;, &quot;foo&quot;, &quot;bar&quot;, &quot;&quot;]</li>
+ *     <li>foo/bar//              - segments: [&quot;foo&quot;, &quot;bar&quot;, &quot;&quot;, &quot;&quot;]</li>
+ *     <li>?a=b                   - segments: [ ], query parameters: [&quot;a&quot;=&quot;b&quot;]</li>
+ *     <li></li>
+ * </ul>
+ *
  * The Url class takes care of encoding and decoding of the segments and parameters.
  * 
  * @author Matej Knopp
@@ -221,13 +230,19 @@ public class Url implements Serializable
 		// get absolute / relative part of url
 		String relativeUrl;
 
-		// absolute urls contain a scheme://
 		final int idxOfFirstSlash = absoluteUrl.indexOf('/');
 		final int protocolAt = absoluteUrl.indexOf("://");
 
-		if (protocolAt > -1 && (protocolAt < idxOfFirstSlash))
+		// full urls start either with a "scheme://" or with "//"
+		boolean protocolLess = absoluteUrl.startsWith("//");
+		final boolean isFull = (protocolAt > 1 && (protocolAt < idxOfFirstSlash)) || protocolLess;
+
+		if (isFull)
 		{
-			result.protocol = absoluteUrl.substring(0, protocolAt).toLowerCase(Locale.US);
+			if (protocolLess == false)
+			{
+				result.protocol = absoluteUrl.substring(0, protocolAt).toLowerCase(Locale.US);
+			}
 
 			final String afterProto = absoluteUrl.substring(protocolAt + 3);
 			final String hostAndPort;
@@ -642,15 +657,15 @@ public class Url implements Serializable
 					StringMode.FULL.name() + " mode because it does not have a host set.");
 			}
 
-			String protocol = this.protocol;
-			if (Strings.isEmpty(protocol))
+			if (Strings.isEmpty(protocol) == false)
 			{
-				protocol = "http";
+				result.append(protocol);
+				result.append("://");
+			}
+			else if (Strings.isEmpty(protocol) && Strings.isEmpty(host) == false)
+			{
+				result.append("//");
 			}
-
-			// output scheme://host:port if specified
-			result.append(protocol);
-			result.append("://");
 			result.append(host);
 
 			if (port != null && port.equals(getDefaultPortForProtocol(protocol)) == false)

http://git-wip-us.apache.org/repos/asf/wicket/blob/b1e68de9/wicket-request/src/test/java/org/apache/wicket/request/UrlTest.java
----------------------------------------------------------------------
diff --git a/wicket-request/src/test/java/org/apache/wicket/request/UrlTest.java b/wicket-request/src/test/java/org/apache/wicket/request/UrlTest.java
index 74af6f7..91a4914 100644
--- a/wicket-request/src/test/java/org/apache/wicket/request/UrlTest.java
+++ b/wicket-request/src/test/java/org/apache/wicket/request/UrlTest.java
@@ -86,7 +86,10 @@ public class UrlTest extends Assert
 	{
 		String s = "//foo/bar/";
 		Url url = Url.parse(s);
-		checkSegments(url, "", "", "foo", "bar", "");
+		assertNull(url.getProtocol());
+		assertEquals("foo", url.getHost());
+		assertNull(url.getPort());
+		checkSegments(url, "", "bar", "");
 		checkQueryParams(url);
 	}
 
@@ -98,6 +101,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/foo/bar//";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "foo", "bar", "", "");
 		checkQueryParams(url);
 	}
@@ -146,6 +150,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url);
 	}
@@ -158,6 +163,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?a=b";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "a", "b");
 	}
@@ -170,6 +176,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?a";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "a", "");
 	}
@@ -182,6 +189,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?a=";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "a", "");
 	}
@@ -194,6 +202,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?=b";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "", "b");
 	}
@@ -206,6 +215,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?a=b&";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "a", "b");
 	}
@@ -218,6 +228,7 @@ public class UrlTest extends Assert
 	{
 		String s = "/?a=b&+";
 		Url url = Url.parse(s);
+		assertTrue(url.isAbsolute());
 		checkSegments(url, "", "");
 		checkQueryParams(url, "a", "b", " ", "");
 	}
@@ -235,6 +246,21 @@ public class UrlTest extends Assert
 	}
 
 	/**
+	 * Make it possible to use full url without protocol
+	 * https://issues.apache.org/jira/browse/WICKET-5065
+	 */
+	@Test
+	public void parse16()
+	{
+		String s = "//localhost:56704;jsessionid=8kxeo3reannw1qjtxgkju8yiu";
+		Url url = Url.parse(s);
+		assertNull(url.getProtocol());
+		assertEquals("localhost", url.getHost());
+		assertEquals(Integer.valueOf(56704), url.getPort());
+		checkSegments(url, ";jsessionid=8kxeo3reannw1qjtxgkju8yiu");
+	}
+
+	/**
 	 * 
 	 */
 	@Test
@@ -270,7 +296,7 @@ public class UrlTest extends Assert
 	{
 		String s = "//absolute/url";
 		Url url = Url.parse(s);
-		assertEquals(url.toString(), s);
+		assertEquals(url.toString(StringMode.FULL), s);
 	}
 
 	/**