diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java index 9a05345099c..22251e5d3e1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java @@ -74,10 +74,12 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter { initIndexLookupPath(resourceUrlProvider); if (url.length() >= this.indexLookupPath) { String prefix = url.substring(0, this.indexLookupPath); - String lookupPath = url.substring(this.indexLookupPath); + int suffixIndex = getQueryParamsIndex(url); + String suffix = url.substring(suffixIndex); + String lookupPath = url.substring(this.indexLookupPath, suffixIndex); lookupPath = resourceUrlProvider.getForLookupPath(lookupPath); if (lookupPath != null) { - return super.encodeURL(prefix + lookupPath); + return super.encodeURL(prefix + lookupPath + suffix); } } return super.encodeURL(url); @@ -95,6 +97,11 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter { this.indexLookupPath = requestUri.lastIndexOf(lookupPath); } } + + private int getQueryParamsIndex(String url) { + int index = url.indexOf("?"); + return index > 0 ? index : url.length(); + } } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java index 416a04e689a..194ed961664 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java @@ -172,11 +172,13 @@ public class ResourceUrlProvider implements ApplicationListener 0 ? index : lookupPath.length(); + } + /** * Compare the given path against configured resource handler mappings and * if a match is found use the {@code ResourceResolver} chain of the matched diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java index e94a2a615ff..bcd6bfc33de 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -106,6 +106,23 @@ public class ResourceUrlEncodingFilterTests { }); } + // SPR-13374 + @Test + public void encodeURLWithRequestParams() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); + request.setContextPath("/"); + request.setAttribute(ResourceUrlProviderExposingInterceptor.RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider); + MockHttpServletResponse response = new MockHttpServletResponse(); + + this.filter.doFilterInternal(request, response, new FilterChain() { + @Override + public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { + String result = ((HttpServletResponse)response).encodeURL("/resources/bar.css?foo=bar&url=http://example.org"); + assertEquals("/resources/bar-11e16cf79faee7ac698c805cf28248d2.css?foo=bar&url=http://example.org", result); + } + }); + } + protected ResourceUrlProvider createResourceUrlProvider(List resolvers) { ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setLocations(Arrays.asList(new ClassPathResource("test/", getClass()))); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java index 98966a01f02..bd0a6ac911f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceUrlProviderTests.java @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; +import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockServletContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; @@ -74,6 +75,18 @@ public class ResourceUrlProviderTests { assertEquals("/resources/foo.css", url); } + // SPR-13374 + @Test + public void getStaticResourceUrlRequestWithRequestParams() { + initTranslator(); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setContextPath("/"); + request.setRequestURI("/"); + + String url = this.translator.getForRequestUrl(request, "/resources/foo.css?foo=bar&url=http://example.org"); + assertEquals("/resources/foo.css?foo=bar&url=http://example.org", url); + } + @Test public void getFingerprintedResourceUrl() { Map versionStrategyMap = new HashMap<>();