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 2012/08/27 16:21:28 UTC

git commit: WICKET-4645 encodeURL broken on Tomcat 7.0.28

Updated Branches:
  refs/heads/wicket-1.5.x 744b9bc46 -> 184f2657b


WICKET-4645 encodeURL broken on Tomcat 7.0.28

Always pass absolute urls to HttpServletResponse#encodeUrl(). This way there is no need the web container to resolve it to absolute just to see whether it is part of the current application.


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

Branch: refs/heads/wicket-1.5.x
Commit: 184f2657ba177c8a2492fcb5314b58e29de7e336
Parents: 744b9bc
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
Authored: Mon Aug 27 15:55:23 2012 +0200
Committer: Martin Tzvetanov Grigorov <mg...@apache.org>
Committed: Mon Aug 27 16:21:06 2012 +0200

----------------------------------------------------------------------
 .../protocol/http/servlet/ServletWebResponse.java  |   38 ++++---
 .../request/cycle/RequestCycleUrlForTest.java      |   11 +-
 .../wicket/request/cycle/UrlRendererTest.java      |   24 ++++
 .../main/java/org/apache/wicket/request/Url.java   |    2 +-
 .../org/apache/wicket/request/UrlRenderer.java     |   93 +++++++--------
 5 files changed, 96 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/184f2657/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java b/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
