h5bp / server-configs-nginx

Nginx HTTP server boilerplate configs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

304 responses changes expire time of resource

markwoon opened this issue · comments

Problem:

  1. Expiration time is currently determined by content-type.
  2. Content-type is not set for 304 responses.
  3. This means 304 responses gets the default expiration time, which could be very different from the original.

Indeed. Good catch @markwoon!

-> GET http://server.localhost/test.json

<- HTTP/1.1 200 OK
Server: nginx
Date: Tue, 14 May 2019 22:24:23 GMT
Content-Type: application/json; charset=utf-8
Last-Modified: Sat, 09 Mar 2019 11:21:52 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
ETag: W/"5c83a1d0-117"
Expires: Tue, 14 May 2019 22:24:23 GMT
Cache-Control: max-age=0
X-Content-Type-Options: nosniff

-> GET http://server.localhost/test.json
If-None-Match: W/"5c83a1d0-117"

<- HTTP/1.1 304 Not Modified
Server: nginx
Date: Tue, 14 May 2019 22:25:06 GMT
Last-Modified: Sat, 09 Mar 2019 11:21:52 GMT
Connection: keep-alive
ETag: "5c83a1d0-117"
Expires: Thu, 13 Jun 2019 22:25:06 GMT
Cache-Control: max-age=2592000
X-Content-Type-Options: nosniff

Sending a Cache-Control is expected for a 304:

The server generating a 304 response MUST generate any of the
following header fields that would have been sent in a 200 (OK)
response to the same request: Cache-Control, Content-Location, Date,
ETag, Expires, and Vary.
https://tools.ietf.org/html/rfc7232#section-4.1

But the miss of Content-Type seems to set the expiration delay to the default one, indeed.

Looking for a solution, any suggestion is welcomed.

One solution is to add an empty condition to the $expires map:

map $sent_http_content_type $expires {
  default  1M;
  ""       off; # <--
  ...
}
-> GET http://server.localhost/test.json
If-None-Match: W/"5c83a1d0-117"

<- HTTP/1.1 304 Not Modified
Server: nginx
Date: Wed, 15 May 2019 00:16:42 GMT
Last-Modified: Sat, 09 Mar 2019 11:21:52 GMT
Connection: keep-alive
ETag: "5c83a1d0-117"
X-Content-Type-Options: nosniff

But we lose Cache-Control for empty Content-Type and for 304.

That works for me. I don't think there's much else we can do here.

I think my bigger issue is that there's no way to add "must-revalidate" when using expires, although that's a different issue.

@markwoon Thanks.

there's no way to add "must-revalidate"

Did you try to add must-revalidate the same way we did with no-transform?

Did you try to add must-revalidate the same way we did with no-transform?

Oops, my bad. I got bit by how add_header works when you use it at different scoping levels. I thought expires was somehow blocking the addition of must-revalidate.