What does a proper etag response look like? - http-status-codes

We were wondering,
Header wise... What does a proper etag response look like.
Etag response, in the sense that an e-tagged request is made, and yes it matches the etag on our end, thus no content must be sent.
Does it need to contain a content-length header?
Do we use a 304 header response?
Claritifaction:
We want to etag handle via php.
The flow is as follows:
a) Etagged request comes in.
b) PHP checks the etag to see if it meets what we think is a proper condition NOT to send back a full document body.
c) What do we manually send back via php to signal to the browser to use the cached content?
Thanks!

Answered my own question after reading the wiki as lanzz sudgested in the comment above:
"In this subsequent request, the server may now compare the client's
ETag with the ETag for the current version of the resource. If the
ETag values match, meaning that the resource has not changed, then the
server may send back a very short response with an HTTP 304 Not
Modified status. The 304 status tells the client that its cached
version is still good and that it should use that."
So yes, a 304 response is the correct way to answer an etagged request if you want the user agent to use the cached copy.

Related

Will New Cache Control Headers Be Seen If Page Previously Cached?

I am trying to determine when newly set cache-control headers will be read by end-users who have previously cached a page.
Let's say a user loads a page that does not have any cache-control headers set. Then I add cache-control: no-cache, no-store header at the server level. Will it force even the users who had previously visited and cached the page to get the latest version? Or would their current version have to expire per their browsers rules since no headers were initially set?
The latter. Headers aren't pushed unless a user agent requests a resource. However, see this question. If a client makes a conditional request to validate its cache, those headers will also be sent in 304 responses. The spec says the cache MUST
use other header fields provided in the 304 (Not Modified)
response to replace all instances of the corresponding header
fields in the stored response.

Using Etags with ember-data

I am trying to implement some client side caching via etags and last modified headers; however, ember-data doesn't seem to be using the etags for the ajax requests. I only get 200 responses and never a 304. I don't see any ETag header being sent with the request headers.
When I make the ajax request multiple times directly from the browser address bar, I'll get 304 not modified responses after the first request, so I know the server is sending things back correctly.
Is there a configuration I need to set up to make this happen?
This is a CORS request, but I think that I have and I have exposed the ETag header:
Access-Control-Expose-Headers: ETag
and the Etag header is sent back with the response.

How does validation work in case of a browser cache, proxy cache and an origin server?

See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Freshness
when the cache receives a request for a stale resource, it forwards this request with a If-None-Match to check if it is in fact still fresh. If so, the server returns a 304 (Not Modified) header without sending the body of the requested resource, saving some bandwidth.
Let's assume we have: a browser cache, proxy cache and an origin server:
The browser cache contains a stored stale resource with entity-tag "A".
The proxy cache contains a stored stale resource with entity-tag "B". The proxy cache can act as a client, and as a server.
This can for example be the case if you're just starting to use a proxy cache. What will happen in this case?
The browser will send a conditional request with If-None-Match: "A".
The proxy cache receives the conditional request.
The proxy cache will forward this request (according to the quote above). This is because the stored resource in proxy cache is stale.
The origin server receives the request with the entity-tag "A".
Let's say, the resource on the origin server contains entity-tag "A". Now the server will respond with a 304 Not Modified response.
At this point, I don't understand things anymore, so maybe I misunderstood something before? The 304 response is okay for the browser cache, because it contains the same resource as on the origin server (same entity-tag). However, the proxy cache contains an older resource (with a different Etag). If the proxy cache would receive the 304 response (and would update its metadata), then the proxy cache makes a resource valid again while it's an old resource.
This is not desirable, so probably I made a mistake somewhere? How does it actually work? How I have to see this process?
Have a look at the section 4.3 of the RFC7234 spec. Section 4.3.2 in particular says the following:
When a cache decides to revalidate its own stored responses for a
request that contains an If-None-Match list of entity-tags, the cache
MAY combine the received list with a list of entity-tags from its own
stored set of responses (fresh or stale) and send the union of the
two lists as a replacement If-None-Match header field value in the
forwarded request. If a stored response contains only partial
content, the cache MUST NOT include its entity-tag in the union
unless the request is for a range that would be fully satisfied by
that partial stored response. If the response to the forwarded
request is 304 (Not Modified) and has an ETag header field value with
an entity-tag that is not in the client's list, the cache MUST
generate a 200 (OK) response for the client by reusing its
corresponding stored response, as updated by the 304 response
metadata (Section 4.3.4).
So the proxy can send both entity tags (A and B) to the origin server for validation. If the resource representation hasn't changed, the origin server will send a 304 response. If the entity tag in that response is B, the proxy can freshen its stale, stored response and use it to send a 200 OK response to the client. Upon receiving this new response, the browser can update its cache with it.
Now, in the scenario you have specified, the 304 NOT MODIFIED response contains the entity tag A (can such a scenario even occur, given that you are accessing the resources through the proxy?). The spec doesn't seem to address this specific case explicitly, but I guess you can just forward the 304 NOT MODIFIED response to the browser. Upon receiving it, the browser can freshen the stale response using its meta data.

codeception get request with if-none-match does not return 304

i am using codeception for the code coverage of a REST API. In my current case, i want to test the behaviour of sending a request to receive an ETag-Header for the requested resource and reuse the value of this ETag in a second request on the same resource with the header "If-None-Match" to achieve a 304 response code.
So what I am doing in my Cest-File is:
// send first request, grab etag
$I->sendGET('/myresource');
$I->seeResponseCodeIs(200);
$I->seeHttpHeader('ETag');
$eTag = $I->grabHttpHeader('ETag');
// send second request with header "If-None-Match" containing the etag
$I->haveHttpHeader('If-None-Match', $eTag);
$I->sendGET('/myresource');
$I->seeHttpHeader('ETag');
$I->seeResponseCodeIs(304);
When I execute this test it fails after the second request saying that response code 200 does not match 304.
When I execute the same request with an external tool (HTTP Requester Plugin for Firefox), i get the expected behaviour. What do i have to do to get my tests working? Am i mssing something on the codeception side or may this be a bug?
Any help is appreciated, maybe someone already had this scenario before.
Thanks in advance for your help!

How to prevent the server from replying with 304?

I need to know the steps that I can do to prevent the server from replying with 304.
Your client is probably sending an 'If-Modified-Since' header. Don't send it and you should be fine.
The intent of the header and the 304 reply is that if the client already has the latest data (as per the header 'If-Modified-Since'), there is no point in downloading it again.
The server will send a 304 if the content has not been modified since a particular date. That date is set via the client's IF_MODIFIED_SINCE header. See here for more details.
I recognized that It is not a good idea to do so.
However, If you need to do so, You can put some filter in the server to reset the value of IF_MODIFIED_SINCE request tag.

Resources