Skip to content

Set-Cookie headers should not be combined / Support Headers.getSetCookie() method #1384

Open
@ezzatron

Description

@ezzatron

The Fetch Standard defines special behaviour for Set-Cookie headers:

To sort and combine a header list list, run these steps. They return a header list.

  1. Let headers be a header list.
  2. Let names be the result of convert header names to a sorted-lowercase set with all the names of the headers in list.
  3. For each name of names:
    1. If name is `set-cookie`, then:
      1. Let values be a list of all values of headers in list whose name is a byte-case-insensitive match for name, in order.
      2. For each value of values:
        1. Append (name, value) to headers.
    2. Otherwise:
      1. Let value be the result of getting name from list.
      2. Assert: value is non-null.
      3. Append (name, value) to headers.
  4. Return headers.

This is because the values of set-cookie headers can contain commas, such as in the case of a cookie with an expiry time (e.g. cookie-name=cookie-value; Path=/; Expires=Thu, 21 Sep 2023 06:12:39 GMT; Secure). Combining them with commas can change their semantics.

This library currently seems to ignore this part of the spec, and combine set-cookie values. For example, this is the current behaviour of whatwg-fetch:

const { Headers } = require("whatwg-fetch");

const headers = new Headers();
headers.append("Set-Cookie", "x=x");
headers.append("Set-Cookie", "y=y");

console.log(JSON.stringify([...headers.entries()])); // outputs [["set-cookie","x=x, y=y"]]

In comparison, Chrome and Firefox follow the spec (Safari doesn't):

Chrome output Firefox output

This seems to be a pretty recent addition to the spec (2021ish). There's also a new method Headers: getSetCookie() method added around the same time which is missing from whatwg-fetch:

Chrome getSetCookie output

For context, I'm using whatwg-fetch as a polyfill for running Jest tests that use Mock Service Worker (MSW), similar to this example over in the MSW project. I noticed this issue because I was setting multiple cookies with different options, and the combining of the cookie values was causing strange behaviour in my tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions