Refer to RFC 2109 on HTTP State Management.
An origin server may include multiple Set-Cookie headers in a
response. Note that an intervening gateway could fold multiple such
headers into a single header.
Drupal folds multiple headers by using the following code in drupal_http_request():
if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
// RFC 2109: the Set-Cookie response header comprises the token Set-
// Cookie:, followed by a comma-separated list of one or more cookies.
$result->headers[$header] .= ',' . trim($value);
}
Unfortunately, Drupal fails to account for a legacy case where a cookie contains an "expires" attribute like the following:
Set-Cookie: cookie=2975; expires=Mon, 09-Nov-2009 12:34:19 GMT; path=/
Set-Cookie: cookie2=8456; expires=Mon, 09-Nov-2009 12:34:19 GMT; path=/
On this topic, the RFC notes:
Netscape's original proposal defined an Expires header that took a
date value in a fixed-length variant format in place of Max-Age:Wdy, DD-Mon-YY HH:MM:SS GMT
Note that the Expires date format contains embedded spaces, and that
"old" cookies did not have quotes around values. Clients that
implement to this specification should be aware of "old" cookies and
Expires.
This is a legacy/quirk case, but it would not disrupt operation since the comma is not a delimiter in separate Set-Cookie headers. However, when folding the Set-Cookie handlers into a single comma-separated string, the unprotected commas cause a conflict.
Since Drupal's implementation is currently completely unaware of attribute-value pairs, it would take a lot of additional logic to separate the individual cookies into pairs, then protect values with quotes if necessary, then reassemble them. And it may not be worth it, because the case is so rare. However, I have just encountered it and will now have to code a workaround on my own, so I'm reporting the issue here.
Comments
Comment #1
franzBumping. So the RFC is not fully implemented?
Comment #2
mikeytown2 commentedWhat I've done in httprl
Comment #4
mikeytown2 commentedI've come up with some cleaner code and added in a lot more comments.
Comment #6
mikeytown2 commentedComment #7
mikeytown2 commentedD8 has guzzle. Moving this to D7.