Http: conditional get does not allow updating headers without sending body again

I don't know if this is a bug or function in the http specification, or I don't understand things in order.

I have a resource that changes no more than once a week, at the beginning of the week. If it has not changed, the resource of the previous week will be valid throughout the week.

(For all our tests, we modified one week period for five minutes, but I think our observations are still valid).

First, we send the resource with the title Expires: next Monday . The whole week the browser retrieves from the cache. If on Monday we have a new resource, then it is extracted with its new headers, and everything is in order.

The problem occurs when the resource is not updated. In response to the conditional receipt of our application (Java + Tomcat) sends new headers with Expires: next Monday , but without the body. But our external server (apache) removes this header because the specification says that you should not send new headers if the resource has not changed. So, now forever (until the resource changes) the browser will send a conditional get when we want it to continue serving directly from the cache.

Is there a specification compatible method for updating headers without updating the body? (or send it again)

And the subquery: how to make apache go along tomcat headers?

+4
source share
4 answers

Just the Expires header Expires not enough. According to RFC 2616 , section 13.3.4, the server must respond with two Last-Modified and ETag in order to make a conditional GET right:

In other words, the preferred behavior for the HTTP / 1.1 origin server is to send both a strong object tag and the last modified value.

And if the client meets the requirements of HTTP / 1.1, it should send If-Modified-Since . Then the server should respond as follows (quoted in Roy Fielding's suggestion to add a conditional GET ):

  • If the resource is unavailable (for any reason), the server should return a 4XX message exactly as it does now.
  • If the resource no longer exists, the server should return a 404 Not Found response (i.e. the same as it is now).
  • If the resource is available, but its latest modification date is higher (less) or equal to the date, the server should return a 304 Not Modified message (without body).
  • If the resource is available, and the date of its last modification is later than the date, the server should return a 200 OK message (the same as now) with the body.

So, I think you do not need to configure Apache and / or Tomcat as you described. You need to make the HTTP / 1.1 application compatible.

+5
source

Try sending a valid HTTP Date for an Expiring Header?

0
source

One way to solve the problem is to use separate URIs for each week. The canonical url redirects to the appropriate URL within a week and instructs the browser to cache the redirection for a week. In addition, URLs that contain a date in them will point the browser to cache forever.

Canonical URL: / path / to / resource

 Status Code : 301 Location : /path/to/resource/12-dec or /path/to/resource/19-dec Expires : Next Monday 

Week 1: / path / in / resource / 12-dec

 Status code : 200 Expires : Never 

Week 2: / path / in / resource / 19-dec

 Status code : 200 Expires : Never 

When the cache expires on Monday, you simply send a redirect response. You either send the URL of the last weeks or weeks, but you never send the entire body of the response.

With this approach, you eliminated conditional wins. You also contributed your “non-modifiable” resources, and you also get versions with versions.

The only caveat is that redirection is not cached by all browsers, although the http specification requires them to. It is noteworthy that IE8 and below do not cache. For more information, see the “cache browser redirect” column in the browser .

0
source

The Expires header Expires mostly deprecated since HTTP 1.1; Use Cache-Control: max-age instead.

Make sure you enable Last-Modified .

This is optional, but you can also specify Cache-Control: must-revalidate so that intermediate proxies do not deliver potentially stale content.

You do not need to install ETag .

Request example:

 GET http://localhost/images/logo.png HTTP/1.1 Accept: image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5 Referer: http://localhost/default.aspx Accept-Language: en-US User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) Accept-Encoding: gzip, deflate Host: localhost Connection: Keep-Alive 

The response includes the requested content:

 HTTP/1.1 200 OK Cache-Control: max-age=10 Content-Type: image/png Last-Modified: Sat, 21 Feb 2009 11:28:18 GMT Accept-Ranges: bytes Date: Sun, 18 Dec 2011 05:48:34 GMT Content-Length: 2245 

Requests made before the 10 second timeout are resolved from the cache, without an HTTP request. After the timeout:

 GET http://localhost/images/logo.png HTTP/1.1 Accept: image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5 Referer: http://localhost/default.aspx Accept-Language: en-US User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) Accept-Encoding: gzip, deflate Connection: Keep-Alive If-Modified-Since: Sat, 21 Feb 2009 11:28:18 GMT Host: localhost 

The answer is only headers, without content:

 HTTP/1.1 304 Not Modified Cache-Control: max-age=10 Last-Modified: Sat, 21 Feb 2009 11:28:18 GMT Accept-Ranges: bytes Date: Sun, 18 Dec 2011 05:49:04 GMT 

Subsequent requests are again resolved from the browser cache before the specified cache expiration date.

0
source

Source: https://habr.com/ru/post/1385315/


All Articles