index 2296e34..bda9e57 100644
--- a/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
+++ b/wicket-core/src/main/java/org/apache/wicket/protocol/http/servlet/ServletWebResponse.java
@@ -22,6 +22,9 @@ import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.UrlRenderer;
+import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.wicket.request.http.WebResponse;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.time.Time;
@@ -168,27 +171,30 @@ public class ServletWebResponse extends WebResponse
 	public String encodeURL(CharSequence url)
 	{
 		Args.notNull(url, "url");
-		if (url.length() > 0 && url.charAt(0) == '?')
-		{
-			// there is a bug in apache tomcat 5.5 where tomcat doesn't put sessionid to url
-			// when the URL starts with '?'. So we prepend the URL with ./ and remove it
-			// afterwards (unless some container prepends session id before './' or mangles
-			// the URL otherwise
 
-			String encoded = httpServletResponse.encodeURL("./" + url.toString());
-			if (encoded.startsWith("./"))
-			{
-				return encoded.substring(2);
-			}
-			else
-			{
-				return encoded;
-			}
+		/*
+		  WICKET-4645 - always pass absolute url to the web container for encoding
+		  because when REDIRECT_TO_BUFFER is in use Wicket may render PageB when
+		  PageA is actually the requested one and the web container cannot resolve
+		  the base url properly
+		 */
+		UrlRenderer urlRenderer = RequestCycle.get().getUrlRenderer();
+		Url relativeUrl = Url.parse(url.toString());
+		String fullUrl = urlRenderer.renderFullUrl(relativeUrl);
+		String encodedFullUrl = httpServletResponse.encodeURL(fullUrl);
+		final String encodedRelativeUrl;
+		if (fullUrl.equals(encodedFullUrl))
+		{
+			// no encoding happened so just reuse the relative url
+			encodedRelativeUrl = url.toString();
 		}
 		else
 		{
-			return httpServletResponse.encodeURL(url.toString());
+			// get the relative url with the jsessionid encoded in it
+			Url _encoded = Url.parse(encodedFullUrl);
+			encodedRelativeUrl = urlRenderer.renderRelativeUrl(_encoded);
 		}
+		return encodedRelativeUrl;
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/184f2657/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java b/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
index b779521..b08c358 100644
--- a/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/request/cycle/RequestCycleUrlForTest.java
@@ -81,6 +81,7 @@ public class RequestCycleUrlForTest extends Assert
 		RequestCycleContext context = new RequestCycleContext(request, response, mapper, exceptionMapper);
 
 		requestCycle = new RequestCycle(context);
+		requestCycle.getUrlRenderer().setBaseUrl(Url.parse("http://dummy-host"));
 	}
 
 	/**
@@ -92,7 +93,7 @@ public class RequestCycleUrlForTest extends Assert
 	public void urlForClass() throws Exception
 	{
 		CharSequence url = requestCycle.urlFor(MockHomePage.class, new PageParameters());
-		assertEquals("/bookmarkablePage"+JSESSIONID, url);
+		assertEquals("./bookmarkablePage"+JSESSIONID, url);
 	}
 
 	/**
@@ -114,7 +115,7 @@ public class RequestCycleUrlForTest extends Assert
 		}; 
 		ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference);
 		CharSequence url = requestCycle.urlFor(handler);
-		assertEquals(RES_REF_URL, url);
+		assertEquals('.'+RES_REF_URL, url);
 	}
 
 	/**
@@ -136,7 +137,7 @@ public class RequestCycleUrlForTest extends Assert
 		};
 		ResourceReferenceRequestHandler handler = new ResourceReferenceRequestHandler(reference);
 		CharSequence url = requestCycle.urlFor(handler);
-		assertEquals(RES_REF_URL+JSESSIONID, url);
+		assertEquals('.'+RES_REF_URL+JSESSIONID, url);
 	}
 
 	/**
@@ -150,7 +151,7 @@ public class RequestCycleUrlForTest extends Assert
 		IStaticCacheableResource resource = mock(IStaticCacheableResource.class);
 		ResourceRequestHandler handler = new ResourceRequestHandler(resource, new PageParameters());
 		CharSequence url = requestCycle.urlFor(handler);
-		assertEquals(RESOURCE_URL, url);
+		assertEquals('.'+RESOURCE_URL, url);
 	}
 
 	/**
@@ -164,7 +165,7 @@ public class RequestCycleUrlForTest extends Assert
 		ByteArrayResource resource = new ByteArrayResource(null, new byte[] {1, 2}, "test.bin");
 		ResourceRequestHandler handler = new ResourceRequestHandler(resource, new PageParameters());
 		CharSequence url = requestCycle.urlFor(handler);
-		assertEquals(RESOURCE_URL + JSESSIONID, url);
+		assertEquals('.'+RESOURCE_URL + JSESSIONID, url);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/wicket/blob/184f2657/wicket-core/src/test/java/org/apache/wicket/request/cycle/UrlRendererTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/request/cycle/UrlRendererTest.java b/wicket-core/src/test/java/org/apache/wicket/request/cycle/UrlRendererTest.java
index ca9e167..81a0799 100644
--- a/wicket-core/src/test/java/org/apache/wicket/request/cycle/UrlRendererTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/request/cycle/UrlRendererTest.java
@@ -249,4 +249,28 @@ public class UrlRendererTest extends Assert
 		fullUrl = renderer.renderUrl(newUrl);
 		assertEquals("http://www.example.com:8888/four", fullUrl);
 	}
+
+	@Test
+	public void renderFullUrlAsRelativeToAnotherBaseUrl()
+	{
+		Url baseUrl = Url.parse("http://host:8080/contextPath/filterPath/a/b/c/d");
+		Url encodedFullUrl = Url.parse("http://host:8080/contextPath/filterPath/a/b;jsessionid=123456");
+
+		UrlRenderer renderer = new UrlRenderer(new MockWebRequest(baseUrl));
+		String encodedRelativeUrl = renderer.renderRelativeUrl(encodedFullUrl);
+
+		assertEquals("../../b;jsessionid=123456", encodedRelativeUrl);
+	}
+
+	@Test
+	public void renderFullUrlAsRelativeToAnotherBaseUrl_2()
+	{
+		Url baseUrl = Url.parse("/contextPath/filterPath/a/b/c/d");
+		Url encodedFullUrl = Url.parse("http://host:8080/contextPath/filterPath/a/b;jsessionid=123456");
+
+		UrlRenderer renderer = new UrlRenderer(new MockWebRequest(baseUrl));
+		String encodedRelativeUrl = renderer.renderRelativeUrl(encodedFullUrl);
+
+		assertEquals("../../b;jsessionid=123456", encodedRelativeUrl);
+	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/184f2657/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 8f9c149..8d190ae 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
@@ -709,7 +709,7 @@ public class Url implements Serializable
 
 			if (!path.startsWith("/"))
 			{
-				result.append("/");
+				result.append('/');
 			}
 
 		}

http://git-wip-us.apache.org/repos/asf/wicket/blob/184f2657/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.java
----------------------------------------------------------------------
diff --git a/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.java b/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.java
index 5acbedd..dde0659 100644
--- a/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.java
+++ b/wicket-request/src/main/java/org/apache/wicket/request/UrlRenderer.java
@@ -196,7 +196,7 @@ public class UrlRenderer
 	 * This method is only intended for Wicket URLs, because the {@link Url} object represents part
 	 * of URL after Wicket Filter.
 	 * 
-	 * For general URLs within context use {@link #renderContextPathRelativeUrl(String)}
+	 * For general URLs within context use {@link #renderContextRelativeUrl(String)}
 	 * 
 	 * @param url
 	 * @return Url rendered as string
@@ -205,68 +205,61 @@ public class UrlRenderer
 	{
 		Args.notNull(url, "url");
 
-		if (url.isAbsolute())
-		{
-			return url.toString();
-		}
-		else
-		{
-			List<String> baseUrlSegments = getBaseUrl().getSegments();
-			List<String> urlSegments = new ArrayList<String>(url.getSegments());
-
-			List<String> newSegments = new ArrayList<String>();
-
-			int common = 0;
+		List<String> baseUrlSegments = getBaseUrl().getSegments();
+		List<String> urlSegments = new ArrayList<String>(url.getSegments());
 
-			String last = null;
+		List<String> newSegments = new ArrayList<String>();
 
-			for (String s : baseUrlSegments)
-			{
-				if (!urlSegments.isEmpty() && s.equals(urlSegments.get(0)))
-				{
-					++common;
-					last = urlSegments.remove(0);
-				}
-				else
-				{
-					break;
-				}
-			}
+		int common = 0;
 
-			// we want the new URL to have at least one segment (other than possible ../)
-			if ((last != null) && (urlSegments.isEmpty() || (baseUrlSegments.size() == common)))
-			{
-				--common;
-				urlSegments.add(0, last);
-			}
+		String last = null;
 
-			int baseUrlSize = baseUrlSegments.size();
-			if (common + 1 == baseUrlSize && urlSegments.isEmpty())
+		for (String s : baseUrlSegments)
+		{
+			if (!urlSegments.isEmpty() && s.equals(urlSegments.get(0)))
 			{
-				newSegments.add(".");
+				++common;
+				last = urlSegments.remove(0);
 			}
 			else
 			{
-				for (int i = common + 1; i < baseUrlSize; ++i)
-				{
-					newSegments.add("..");
-				}
+				break;
 			}
-			newSegments.addAll(urlSegments);
+		}
 
-			String renderedUrl = new Url(newSegments, url.getQueryParameters()).toString();
-			if (!renderedUrl.startsWith(".."))
-			{
-				// WICKET-4260
-				renderedUrl = "./" + renderedUrl;
-			}
-			if (renderedUrl.endsWith(".."))
+		// we want the new URL to have at least one segment (other than possible ../)
+		if ((last != null) && (urlSegments.isEmpty() || (baseUrlSegments.size() == common)))
+		{
+			--common;
+			urlSegments.add(0, last);
+		}
+
+		int baseUrlSize = baseUrlSegments.size();
+		if (common + 1 == baseUrlSize && urlSegments.isEmpty())
+		{
+			newSegments.add(".");
+		}
+		else
+		{
+			for (int i = common + 1; i < baseUrlSize; ++i)
 			{
-				// WICKET-4401
-				renderedUrl = renderedUrl + '/';
+				newSegments.add("..");
 			}
-			return renderedUrl;
 		}
+		newSegments.addAll(urlSegments);
+
+		String renderedUrl = new Url(newSegments, url.getQueryParameters()).toString();
+		if (!renderedUrl.startsWith(".."))
+		{
+			// WICKET-4260
+			renderedUrl = "./" + renderedUrl;
+		}
+		if (renderedUrl.endsWith(".."))
+		{
+			// WICKET-4401
+			renderedUrl = renderedUrl + '/';
+		}
+		return renderedUrl;
 	}
 
 	/**