Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds ability to add more than one cookie per response #1161

Merged
merged 5 commits into from
May 4, 2022

Conversation

merwan7
Copy link
Contributor

@merwan7 merwan7 commented May 2, 2022

Description

This is necessary because the only way to set multiple cookies reliably from node is by writing a header like this:

{'set-cookie': ['foo=bar', 'bar=baz']}

We need to use headers.raw() which is currently provided by node-fetch, so that we can access the unserialized array and set it on the response. Otherwise node-fetch's implementation of Headers, which used by hydrogen, will serialize the array into a comma separated string.

Makes me think that now that fetch is part of Node v16 and v18 this may stop being a problem (I haven't confirmed this yet), but while node-fetch's Response is in use, it's best to use headers.raw() instead for this purpose.

Additional context

This fixes this minor bug Shopify/hydrogen#1138 which we need for our brochure site so we can set our attribution and other cookies in one response.

This behavior of node-fetch is described in its readme here: https://github.com/node-fetch/node-fetch#extract-set-cookie-header


Before submitting the PR, please make sure you do the following:

  • Read the Contributing Guidelines
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123)
  • Update docs in this repository according to your change
  • Run yarn changeset add if this PR cause a version bump based on Keep a Changelog and adheres to Semantic Versioning

@merwan7 merwan7 force-pushed the mr-set-cookie-array branch 2 times, most recently from 45e6a9f to 25c153c Compare May 2, 2022 10:11
@merwan7 merwan7 marked this pull request as ready for review May 2, 2022 10:25
@merwan7 merwan7 marked this pull request as draft May 2, 2022 10:47
@merwan7
Copy link
Contributor Author

merwan7 commented May 2, 2022

setting this back to draft while I figure out testing

@merwan7 merwan7 changed the title uses a for of instead of Object.fromEntries to preserve arrays in headers Adds ability to add more than one cookie per response May 2, 2022
Copy link
Contributor

@blittle blittle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @merwan7 I see the problem with the tests. I can finish this out if you'd like.

@blittle blittle force-pushed the mr-set-cookie-array branch from 6513244 to 2e2eb22 Compare May 3, 2022 17:17
@blittle blittle marked this pull request as ready for review May 3, 2022 17:25
const rawHeaders = headers.raw();
// Warning! Headers.raw is non-standard and might disappear in undici or newer versions of node-fetch
// See: https://github.com/whatwg/fetch/issues/973
const setCookieKey = Object.keys(rawHeaders).find(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that headers.entries() concatenates multiple set-cookie headers into a single string separated by a comma. The thing is that cookie values can have commas, so the browser mis-interprets the multiple cookies. headers.raw() is an non-standard API that returns an array for the value. { 'set-cookie': ['someval=5', 'someotherval=1']}. Subsequently we can use that array on line 947 to append multiple Set-Cookie headers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to limit this to set-cookie? Do we need to support setting multiple values for all headers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was discussed in whatwg/fetch#973, and it doesn't seem to be a problem with other headers. The downside for doing it with all headers is that it just adds more bytes over the wire.

Copy link
Contributor

@blittle blittle May 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically non Set-Cookie headers:

values may be comma-concatenated anyway by any intermediate proxy

packages/hydrogen/src/entry-server.tsx Outdated Show resolved Hide resolved
const rawHeaders = headers.raw();
// Warning! Headers.raw is non-standard and might disappear in undici or newer versions of node-fetch
// See: https://github.com/whatwg/fetch/issues/973
const setCookieKey = Object.keys(rawHeaders).find(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to limit this to set-cookie? Do we need to support setting multiple values for all headers?

@merwan7
Copy link
Contributor Author

merwan7 commented May 3, 2022

Hey @merwan7 I see the problem with the tests. I can finish this out if you'd like.

@blittle thank you so much for driving this one through to the end!

@blittle blittle merged commit 6b963fb into v1.x-2022-07 May 4, 2022
@blittle blittle deleted the mr-set-cookie-array branch May 4, 2022 13:24
blittle added a commit that referenced this pull request May 4, 2022
* v1.x-2022-07: (95 commits)
  [ci] release v1.x-2022-07 (#1170)
  Try ignoring hello-world to see if it will get bumped
  Don't consider examples part of the workspace (#1202)
  Fix headers on oxygen (#1201)
  Add bot user agents for Seoradar and Adresults, resolves #1199 (#1200)
  Fix changeset
  updates to docker deploy documentation to resolve run issues (#1196)
  Upgrade body-parser (#1162)
  Fix path for deployments
  Adds ability to add more than one cookie per response (#1161)
  Move Demo Store to templates folder (#1132)
  Avoid additional div element (#1191)
  Whoops this should only be patch
  Adds preconnect <link> for CDN (#1160)
  Bump ejs from 3.1.6 to 3.1.7 (#1147)
  Fix scroll restoration when server props are changed (#1152)
  Typo
  Fixes #1165 by making a missing alt tag a console warning (#1167)
  Remove concurrency directive for Oxygen deployments
  Fix hydrogen-ui dev and build issues (#1169)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants