Zsolt Fatér opened SPR-15892 and commented

Pull request url: https://github.com/spring-projects/spring-framework/pull/1503

Prefix based version path strategy has a problem with css.

If css include any relative url, the server can not resolve relative url, because it has two version prefix in the url.

Example

The version: 1.0.0

The css url: http://localhost/application/1.0.0/css/test.css

Original css content

body {
    background-image: url("img/picture.jpg");
    background-size: cover;
}

Modified css content

body {
    background-image: url("1.0.0/img/picture.jpg");
    background-size: cover;
}

The picture.jpg url will be: http://localhost/application/1.0.0/css/1.0.0/img/picture.jpg but the expected is http://locahost/application/1.0.0/css/img/picture.jpg

Solution

We was make the UrlParameterFixedVersrionStrategy class.

The css url: http://localhost/application/css/test.css?v=1.0.0

Modified css content

body {
    background-image: url("img/picture.jpg?v=1.0.0");
    background-size: cover;
}

the picture.jpg url: http://localhost/application/css/img/picture.jpg?v=1.0.0

MvcConfig example

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.resource.AbstractVersionStrategy;
import org.springframework.web.servlet.resource.UrlParameterFixedVersionStrategy;
import org.springframework.web.servlet.resource.VersionResourceResolver;

@Configuration
@ComponentScan({"test.controller"})
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        AbstractVersionStrategy fixedVersionStrategy = new UrlParameterFixedVersionStrategy("1.0.0");
        VersionResourceResolver versionResourceResolver = new VersionResourceResolver()
                .addVersionStrategy(fixedVersionStrategy, "/**");

        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/other-resources/")
                .resourceChain(true)
                .addResolver(versionResourceResolver);
    }

}

Reference URL: https://github.com/spring-projects/spring-framework/pull/1503

Comment From: spring-projects-issues

Brian Clozel commented

Hi Zsolt Fatér!

The issue you're describing seems to be solved with #19166. I'm also a bit hesitant about the PR for two reasons:

  • Many (outdated?) resources still point that using the query string for that is not the best idea; I understand that most proxies now support that, but it seems CDNs don't always enable that by default (i.e. they don't consider by default the query string for caching purposes)
  • Looking at the code parsing/updating the query string, it seems to be too much involved and could be a source of security issues. When it comes to serving static resources, there are many pitfalls coming with the processing of the request URL (see this CVE, for example).

We've considered backporting #19166 to the 4.x branch, but it was already a big change of behaviour back then - it's even worse now with 4.x being very stable and in maintenance mode.

Thanks for creating this issue (and your contribution)!

Comment From: bclozel

Closing this as #19166 solves the use case described here. We didn't get much demand for this nor new use cases.