Bug 18388

Summary: Set-Cookie header not honored on 304 (Not modified) status
Product: Apache httpd-2 Reporter: Ryan J Eberhard <ryan.eberhard>
Component: CoreAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED FIXED    
Severity: normal Keywords: FixedInTrunk
Priority: P3    
Version: 2.0.44   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: Process Set-Cookien on HTTP_NOT_MODIFIED

Description Ryan J Eberhard 2003-03-26 20:39:41 UTC
RFC 2109 -- HTTP State Management, e.g. cookies -- does not specify whether
cookies should be returned on requests with HTTP status codes other than 200. 
However, the earlier Netscape cookie specification did state that cookies should
be returned on other status codes, specifically 304 (Not modified).

Returning cookies during a 304 or 302 (Redirect) is very useful for
authorization / access-management products.

Can you please enable the Set-Cookie header during a 304?

Code to change is line 1675 of /modules/http/http_protocol.c.

Thanks!
Comment 1 Ryan J Eberhard 2003-04-21 18:13:45 UTC
Created attachment 5927 [details]
Process Set-Cookien on HTTP_NOT_MODIFIED
Comment 2 Jeff Trawick 2003-05-31 21:10:30 UTC
This has been reported before (in the old PR database, against Apache 1.3).
The answer, in the words of Marc Slemko, is:

"It is not valid to set a cookie in a 304 response.  Please see section 10.3.5
of RFC2616.  That is the reason Apache explictly lists headers that will be sent
and why Set-Cookie isn't one of them."
Comment 3 Ryan J Eberhard 2003-06-03 13:54:15 UTC
Section 10.3.5 of RFC 2616 makes this statement:

   "If the conditional GET used a strong cache validator (see section
   13.3.3), the response SHOULD NOT include other entity-headers.
   Otherwise (i.e., the conditional GET used a weak validator), the
   response MUST NOT include other entity-headers; this prevents
   inconsistencies between cached entity-bodies and updated headers."

Note that only entity-headers are forbidden.

Section 4.2 describes three sets of headers: request (defined in 5.3), response
(defined in section 6.2), and entity (defined in section 7.1).

Each of these three sections lists headers, but "Set-Cookie" is not listed in
any of the three sets.

Section 6.2 makes this statment:

   "The response-header fields allow the server to pass additional
   information about the response which cannot be placed in the Status-
   Line."

and...

   "However, new or
   experimental header fields MAY be given the semantics of response-
   header fields if all parties in the communication recognize them to
   be response-header fields. Unrecognized header fields are treated as
   entity-header fields."

While section 7.1 makes this statement:

   "Entity-header fields define metainformation about the entity-body or,
   if no body is present, about the resource identified by the request."

Set-Cookie meets the test of universal acceptance as a known response-header and
is must better defined as a response-header ("additional information") than as
an entity-header ("metainformation about the entity-body").

It is also important to note that all other major web servers (IIS, iPlanet, and
Domino) will return Set-Cookie headers on a 304 status.
Comment 4 Jeff Trawick 2003-11-21 22:16:16 UTC
enabling the PatchAvailable keyword
updated doc on submitting patches is at http://httpd.apache.org/dev/patches.html
Comment 5 Nicolas Grekas 2005-02-25 12:41:30 UTC
The http_protocol.c file has changed, so the patch should apply line 1657 rather
than line 1682.

This bug is more than one year old.
Just by correcting it, it could be possible to reduce bandwith usage on Apache 2
servers, by not resending all the page just to set a cookie.
Please take a second to apply the patch in the next 2.0.54 or so.
Thank you very very much !

Here is a small PHP script to test the bug :
on Apache 1.3.x, the printed line changes every second,
on Apache <=2.0.53, it won't change

==============
<?php
if (@$_SERVER['HTTP_IF_MODIFIED_SINCE']) header('HTTP/1.x 304 Not Modified');

header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Set-Cookie: test=' . time());

?>
<script>document.write(document.cookie);</script>
==============
Comment 6 Roy T. Fielding 2008-05-16 17:41:41 UTC
This was fixed in trunk in 2004 (r104924).
Comment 7 Roy T. Fielding 2008-05-16 18:11:38 UTC
and released in 2.2.0.