-
-
Notifications
You must be signed in to change notification settings - Fork 535
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
Multiple set-cookie response headers combined into a single one #640
Comments
Hey, @sergey-be. Thanks for raising this. Some context: we're using the headers-utils library as a middle-ground between various environments and their ways to construct and handled Headers, both request and response ones. We use the const headers = new Headers()
headers.set('set-cookie', '123')
headers.append('set-cookie', '456')
headers.get('set-cookie') // "123, 456" I believe I won't be wrong to conclude that this issue is relevant only in the Node.js context, as browsers don't operate with the On the other hand, according to RFC2616, it's perfectly valid to represent multiple message-header fields as a single header where each
Judged by that statement, there seems to be no violation of the spec by keeping multiple |
I'm closing this because I don't think this is a violation of the specification. If you find this obstructing your usage, please consider opening a pull request to the headers-utils package that would handle the |
Hi @kettanaito. Actually, according to rfc6265:
Because it's not valid to set the |
Thanks for the insights, @hugo! The (req, res, ctx) => {
return res(ctx.set('Set-Cookie', serializedCookie))
} I wonder if there are any implications with how the |
My knowledge of service workers is limited, but I think this might be a case where a clean translation of a Web API to the server isn't entirely possible, because of the different semantics. By the looks of it, there is a proposal for how to handle cookies within a service worker — browser support isn't great. In the browser,
If that sounds sensible I'd be happy to (at least try to) produce PRs to make the change. But I'm sure there's nuance here around |
I've been looking into setting multiple cookies myself. I've not been able to do that. I've tried adding multiple "Set-Cookie" headers and I've tried adding multiple cookies as one (comma separated). When using multiple Set-Cookies only the last is respected. Using one Set-Cookies with comma separated values, only the first is respected. From what I can see browsers seem to need multiple Set-cookie headers to work. Is it's possible using MSW @kettanaito & if so how? |
@GetafixIT, you can set multiple new Headers([
['Set-Cookie', 'a=b'],
['Set-Cookie', 'c=d']
]) Headers merge the values of that header into a comma-separated string. To mock that with MSW, I think this should work: res(
ctx.set('Set-Cookie', 'a=b'),
ctx.set('Set-Cookie', 'c=d')
) I also highly encourage you to upgrade to http.post('/sign-in', () => {
return new Response(null, {
headers: new Headers([
['Set-Cookie', 'a=b'],
['Set-Cookie', 'c=d'],
])
})
}) |
@kettanaito thanks for you reply :) I've tried your first suggestion:
This doesn't work. Only the second header is respected. I think this is due to the mapping reference in the underlaying Symbol. I will try upgrading and report back. |
For visibility of the issue with Given the following mock response:
The browser received the following header: But the browser only stores the BBBBB cookie despite both appearing in the header comma separated: This is true in: |
Using I get the following error from my setupServer script: error - ./mocks/server.js:1:0 Module not found: Package path ./node is not exported from package app/node_modules/msw |
This is correct browser behaviour according to the set-cookie header parsing algoritm in the spec. A browser deems the second cookie as an unknown attribute of the first cookie and ignores it. Multiple cookies cannot be folded into a single |
Hey @sergey-be That maybe be so in the spec, however, it also means MSW is unable to set multiple cookies in the browser... a common practice. Perhaps the spec is detailing the way browsers should handle 1 Set-Cookie header with multiple strings in it. But that is not the same things as how to set multiple cookies ... or at least the browsers seem to require multiple Set-Cookie headers to actually set multiple cookies. I could well be wrong... I have not read the spec :) Despite my lack of reading... When I run un-mocked, there are multiple Set-Cookie headers present and the browser respects them, setting multiple cookies. This is the behaviour I'm trying to mock. For example, here are the headers sent by my BE: |
@GetafixIT, try to remove |
Regarding the issue, you may be stumbling upon the Fetch API spec limitation. This is nothing specific to MSW. If you set multiple You get the right behavior when receiving the multi-cookie header from the server because the browser sets it differently behind the scenes. Also note that this behavior is specific only to the |
Note that this is purely a representational issue. The only thing that matters if whether MSW parses that multi-cookie header and applies it correctly to
|
@kettanaito I will take another look Next week and get back to you. |
@kettanaito I've been debugging this today... and thank you for your suggestions. From what I can see, the issue is with the cookie boolean option 'httpOnly'. When I set this option in the mock, those cookies aren't set. So, if I try to strictly mimic the API the cookies don't get set. This is the root cause of the other missing cookies in my case. So I can now set multiple cookies so long as they're not httpOnly. I can work with that. The httpOnly option should prevent cookies from being read by JavaScript. I figured you should be able to set them though, however I did a quick test in the browser - it seems you can't anymore. |
That's interesting. Thanks for looking into it, @GetafixIT! In V2, we are using the Have you tested this on |
@kettanaito I have not yet. Will post here once I have.. |
Describe the bug
Instead of sending multiple
set-cookie
headers as stated in the specification, MSW combines them into a single comma-separated value.Environment
msw: 0.27.1
nodejs: 12.13, 14.16
npm: 6.11.0
To Reproduce
Expected behavior
Multiple headers are sent, i.e
response.res.rawHeaders = [ 'x-powered-by', 'msw', 'set-cookie', 'abc=1', 'set-cookie', 'xyz=0; Secure' ]
The text was updated successfully, but these errors were encountered: