提交 24d77f32 编写于 作者: R Rossen Stoyanchev

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
上级 fa4ba2a8
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册