Skip to content

Duplicate cache headers in spring boot 1.5.1 #8188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
apixandru opened this issue Feb 3, 2017 · 10 comments
Closed

Duplicate cache headers in spring boot 1.5.1 #8188

apixandru opened this issue Feb 3, 2017 · 10 comments
Labels
status: feedback-provided Feedback has been provided

Comments

@apixandru
Copy link

apixandru commented Feb 3, 2017

There's this bug in IE that the fonts from fonts awesome don't work very well with https. It has some problems with caching or something. (see FortAwesome/Font-Awesome#6454 )

To get around this, we set up a filter registration bean.

@Bean
public FilterRegistrationBean fixIeHttpsFontCache() {
	FilterRegistrationBean registration = new FilterRegistrationBean();
	registration.setFilter(new InternetExplorerHttpsFontFilter);
	registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
        registration.setUrlPatterns(/*urls for fonts */);
	return registration;
}

The Internet Explorer Https Font filter would just set the http request headers to

Expires -1
Cache-control public
Pragma cache

This worked fine until 1.4.4, but on 1.5.1 it no longer works. I'm guessing that the way to set headers has changed lately or that the filters should be registered differently?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 3, 2017
@wilkinsona
Copy link
Member

I'm guessing that the way to set headers has changed lately or that the filters should be registered differently?

Neither of those things has changed as far as I know.

Have you dug into why it no longer works? I'm guessing that the headers aren't getting set as you intend. It should be possible to verify that without involving IE, for example by using curl. Can you provide a small sample that illustrates the problem?

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label Feb 3, 2017
@apixandru
Copy link
Author

Just by looking at the request, it appears that the default content type has changed from spring 1.4.4 for eot type fonts from application/octet-stream to application/vnd.ms-fontobject

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 3, 2017
@wilkinsona
Copy link
Member

wilkinsona commented Feb 3, 2017

As far as I can tell, there's no content type in 1.4.4:

curl --head -i http://localhost:8080/fontawesome-webfont.eot
HTTP/1.1 200
Last-Modified: Fri, 03 Feb 2017 13:54:12 GMT
Accept-Ranges: bytes
Content-Length: 165742
Date: Fri, 03 Feb 2017 13:54:18 GMT

With 1.5 it's application/vnd.ms-fontobject as you have observed:

curl --head -i http://localhost:8080/fontawesome-webfont.eot
HTTP/1.1 200
Last-Modified: Fri, 03 Feb 2017 13:55:17 GMT
Accept-Ranges: bytes
Content-Type: application/vnd.ms-fontobject
Content-Length: 165742
Date: Fri, 03 Feb 2017 13:57:05 GMT

That change is a result of this commit. We added some more mappings when upgrading to a new version of Undertow as we make sure that the mappings are consistent across all three supported embedded containers (Tomcat, Undertow, and Jetty).

If that change is what's causing your problem (you haven't confirmed that yet) then I don't think there's anything we can do about it and you'll have to find an alternative workaround.

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Feb 3, 2017
@apixandru
Copy link
Author

apixandru commented Feb 3, 2017

It looks like this is loosely linked to #8176

I took a quick look on the deployment server and it looks like my cache headers are in fact being 'overridden'.

Spring boot 1.5.1


Response            HTTP/1.1 200 OK
Date      Fri, 03 Feb 2017 15:02:48 GMT
[…]
Cache-Control   public
Cache-Control   no-cache, no-store, max-age=0, must-revalidate
Pragma cache
Pragma no-cache
Accept-Ranges  bytes
Expires 0
Last-Modified    Fri, 03 Feb 2017 15:00:47 GMT
[…]

Spring boot 1.4.4


Response            HTTP/1.1 200 OK
Date      Fri, 03 Feb 2017 15:18:53 GMT
[…]
Cache-Control   public
Pragma cache
Accept-Ranges  bytes
Expires -1
Last-Modified    Fri, 03 Feb 2017 15:15:26 GMT
[…]

It looks like before it wasn't adding the Pragma / Cache-Control / Expires headers if they were already defined but now they are added regardless.

Locally this it works fine for me but I don't have a https connection locally and this bug is only available with https.

Also, I forgot to mention that this is when deploying to weblogic, I'm not sure if it's relevant or not.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 3, 2017
@wilkinsona
Copy link
Member

This issue's all over the place at the moment. So it looks like you're now saying that the Content-Type header has nothing to do with the problem?

You haven't said how you've configured the static resource handling and where you've configured the caching. As you can see in the curl output I shared above you won't get any caching headers by default so you must have configured something that's setting them in addition to your custom filter.

Can you please share some code that reproduces the problem?

@wilkinsona wilkinsona added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Feb 3, 2017
@apixandru
Copy link
Author

Yes, the Content-Type header had nothing to do with it.

The only place where i am configuring cache is the internet explorer filter that I previously mentioned.
Other than that this application is a very simple. All the files are in src/main/resources/static. It is packaged in a war for deployment to weblogic.

There is really nothing to show on the spring boot configuration. The filter registration bean that i previously mentioned is the only thing that configures anything, everything else is simple controllers / authentication.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 3, 2017
@apixandru
Copy link
Author

I'm trying to AOP the httpservletresponse to see if i can figure out where the headers come from but i'm not having any luck doing that.

@snicoll snicoll added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Feb 3, 2017
@apixandru apixandru changed the title Font awesome + IE + https no longer works in spring 1.5.1 Dupplicate headers in spring boot 1.5.1 Feb 3, 2017
@apixandru
Copy link
Author

apixandru commented Feb 3, 2017

Found it, it's in CacheControlHeadersWriter

Before, the writeHeader method used to write

public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
	if (hasHeader(response, CACHE_CONTROL) || hasHeader(response, EXPIRES)
			|| hasHeader(response, PRAGMA)) {
		return;
	}
	this.delegate.writeHeaders(request, response);
}

Now, it's simply

public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
	for (Header header : headers) {
		for (String value : header.getValues()) {
			response.addHeader(header.getName(), value);
		}
	}
}

This is the commit spring-projects/spring-security@57d7ad0

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Feb 3, 2017
@apixandru
Copy link
Author

sample project here
https://github.com/apixandru/case-study/tree/master/spring-boot-duplicate-headers

it turns out that WebSecurityConfigurerAdapter enables the cache control headers that you were missing

happens with a weblogic deployment


$ curl --head -i http://192.168.0.248:7001/test/b.txt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 200 OK
Cache-Control: public
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Date: Fri, 03 Feb 2017 20:20:36 GMT
Pragma: cache
Pragma: no-cache
Transfer-Encoding: chunked
Accept-Ranges: bytes
Content-Type: text/plain
Expires: 0
Last-Modified: Fri, 03 Feb 2017 20:20:11 GMT
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff

@apixandru apixandru changed the title Dupplicate headers in spring boot 1.5.1 Duplicate cache headers in spring boot 1.5.1 Feb 3, 2017
@wilkinsona
Copy link
Member

Thanks for tracking it down. As you've noted CacheControlHeadersWriter is part of Spring Security. Unfortunately that means this issue's in the wrong place and GitHub doesn't support moving issues. Can you please open an issue against Spring Security: https://github.com/spring-projects/spring-security

/cc @rwinch

@snicoll snicoll removed the status: waiting-for-triage An issue we've not yet triaged label Feb 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided
Projects
None yet
Development

No branches or pull requests

4 participants