Skip to content

Fix multiple headers with the same name #1666

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

Merged
merged 5 commits into from
Mar 29, 2023

Conversation

dgaw
Copy link
Contributor

@dgaw dgaw commented Mar 21, 2023

Fix recursion in the instance BuildHeadersTo (Header h v ': xs) so that multiple headers with the same name work in servant-client.

Fixes #1665

@tchoutri
Copy link
Contributor

@dgaw Thanks a lot! Could you also include a changelog entry? :) We collect entries in different files in https://github.com/haskell-servant/servant/tree/master/changelog.d and amalgamate them later during release

@dgaw
Copy link
Contributor Author

dgaw commented Mar 22, 2023

@tchoutri I've added a changelog entry and removed an old comment.

Copy link
Contributor

@tchoutri tchoutri left a comment

Choose a reason for hiding this comment

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

Awesome, thank you

Comment on lines +107 to +113
buildHeadersTo headers = case L.find wantedHeader headers of
Nothing -> MissingHeader `HCons` buildHeadersTo headers
Just header@(_, val) -> case parseHeader val of
Left _err -> UndecodableHeader val `HCons` buildHeadersTo (L.delete header headers)
Right h -> Header h `HCons` buildHeadersTo (L.delete header headers)
where wantedHeader (h, _) = h == wantedHeaderName
wantedHeaderName = CI.mk . pack $ symbolVal (Proxy :: Proxy h)
Copy link
Contributor

Choose a reason for hiding this comment

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

I had a look at multiple RFCs regarding HTTP header fields, i.e.:

At the end, we do not still have a precise definition for which field lines with the same field name are allowed to be present in the HTTP message or not (except for the Set-Cookie), and which ones are allowed to be merged in some way.
We have something about it, see [4] and [5], and those RFCs are pretty new or are still drafts.

I think that the current (fixed) approach of not manipulating the requested header fields is ok.
We'll be able to create also not valid messages, and this is good for testing (here being not valid means that we could generate HTTP messages with header fields with the same field name, for which we require to have just one line, and not multiple ones).

I would just add a short comment that summarise this behaviour, like: The current implementation do not manipulate HTTP header field lines in any way, like merging field lines with the same field name in a single line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for doing the research @marinelli! I've added the suggested comment.

@tchoutri tchoutri merged commit 9131f4f into haskell-servant:master Mar 29, 2023
@ysangkok
Copy link
Contributor

This is now released on Hackage and is visible in the changelog for servant-client-0.20.

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.

servant-client doesn't handle multiple Set-Cookie headers correctly
4 participants