diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
index a9e6adb5ad6..245c9981f13 100644
--- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
+++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java
@@ -165,6 +165,8 @@ public class UrlPathHelper {
* i.e. the part of the request's URL beyond the part that called the servlet,
* or "" if the whole URL has been used to identify the servlet.
*
Detects include request URL if called within a RequestDispatcher include.
+ *
E.g.: servlet mapping = "/*"; request URI = "/test/a" -> "/test/a".
+ *
E.g.: servlet mapping = "/"; request URI = "/test/a" -> "/test/a".
*
E.g.: servlet mapping = "/test/*"; request URI = "/test/a" -> "/a".
*
E.g.: servlet mapping = "/test"; request URI = "/test" -> "".
*
E.g.: servlet mapping = "/*.test"; request URI = "/a.test" -> "".
@@ -174,7 +176,17 @@ public class UrlPathHelper {
public String getPathWithinServletMapping(HttpServletRequest request) {
String pathWithinApp = getPathWithinApplication(request);
String servletPath = getServletPath(request);
- String path = getRemainingPath(pathWithinApp, servletPath, false);
+ String sanitizedPathWithinApp = getSanitizedPath(pathWithinApp);
+ String path;
+
+ // if the app container sanitized the servletPath, check against the sanitized version
+ if(servletPath.indexOf(sanitizedPathWithinApp) != -1) {
+ path = getRemainingPath(sanitizedPathWithinApp, servletPath, false);
+ }
+ else {
+ path = getRemainingPath(pathWithinApp, servletPath, false);
+ }
+
if (path != null) {
// Normal case: URI contains servlet path.
return path;
@@ -243,7 +255,7 @@ public class UrlPathHelper {
if (c1 == c2) {
continue;
}
- if (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2))) {
+ else if (ignoreCase && (Character.toLowerCase(c1) == Character.toLowerCase(c2))) {
continue;
}
return null;
@@ -251,7 +263,7 @@ public class UrlPathHelper {
if (index2 != mapping.length()) {
return null;
}
- if (index1 == requestUri.length()) {
+ else if (index1 == requestUri.length()) {
return "";
}
else if (requestUri.charAt(index1) == ';') {
@@ -260,6 +272,26 @@ public class UrlPathHelper {
return (index1 != -1 ? requestUri.substring(index1) : "");
}
+ /**
+ * Sanitize the given path with the following rules:
+ *
+ * - replace all "//" by "/"
+ *
+ */
+ private String getSanitizedPath(final String path) {
+ String sanitized = path;
+ while (true) {
+ int index = sanitized.indexOf("//");
+ if (index < 0) {
+ break;
+ }
+ else {
+ sanitized = sanitized.substring(0, index) + sanitized.substring(index + 1);
+ }
+ }
+ return sanitized;
+ }
+
/**
* Return the request URI for the given request, detecting an include request
* URL if called within a RequestDispatcher include.
diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
index 7ef440766ad..a18b154a196 100644
--- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,6 +78,16 @@ public class UrlPathHelperTests {
assertEquals("Incorrect path returned", "/welcome.html", helper.getPathWithinServletMapping(request));
}
+ @Test
+ public void alwaysUseFullPath() {
+ helper.setAlwaysUseFullPath(true);
+ request.setContextPath("/petclinic");
+ request.setServletPath("/main");
+ request.setRequestURI("/petclinic/main/welcome.html");
+
+ assertEquals("Incorrect path returned", "/main/welcome.html", helper.getLookupPathForRequest(request));
+ }
+
// SPR-11101
@Test
@@ -194,6 +204,28 @@ public class UrlPathHelperTests {
assertEquals("/foo/", helper.getLookupPathForRequest(request));
}
+ //SPR-12372
+ @Test
+ public void defaultServletEndingWithDoubleSlash() throws Exception {
+ request.setContextPath("/SPR-12372");
+ request.setPathInfo(null);
+ request.setServletPath("/foo/bar/");
+ request.setRequestURI("/SPR-12372/foo//bar/");
+
+ assertEquals("/foo//bar/", helper.getLookupPathForRequest(request));
+
+ request.setServletPath("/foo/bar/");
+ request.setRequestURI("/SPR-12372/foo/bar//");
+
+ assertEquals("/foo/bar//", helper.getLookupPathForRequest(request));
+
+ // "normal" case
+ request.setServletPath("/foo/bar//");
+ request.setRequestURI("/SPR-12372/foo/bar//");
+
+ assertEquals("/foo/bar//", helper.getLookupPathForRequest(request));
+ }
+
@Test
public void wasDefaultServletRoot() throws Exception {
request.setContextPath("/test");
@@ -366,6 +398,26 @@ public class UrlPathHelperTests {
tomcatCasualServletFolder();
}
+ @Test
+ public void getOriginatingRequestUri() {
+ request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path");
+ request.setRequestURI("/forwarded");
+ assertEquals("/path", helper.getOriginatingRequestUri(request));
+ }
+
+ @Test
+ public void getOriginatingRequestUriWebsphere() {
+ request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/path");
+ request.setRequestURI("/forwarded");
+ assertEquals("/path", helper.getOriginatingRequestUri(request));
+ }
+
+ @Test
+ public void getOriginatingRequestUriDefault() {
+ request.setRequestURI("/forwarded");
+ assertEquals("/forwarded", helper.getOriginatingRequestUri(request));
+ }
+
@Test
public void getOriginatingQueryString() {
request.setQueryString("forward=on");