Bug 251194 - [fetch] Implement `Headers.prototype.getSetCookie`
Summary: [fetch] Implement `Headers.prototype.getSetCookie`
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL: https://github.com/whatwg/fetch/pull/...
Keywords: BrowserCompat, InRadar
Depends on:
Blocks:
 
Reported: 2023-01-25 21:57 PST by Andreu Botella
Modified: 2023-02-20 04:41 PST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreu Botella 2023-01-25 21:57:28 PST
Spec PR: https://github.com/whatwg/fetch/pull/1346
Test PR: https://github.com/web-platform-tests/wpt/pull/31442

The proposed `getSetCookie()` method of the Headers class allows getting a list of the values of the `Set-Cookie` header in the header list. This was not possible before, since the `get()` method would combine the values by joining them with comma and whitespace, which is valid per the HTTP spec, but clashes with Set-Cookie syntax.

The spec change that introduces this method also changes the iteration behavior for Headers to have each Set-Cookie header show up in the iteration, rather than having them combined.

The fetch spec's `Request` and `Response` classes don't allow setting the `Set-Cookie` header, and `fetch` will remove that header from the returned `Response`. This change to the spec does not change this. It only makes it so a user-created `Headers` class can deal with `Set-Cookie` headers in an easier way, and enables compatibility with server-side runtimes which allow these headers.
Comment 1 Andreu Botella 2023-01-25 22:15:35 PST
By the way, I am working on a patch to implement this method. The main thing that makes this hard in WebKit is that the Headers interface is backed by an `HTTPHeaderMap`, which already combines all headers with the same name. Any patch would therefore have to add support for multiple `Set-Cookie` header values to `HTTPHeaderMap`.

Since `HTTPHeaderMap` already splits headers into two lists, for common (interned) and uncommon headers, it seems like it could have a third list specifically for `Set-Cookie` values. The various methods of `HTTPHeaderMap` that take a header name would have to add a match for `Set-Cookie`, but since `Set-Cookie` is a common header (and assuming it stays that way), the match is a simple enum comparison.

Some questions that are not yet clear to me at this point are how this change would affect any other consumers of `HTTPHeaderMap` in WebCore. In particular, there is at least one consumer (`WebSocketHandshake::serverSetCookie`) which uses `HTTPHeaderMap` to get the `Set-Cookie` value, which currently returns a combined string that isn't perfectly recoverable. Is other code that depends on `Set-Cookie` headers getting the header values from some other API?
Comment 2 youenn fablet 2023-01-26 00:37:43 PST
We should probably not change HTTPHeaderMap. We can change the FetchHeaders class directly.
WebSocketHandshake is deprecated code, it is probably not worth fixing.
Comment 3 Andreu Botella 2023-01-26 02:01:20 PST
For Set-Cookie, combining multiple values with comma followed by whitespace is lossy, since you can have valid values such as "foo=bar; Expires=Thu, 01 Jan 1970 00:00:00 GMT", or even "bar=baz; Path=/test/a, b=c" (where "/test/a, b=c" is the path). Therefore, you can't accurately split a pre-combined value. And this would be observable when constructing Headers instances.

Alternatively, since Set-Cookie is both a forbidden request and response header, `FetchHeaders` could keep track of the Set-Cookie values only if the guard is `FetchHeadersGuard::None`, while maybe storing the combined value in the underlying `HTTPHeaderMap`. This would work, but it seems fragile, since the `FetchHeaders` state would not directly correspond to the `HTTPHeaderMap`'s state.
Comment 4 youenn fablet 2023-01-26 02:19:03 PST
Why would we need to store the Set-Cookie combined value in HTTPHeaderMap?
AIUI, the goal here is to have a general FetchHeaders container, Set-Cookie headers would only be accessed by JS.
Comment 5 Andreu Botella 2023-02-01 15:42:08 PST
Pull request: https://github.com/WebKit/WebKit/pull/9490
Comment 6 Radar WebKit Bug Importer 2023-02-01 21:58:25 PST
<rdar://problem/104946593>
Comment 7 Karl Dubost 2023-02-09 03:53:52 PST
Current Status on
https://wpt.fyi/results/fetch/api/headers/header-setcookie.any.html
Comment 8 EWS 2023-02-20 04:41:42 PST
Committed 260533@main (77fd8deab6cb): <https://commits.webkit.org/260533@main>

Reviewed commits have been landed. Closing PR #9490 and removing active labels.