`setCookie` on the same key multiple times is not deduped
What version of Hono are you using?
4.9.10
What runtime/platform is your app running on? (with version if possible)
What steps can reproduce the bug?
simply call setCookie with the same key multiple times, e.g.:
setCookie(c, 'hello', 'world1')
setCookie(c, 'hello', 'world2')
setCookie(c, 'hello', 'world3')
What is the expected behavior?
Only the last call's data is sent, i.e.:
set-cookie:
hello=world3; Path=/
What do you see instead?
set-cookie:
hello=world1; Path=/
set-cookie:
hello=world2; Path=/
set-cookie:
hello=world3; Path=/
The response includes multiple Set-Cookie header for the same key, wasting unnecessary bandwidth and possibly prone to error with the receiving client's parser.
Additional information
No response
Hi @NamesMT, thank you for your comment.
While the response data will undoubtedly be larger than necessary, it is not an invalid response, so I don't believe it will cause an error on the client side.
I don't think there are many cases where the same cookie is sent multiple times. I believe the current simple implementation is sufficient.
Hi @usualoma, while its indeed not an invalid response, it might cause issues via aspects like
- Response (header) limits, like AWS Lambda
- When our client is not a modern browser but some application/server with a simple cookie header parsing method, which I'm working with currently XD, that's probably out of Web Standards scope and should be fixed in said client, but we can also fix it by not sending unnecessary dupes.
You're right about it being rare for this use-case to happen, I'm logging this mainly to raise awareness and get feedbacks, I'm intending to do a refactor/enhancement PR on the cookie utils soon-ish probably.
Hi @NamesMT, thanks for raising such an interesting question - if you don't mind me weighing in, it's my understanding that since Hono relies on fetch API web standards (Headers, Response, etc.) in order to handle HTTP response construction, deduplication like you describe would need to be handled by at the runtime layer (or even the fetch API layer), not at the framework layer, right?
| layers |
|---|
| Hono |
| JS/TS runtime |
| Fetch API |
| HTTP spec |
Interestingly, I wasn't able to find any runtimes that dedupe set-cookie headers with identical keys, despite the fact that the most recent RFC HTTP standard strongly advises against duplicates:
"Servers SHOULD NOT include more than one Set-Cookie header field in the same response with the same cookie-name."
Note that the current standard is from 2011, and its proposed replacement goes even further, updating the language from 'SHOULD NOT' to 'MUST NOT'!
Servers MUST NOT include more than one Set-Cookie header field in the same response with the same cookie-name."
It seems to me that at this point it's mostly
- left to the server author to ensure that duplicates aren't generated
- and left to the client/user-agent to process duplicates appropriately when they do occur
Obviously this isn't ideal for a number of reasons, but it's unsurprising that it's the case due to how much history is wrapped up in cookies, set-cookie's unique status among headers, and the fact that "fixing" this would require updating the fetch API standard implementation of the HTTP spec.
That said, Hono could implement deduplication as a developer convenience feature to help avoid these edge cases like the one you're running into, which would really set it apart from other implementations! The set-cookie header intentionally gets special treatment by the fetch API to allow multiple values, but there's nothing preventing Hono from maintaining a map of cookie names and only setting the final value when constructing the response, besides the fact that it would be a slight deviation from the web standard behavior it's designed around.
Thanks again for bringing this up - if I happen to be misunderstanding anything here, I welcome feedback! I've been really enjoying using Hono recently, and I'm mostly just happy to be able to get into the weeds of this topic 😁
Hi @marsbird, thank you for the very helpful link and comments!
I see. If deduping by name is preferred in the specification, doing it at the Hono layer is one option.
That said, even if the proposal in the link gets approved and becomes a MUST NOT, I doubt any clients would change their current behavior. Moreover, since few applications set multiple cookies with the same name in the same request via set-cookie, it's questionable whether implementing this is reasonable.
The specification simply states “with the same cookie-name,” but it's tricky whether it's acceptable to dedupe solely by name when multiple Set-Cookie headers exist with identical names but differing Domain= or Path=.
Consolidating Set-Cookie headers can be handled at the application layer. Unless the current implementation is causing practical problems, I don't think changes are necessary at this time.
It would be nice if something took care of duplicate cookies, but I can also see the argument for leaving that for the application layer. Some cases that would need to be considered would include
- only accepting the first unique
namevalue and ignoring additional values - only accepting the last unique
namevalue and forgetting all previous values - throwing an error if a unique
namevalue has already been set
There are probably others I haven't considered. Each case would be equally valid. My personal opinion is that multiple calls to setCookie with the same name would be a bug in my application logic, and I'd restructure things to prevent it.