yglodt
yglodt

Reputation: 14551

Http headers to cache files forever until modified

I serve files from the filesystem via a Spring @Controller, and I want to make the best possible use of the browser cache.

Here is the method handling the request:

@ResponseBody
@GetMapping(value = "/file/{f:.*}")
public FileSystemResource getFile(@PathVariable("f") String fileName, HttpServletResponse response) {

    File file = new File("/folder/" + fileName);

    response.setHeader("Cache-Control", CacheControl.maxAge(7, TimeUnit.DAYS).cachePrivate().getHeaderValue());
    response.setDateHeader("Last-Modified", file.lastModified());
    response.setHeader("ETag", "" + file.lastModified());

    return new FileSystemResource(file);
}

The browser should cache the files forever, except if they were modified on the filesystem since the last request.

I am not sure how to set Cache-Control and Expires.

How to set them, and which headers would I need to add to get the desired behaviour?

Note that I also use Spring Security which adds the following headers by default:

Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Expires:0
Pragma:no-cache

Those headers are fine for "normal" pages, but I dont' want them for the method shown above handling /file/**.

Upvotes: 0

Views: 902

Answers (1)

Janar
Janar

Reputation: 2701

Usually ETag header is used for that. From the official Spring documentation on ETags:

An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL.

The request headers used with ETags are "If-None-Match" and "If-Match". Those are used to make requests conditional.

Edit: To get it working with Spring Security you have to disable setting those headers. In configure method you can add httpSecurity.headers().cacheControl().disable();

Upvotes: 1

Related Questions