Subject: 304 on Non-Conditional Request?

From: Mike Bishop <[email-masked]>
Date: Thu, 11 Aug 2016 21:44:38 +0000

Going back over my HTTP Workshop notes around push and cache revalidation, I see a comment that a 304 response to a non-conditional GET is supposed to be valid, if somewhat ambiguous.  I'm trying to parse what that would mean, and I'm drawing a blank.

RFC 7232 defines 304 (Not Modified) this way:

   The 304 (Not Modified) status code indicates that a conditional GET

   or HEAD request has been received and would have resulted in a 200

   (OK) response if it were not for the fact that the condition

   evaluated to false.  In other words, there is no need for the server

   to transfer a representation of the target resource because the

   request indicates that the client, which made the request

   conditional, already has a valid representation; the server is

   therefore redirecting the client to make use of that stored

   representation as if it were the payload of a 200 (OK) response.

I therefore can't envision the scenario in which you would use this for a non-conditional GET.  I could vaguely see the reason phrase "Not Modified" as applying to e.g. a PATCH or PUT that doesn't actually result in a change to the resource, but that still seems more like a 2XX series response, perhaps 202 (Accepted).  But that's not GET.

Is there a scenario I'm missing, were my notes incorrect, or did I accurately transcribe the comment of someone who was incorrect?

---

From: Mark Nottingham <[email-masked]>
Date: Fri, 12 Aug 2016 10:50:03 +1000

If you squint at it just right, you can see a 304 as a redirect to what you already have at hand -- in the common case, what you have in cache, expressed by the conditional.

If there were some other way of expressing what you have at hand, a 304 might be the status code to return in that situation too. It would require some work, though.

Cheers,

> On 12 Aug 2016, at 7:44 AM, Mike Bishop <[email-masked]> wrote:
> 
> Going back over my HTTP Workshop notes around push and cache revalidation, I see a comment that a 304 response to a non-conditional GET is supposed to be valid, if somewhat ambiguous.  I’m trying to parse what that would mean, and I’m drawing a blank.
>  
> I therefore can’t envision the scenario in which you would use this for a non-conditional GET.  I could vaguely see the reason phrase “Not Modified” as applying to e.g. a PATCH or PUT that doesn’t actually result in a change to the resource, but that still seems more like a 2XX series response, perhaps 202 (Accepted).  But that’s not GET.
>  
> Is there a scenario I’m missing, were my notes incorrect, or did I accurately transcribe the comment of someone who was incorrect?

--
Mark Nottingham   https://www.mnot.net/

---

From: "Adrien de Croy" <[email-masked]>
Date: Fri, 12 Aug 2016 01:32:03 +0000

if the request was non-conditional, that would also happen if you didn't 
have any version already.  Client basically needs to retry.

FWIW we see this happen quite a bit with proxies encountering broken 
servers.

E.g.

1. client makes non-conditional request to proxy.
2. Proxy has a stale version
3. Proxy adds If-None-Match and stored ETag
4. Server responds with 304 with different ETag (yes, there are several 
high-profile servers that frequently do this)
5. Exasperated proxy forwards 304 to the client, which then has to 
retry, hopefully the proxy removed the invalidated (by ETag) cache entry 
in the meantime so it works the second time.

Adrien

------ Original Message ------
From: "Mark Nottingham" <[email-masked]>
To: "Mike Bishop" <[email-masked]>
Cc: "HTTP Working Group" <[email-masked]>
Sent: 12/08/2016 12:50:03 PM
Subject: Re: 304 on Non-Conditional Request?

>If you squint at it just right, you can see a 304 as a redirect to what 
>you already have at hand -- in the common case, what you have in cache, 
>expressed by the conditional.
>
>If there were some other way of expressing what you have at hand, a 304 
>might be the status code to return in that situation too. It would 
>require some work, though.
>
>Cheers,
>
>
>>  Going back over my HTTP Workshop notes around push and cache 
>>revalidation, I see a comment that a 304 response to a non-conditional 
>>GET is supposed to be valid, if somewhat ambiguous.  I’m trying to 
>>parse what that would mean, and I’m drawing a blank.
>>
>>  I therefore can’t envision the scenario in which you would use this 
>>for a non-conditional GET.  I could vaguely see the reason phrase “Not 
>>Modified” as applying to e.g. a PATCH or PUT that doesn’t actually 
>>result in a change to the resource, but that still seems more like a 
>>2XX series response, perhaps 202 (Accepted).  But that’s not GET.
>>
>>  Is there a scenario I’m missing, were my notes incorrect, or did I 
>>accurately transcribe the comment of someone who was incorrect?
>
>--

---

From: Willy Tarreau <[email-masked]>
Date: Mon, 15 Aug 2016 10:23:08 +0200

Hi Adrien,

On Fri, Aug 12, 2016 at 01:32:03AM +0000, Adrien de Croy wrote:
> 5. Exasperated proxy forwards 304 to the client, which then has to retry,
> hopefully the proxy removed the invalidated (by ETag) cache entry in the
> meantime so it works the second time.

A long time ago (~15 years) I've been experiencing a different case where
a caching proxy would ignore the if-none-match field, pass the request to
the server, which responds 304, which is forwarded to the client and cached
by the proxy. The next client requesting the same object to the proxy would
be delivered the 304 from the cache.

Willy

---

From: "Adrien de Croy" <[email-masked]>
Date: Tue, 16 Aug 2016 02:03:15 +0000

Actually there's a hole in the spec maybe.

if you get a 304 response to a request that had more than 1 Etag, and 
the Etag in the response doesn't match any of the Etags from the 
request, then there's no way to choose which representation is being 
indicated by the 304.

Is this just a broken server?  We see 304s come back all the time with 
new Etags, and I'm pretty sure I've seen comments about just treating it 
as metadata and updating the stored Etag, but fundamentally

if 304 means no change, and
different Etag means it changed,

then which is it?  And this only "works" if there's only 1 Etag.

Adrien

------ Original Message ------
From: "Willy Tarreau" <[email-masked]>
To: "Adrien de Croy" <[email-masked]>
Cc: "Mark Nottingham" <[email-masked]>; "Mike Bishop" 
<[email-masked]>; "HTTP Working Group" 
<[email-masked]>
Sent: 15/08/2016 8:23:08 PM
Subject: Re: 304 on Non-Conditional Request?

>>retry,