Code change:
Technologies such as HTTP/2 will split the header into multiple fields. This PR modifies the spec to no longer expressly forbid this and instructs servers to be aware and capable of handling multiple incoming headers.
In the original 6265 as well as in the latest 6265bis draft, this paragraph exists: This is directly contradicted by RFC 7540 and then : I personally suspect that trying to split the header up into multiples is a recipe for disaster and interop problems even if done only over HTTP/2, but maybe I'm just a pessimist. Would it be sensible to maybe address this contradiction (better) in the bis document?
HTTP/3, repeats the HTTP/2 statement as well: Both these HTTP RFCs also clarify that: But still, that is for the receiving end and does not really restrict the sender when using HTTP/2 or HTTP/3.
I agree that the inconsistency is bad. That said, why do you believe that using multiple field instances can cause an interop problem?
I'm fairly sure Chromium does this, so if there were interop problems, we'd probably have noticed by now. :-) The phrasing is a little odd and probably could be improved. One resolution is to say this is an HPACK-specific encoding thing and not actually sending multiple fields. The full text from 9113 says: I.e. this field splitting starts and ends its life in HTTP/2.
A concern: Some servers have a maximum request header field size limit of around 8K. curl makes sure to never send a header longer than that as it risks getting a 400 back and basically blocking that particular request without it being very obvious to the user. This is a limit RFC6265(bis) does not mention but probably should because it is one of the more important ones. By splitting up the header into multiple ones, the total size of the sent cookies should probably still remain smaller than 8K since there is a risk that there is a h2/3=>h1 conversion done that will pass those cookies on in a single header and thus be affected by this limit. It would if HTTP/3 didn't have the same wording so it also applies there.
Because one RFC says we MUST NOT send them and another says we MAY. I bet there is a server side or two out there that then will not appreciate getting multiple such header fields, perhaps because the h2/h3 special case is not taken care of. But this is just be being worried, I don't know for sure this is the case.
Agreed that such a limit should apply to the total here. I think that would follow from treating this as a funny HPACK encoding of a single field, rather than semantically sending multiple fields. That's not precisely how it's described today, but it results in the exact same behavior on the wire. I.e. we can still get the compression benefits of compressing individual cookies separately, and resolve the slightly awkward phrasing.
Safari started splitting Cookies in h2 and h3 a few years ago, it actually improved website compatibility where the h2 load balancer had a per-field size limit but the ultimate h1 origin did not.
Understood and agreed. So yes, that "MUST NOT" doesn't make any sense, and it's inconsistent with the base HTTP spec. Would be interesting to find out how that got there.
I can't recall the discussions about it on the http-state list back in the day (man, it's been over a decade already!) and I could not find any relevant threads when I casually searched the archives.
Changed from SHOULD NOT to MUST NOT between draft 09 and 10: https://author-URL
I think the wording is intended to be internal to HPACK/QPACK -- that is, there can only ever be one Cookie field as far as HTTP is concerned, but Cookie is special-cased to be split when encoded. To deal with the special case, any occurrence of multiple values gets coalesced. I don't see this as a contradiction.
Are there any remaining concerns before I close this issue? I agree with Mike's interpretation that this isn't a contradiction. The spec mandates that UAs generate a single header field which the server expects on the other end. I don't believe that another layer transparently muxing/demuxing this field is an issue.
I agree that Mike's interpretation is the sensible one to draw from this. I disagree that this is what the specs actually say in the written words.
I can see the potential for confusion here. This seems to stem from 6265bis's tendency to re-implement other specs requirements, but in a somewhat inferior way. The cookie spec probably shouldn't care how the HTTP request is specifically formed so long as the invariant of a single cookie-string from UA -> Server is maintained by the time the server's cookie processing code receives it. URL would probably help here. In the meantime, I'd prefer if we didn't special case actions such as 9113's cookie header field splitting, so maybe some rephrasing could avoid the issue? Here's a rough draft of what I mean. My intention here is to make it clear that the UA (more specifically the cookie code) should create a single cookie-string to attach as the header's value. This would lead to a single header in the default case, but should still allow for header splitting.
9113 and 9114 have to special-case Cookies for one simple reason: they're a semicolon-delimited list rather than a comma-delimited list. 9110 ; the text in question applies the same logic to Cookies despite the different delimiter and points out that for compression reasons it's particularly useful to split Cookie fields. (It might have been worth noting that other list fields might see similar gains from being split and recombined across the compression boundary, too.) I think NAME proposed text on generation is fine -- there should always be exactly one Cookie header generated from UA->server, though a lower layer might mux it before compression. After decompression, demuxing is mandatory when being passed into a context that doesn't know to expect being split. However, there's that exception in both RFCs: "URL being passed into a non-HTTP/2 context, such as an HTTP/1.1 connection, or a generic HTTP server application." This text clearly supposes that anything version-specific which comes after RFC 7540 will know that Cookies may have been split; perhaps this document should prescribe tolerance of receiving that on the server side. It's then an implementation concern whether that tolerance takes the form of recombining them before processing.
Which document specifically?
Sorry, let me clarify antecedents: >This text [found in RFCs 7540, 9113, and 9114] clearly supposes that anything version-specific which comes after RFC 7540 will know that Cookies may have been split; perhaps [6265bis] should prescribe tolerance of receiving that on the server side. That is, perhaps the Cookie spec should require that servers be able to handle Cookie fragments having been split into multiple Cookie headers, since this document has the opportunity to be aware of HTTP/2+ behavior.
Thanks for clarifying, that makes sense.
LGTM % tiny nits.

Related discussion:
text: The user agent includes stored cookies in the Cookie HTTP request header field. <del> When the user agent generates an HTTP request, the user agent MUST NOT attach more than one Cookie header field. </del> A user agent MAY omit the Cookie header field in its entirety.  For example, the user agent might wish to block sending cookies during "third-party" requests from setting cookies (see third-party- cookies). If the user agent does attach a Cookie header field to an HTTP <del> request, the user agent MUST compute the cookie-string following the algorithm defined in retrieval-algorithm, where the retrieval's URI is the request-uri, the retrieval's same-site status is computed for the HTTP request as defined in same-site-requests, and the retrieval's type is "HTTP". </del> <ins> request, the user agent MUST generate a single cookie-string and the user agent MUST compute the cookie-string following the algorithm defined in retrieval-algorithm, where the retrieval's URI is the request-uri, the retrieval's same-site status is computed for the HTTP request as defined in same-site-requests, and the retrieval's type is "HTTP". </ins> 5.7.2.