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: + *

+ */ + 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");