Browse Source

Prepend leading slash in ResourceUrlProvider

The getForRequestUrl method of ResourceUrlProvider uses the
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE attribute to
determine the relevant portion of the resource URL path.

However there are cases when that attribute may not have a leading
(e.g. when the current URL was matched to a prefix-based pattern
and hence extracted via PathMatcher#extractPathWithinPattern), which
interferes with the matching of resource URL paths to patterns.

This change ensures a leading slash is present

Issue: SPR-12281
pull/661/merge
Rossen Stoyanchev 11 years ago
parent
commit
24d77f3272
  1. 3
      spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java
  2. 20
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java
  3. 2
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java
  4. 15
      spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java

3
spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java

@ -179,6 +179,9 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed @@ -179,6 +179,9 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
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);

20
spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

@ -69,7 +69,7 @@ public class ResourceHttpRequestHandlerTests { @@ -69,7 +69,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResource() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/foo.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/css", this.response.getContentType());
@ -83,7 +83,7 @@ public class ResourceHttpRequestHandlerTests { @@ -83,7 +83,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResourceWithHtmlMediaType() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/foo.html");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.html");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/html", this.response.getContentType());
@ -95,7 +95,7 @@ public class ResourceHttpRequestHandlerTests { @@ -95,7 +95,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResourceFromAlternatePath() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/baz.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "baz.css");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/css", this.response.getContentType());
@ -109,7 +109,7 @@ public class ResourceHttpRequestHandlerTests { @@ -109,7 +109,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResourceFromSubDirectory() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/js/foo.js");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "js/foo.js");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/javascript", this.response.getContentType());
@ -118,7 +118,7 @@ public class ResourceHttpRequestHandlerTests { @@ -118,7 +118,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResourceFromSubDirectoryOfAlternatePath() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/js/baz.js");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "js/baz.js");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/javascript", this.response.getContentType());
@ -147,7 +147,7 @@ public class ResourceHttpRequestHandlerTests { @@ -147,7 +147,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void notModified() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/foo.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.addHeader("If-Modified-Since", resourceLastModified("test/foo.css"));
this.handler.handleRequest(this.request, this.response);
assertEquals(HttpServletResponse.SC_NOT_MODIFIED, this.response.getStatus());
@ -155,7 +155,7 @@ public class ResourceHttpRequestHandlerTests { @@ -155,7 +155,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void modified() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/foo.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.addHeader("If-Modified-Since", resourceLastModified("test/foo.css") / 1000 * 1000 - 1);
this.handler.handleRequest(this.request, this.response);
assertEquals(HttpServletResponse.SC_OK, this.response.getStatus());
@ -164,7 +164,7 @@ public class ResourceHttpRequestHandlerTests { @@ -164,7 +164,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void directory() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/js/");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "js/");
this.handler.handleRequest(this.request, this.response);
assertEquals(404, this.response.getStatus());
}
@ -183,14 +183,14 @@ public class ResourceHttpRequestHandlerTests { @@ -183,14 +183,14 @@ public class ResourceHttpRequestHandlerTests {
@Test(expected=HttpRequestMethodNotSupportedException.class)
public void unsupportedHttpMethod() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/foo.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.setMethod("POST");
this.handler.handleRequest(this.request, this.response);
}
@Test
public void resourceNotFound() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/not-there.css");
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "not-there.css");
this.handler.handleRequest(this.request, this.response);
assertEquals(404, this.response.getStatus());
}

2
spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceTransformerSupportTests.java

@ -72,7 +72,7 @@ public class ResourceTransformerSupportTests { @@ -72,7 +72,7 @@ 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.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "resources/main.css");
String resourcePath = "/context/servlet/resources/bar.css";
Resource css = new ClassPathResource("test/main.css", getClass());

15
spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderJavaConfigTests.java

@ -28,6 +28,7 @@ import org.springframework.mock.web.test.MockHttpServletRequest; @@ -28,6 +28,7 @@ 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.*;
@ -68,7 +69,6 @@ public class ResourceUrlProviderJavaConfigTests { @@ -68,7 +69,6 @@ public class ResourceUrlProviderJavaConfigTests {
this.request.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, urlProvider);
}
@Test
public void resolvePathWithRootServletMapping() throws Exception {
this.request.setRequestURI("/myapp/index");
@ -99,6 +99,19 @@ public class ResourceUrlProviderJavaConfigTests { @@ -99,6 +99,19 @@ public class ResourceUrlProviderJavaConfigTests {
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);
}

Loading…
Cancel
Save