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
Gothdo opened this Issue Jul 8, 2017 · 8 comments

Comments

Projects
None yet
4 participants
@Gothdo

Gothdo commented Jul 8, 2017

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

This comment has been minimized.

Show comment
Hide comment
@MaxGabriel

MaxGabriel Jul 8, 2017

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?

Member

MaxGabriel commented Jul 8, 2017

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?

@Gothdo

This comment has been minimized.

Show comment
Hide comment
@Gothdo

Gothdo Jul 8, 2017

@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.

Gothdo commented Jul 8, 2017

@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

This comment has been minimized.

Show comment
Hide comment
@paul-rouse

paul-rouse Jul 9, 2017

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.

Contributor

paul-rouse commented Jul 9, 2017

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

This comment has been minimized.

Show comment
Hide comment
@psibi

psibi Jul 9, 2017

Member

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.

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.

@Gothdo

This comment has been minimized.

Show comment
Hide comment
@Gothdo

Gothdo Jul 9, 2017

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

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

Gothdo commented Jul 9, 2017

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

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

@Gothdo Gothdo closed this Jul 9, 2017

@paul-rouse

This comment has been minimized.

Show comment
Hide comment
@paul-rouse

paul-rouse Jul 9, 2017

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.

Contributor

paul-rouse commented Jul 9, 2017

@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

This comment has been minimized.

Show comment
Hide comment
@psibi

psibi Jul 9, 2017

Member

@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

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

This comment has been minimized.

Show comment
Hide comment
@psibi

psibi Jul 13, 2017

Member

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

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