Avoid HandlerMapping attribute in ResourceUrlProvider

The use of the HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE
in ResourceUrlProvider (as a way of saving lookup path determination)
leads to incorrect results. For example when the request is forwarded
the current requestUri may no longer be compariable to the value of the
PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE. Also where the request is mapped
using a pattern, the value of PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE is
not the same as the lookup path.

This change removes the use of the attribute from ResourceUrlProvider
and instead always determines the lookup path when getForRequestUrl
is called.

Issue: SPR-12332
This commit is contained in:
Rossen Stoyanchev 2014-10-16 17:20:35 -04:00
parent 115f85e44f
commit 97441d054d
3 changed files with 12 additions and 44 deletions

View File

@ -172,24 +172,17 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
if (logger.isTraceEnabled()) {
logger.trace("Getting resource URL for requestURL=" + requestUrl);
}
String pathWithinMapping = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
if (pathWithinMapping == null) {
logger.trace("Request attribute with lookup path not found, calculating instead.");
pathWithinMapping = getPathHelper().getLookupPathForRequest(request);
}
// When extracted with PathMatcher, pathWithinMapping won't have leading slash
pathWithinMapping = (pathWithinMapping.charAt(0) == '/' ? pathWithinMapping : "/" + pathWithinMapping);
int index = getPathHelper().getRequestUri(request).indexOf(pathWithinMapping);
Assert.state(index != -1, "Failed to determine lookup path: " + requestUrl);
int index = getLookupPathIndex(request);
String prefix = requestUrl.substring(0, index);
String lookupPath = requestUrl.substring(index);
String resolvedPath = getForLookupPath(lookupPath);
String resolvedLookupPath = getForLookupPath(lookupPath);
return (resolvedLookupPath != null) ? prefix + resolvedLookupPath : null;
}
return (resolvedPath != null) ? prefix + resolvedPath : null;
private int getLookupPathIndex(HttpServletRequest request) {
String requestUri = getPathHelper().getRequestUri(request);
String lookupPath = getPathHelper().getLookupPathForRequest(request);
return requestUri.indexOf(lookupPath);
}
/**

View File

@ -72,8 +72,8 @@ public class ResourceTransformerSupportTests {
@Test
public void resolveUrlPath() throws Exception {
this.request.setRequestURI("/context/servlet/resources/main.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "resources/main.css");
this.request.setContextPath("/context");
this.request.setServletPath("/servlet");
String resourcePath = "/context/servlet/resources/bar.css";
Resource css = new ClassPathResource("test/main.css", getClass());
String actual = this.transformer.resolveUrlPath(resourcePath, this.request, css, this.transformerChain);
@ -85,7 +85,6 @@ public class ResourceTransformerSupportTests {
this.request.setRequestURI("/context/servlet/resources/main.css");
this.request.setContextPath("/context");
this.request.setServletPath("/servlet");
String resourcePath = "/context/servlet/resources/bar.css";
Resource css = new ClassPathResource("test/main.css", getClass());
String actual = this.transformer.resolveUrlPath(resourcePath, this.request, css, this.transformerChain);

View File

@ -28,7 +28,6 @@ import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.config.annotation.*;
import static org.junit.Assert.*;
@ -70,7 +69,7 @@ public class ResourceUrlProviderJavaConfigTests {
}
@Test
public void resolvePathWithRootServletMapping() throws Exception {
public void resolvePathWithServletMappedAsRoot() throws Exception {
this.request.setRequestURI("/myapp/index");
this.request.setServletPath("/index");
this.filterChain.doFilter(this.request, this.response);
@ -80,7 +79,7 @@ public class ResourceUrlProviderJavaConfigTests {
}
@Test
public void resolvePathWithPrefixServletMapping() throws Exception {
public void resolvePathWithServletMappingByPrefix() throws Exception {
this.request.setRequestURI("/myapp/myservlet/index");
this.request.setServletPath("/myservlet");
this.filterChain.doFilter(this.request, this.response);
@ -89,29 +88,6 @@ public class ResourceUrlProviderJavaConfigTests {
resolvePublicResourceUrlPath("/myapp/myservlet/resources/foo.css"));
}
@Test
public void resolvePathWithExtensionServletMapping() throws Exception {
this.request.setRequestURI("/myapp/index.html");
this.request.setServletPath("/index.html");
this.filterChain.doFilter(this.request, this.response);
assertEquals("/myapp/resources/foo-e36d2e05253c6c7085a91522ce43a0b4.css",
resolvePublicResourceUrlPath("/myapp/resources/foo.css"));
}
// SPR-12281
@Test
public void resolvePathWithHandlerMappingAttribute() throws Exception {
this.request.setRequestURI("/myapp/index");
this.request.setServletPath("/index");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "index");
this.filterChain.doFilter(this.request, this.response);
assertEquals("/myapp/resources/foo-e36d2e05253c6c7085a91522ce43a0b4.css",
resolvePublicResourceUrlPath("/myapp/resources/foo.css"));
}
private String resolvePublicResourceUrlPath(String path) {
return this.servlet.wrappedResponse.encodeURL(path);
}