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

How can I overwrite a response header? #1415

Closed
michal-perlakowski opened this issue Jul 8, 2017 · 8 comments
Closed

How can I overwrite a response header? #1415

michal-perlakowski opened this issue Jul 8, 2017 · 8 comments

Comments

@michal-perlakowski
Copy link

How can I overwrite previously set response header? When I use the addHeader function, it adds another header with the same name instead of overwriting it. For example, if inside a handler function I do this:

addHeader "foo" "bar"
addHeader "foo" "baz"

I get

foo: bar
foo: baz

but I want to get just

foo: baz
@MaxGabriel
Copy link
Member

Here's my read of the situation: It looks like having multiple headers of the same name is acceptable/something you might use, if the headers values can be combined into a comma-separated list. So with that in mind probably addHeader shouldn't change. So maybe the answer is using an application-level Map with overwriteable keys, and before sending the response taking the final Map to set the headers?

@michal-perlakowski
Copy link
Author

@MaxGabriel No, I want to have only one value.

The header is an authentication token, and it works in a way that if it's present in the request, then I send it back in the response. I implemented this as a middleware. However, if it's a login request, a new token is generated, and it should be sent instead of the value from the request header.

@paul-rouse
Copy link
Contributor

If you don't want to restructure your code at the Yesod level (which is what I believe @MaxGabriel was suggesting), could you perhaps process your authentication token in WAI middleware instead of Yesod middleware? You would have access to all request headers, and complete control over the response headers.

@psibi
Copy link
Member

psibi commented Jul 9, 2017

Just wondering if there is any reason why there is no replaceOrCreateHeader function in Yesod.Core.Handler. Probably you can add that and use it if that's acceptable.

@michal-perlakowski
Copy link
Author

I ended up manually creating a Response and sending it with sendWaiResponse:

sendWaiResponse $ responseBuilder (mkStatus 204 "No Content") [("foo", "baz")] ""

@paul-rouse
Copy link
Contributor

@psibi AFAIK there is no reason why such a function couldn't exist. I had a quick look before I posted my first answer, and I think it would involve digging fairly deep. It looks as if you'd need some sort of extra encoding in Yesod.Core.Types.Header, passed down into Yesod.Core.Internal.Response.yarToResponse, which would then have to process the list of headers with something more complicated than the simple maps it does at the moment.

@psibi
Copy link
Member

psibi commented Jul 9, 2017

@paul-rouse Thanks for looking up. I will open a new issue to track it (and possibly implement it once I get some spare time). I looked on other frameworks and they do seem to give the ability to replace headers [0][1][2], so I think this would be a reasonable thing to add to Yesod also.

[0] https://docs.djangoproject.com/en/1.11/ref/request-response/#setting-header-fields
[1] https://stackoverflow.com/q/36099244/1651941
[2] https://stackoverflow.com/q/14956085/1651941

@psibi
Copy link
Member

psibi commented Jul 13, 2017

CC: @paul-rouse I have implemented the relevant functionality in this PR: #1417

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

No branches or pull requests

4 participants