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
This commit is contained in:
parent
fa4ba2a82b
commit
24d77f3272
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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 {
|
|||
|
||||
@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());
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 {
|
|||
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 {
|
|||
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…
Reference in New Issue