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

fix: allow cookies to be set in rewritten responses #11280

Merged
merged 3 commits into from
Jun 20, 2024
Merged

fix: allow cookies to be set in rewritten responses #11280

merged 3 commits into from
Jun 20, 2024

Conversation

ascorbic
Copy link
Contributor

Changes

Ensures that set-cookie headers are set when rewriting a request.

Fixes #11265

Testing

Adds a test case for a rewritten request

Docs

Just a bugfix

Copy link

changeset-bot bot commented Jun 18, 2024

🦋 Changeset detected

Latest commit: a5412a7

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Jun 18, 2024

if (result.cookies) {
for (const cookie of AstroCookies.consume(result.cookies)) {
response.headers.append('Set-Cookie', cookie);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should append the headers here. They are already appended further up in the response, here:

if (addCookieHeader) {
for (const setCookieHeaderValue of App.getSetCookieFromResponse(response)) {
response.headers.append('set-cookie', setCookieHeaderValue);
}
}

What I think is happening in this bug is that the Response has changed because of rewriting, so the AstroCookies object is not attached to it anymore. So what I think you can do is call attachCookiesToResponse here and then when the cookies are consumed further up the chain they will be appended to the response there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like they actually need to be merged, so I took a different approach

* Merges a new AstroCookies instance into the current instance. Any new cookies
* will be added to the current instance, overwriting any existing cookies with the same name.
*/
merge(cookies: AstroCookies) {
Copy link
Member

Choose a reason for hiding this comment

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

I have mixed feelings about this method, I would prefer to return a new instance instead of manipulating the existing one. Essentially, try to use a pure/functional approach and avoid side-effects.

I would called this method fork instead

Copy link
Contributor

Choose a reason for hiding this comment

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

Why? In this case there are already 2 AstroCookies instances created (once for each response), what does adding a 3rd accomplish? This is not immutable style code, and this function is not mutating the argument, it's mutating itself.

Copy link
Member

@ematipico ematipico Jun 19, 2024

Choose a reason for hiding this comment

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

I don't think this is the correct fix. I think the fix should be done here:

this.cookies = new AstroCookies(this.request);

And here

this.cookies = new AstroCookies(this.request);

And the code should be

this.cookies = this.cookies.fork(this.request)

fork will return a new instance of AstroCookies, and the creation of these new cookies is confined inside the rewrite function, while the proposed solution seems to be more broad

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, that plan makes sense then. 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think will help with cookies that are set on the response. It only merges the request cookies.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm happy to change it to a pure function, but I don't think it can be done at the point the cookies are first assigned.

Copy link
Member

@ematipico ematipico Jun 19, 2024

Choose a reason for hiding this comment

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

What confuses me is the term "rewriting a response" from the initial issue. Astro.rewrite, actually, rewrites a Request, and you'll get Response, eventually. But there's no "rewritten response" involved. So I wonder how the issue is related to rewriting? I am a bit confused 😅 maybe I am missing something

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It refers to responses to a rewritten request. If page /a has Astro.rewrite('/b'), and /b sets a cookie, currently the cookie from b is not returned.

packages/astro/src/core/render-context.ts Outdated Show resolved Hide resolved
@@ -0,0 +1,4 @@
---
console.log('cookie value: ', Astro.cookies.get('my_cookie')?.value);
Copy link
Member

Choose a reason for hiding this comment

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

Should we add another test where in the first page we set a lorem value, then in the rewritten page we set a ipsum value, and assert that the cookie has ipsum as value?

@ascorbic
Copy link
Contributor Author

@ematipico and I had a chat and agreed this approach

@ascorbic ascorbic merged commit fd3645f into main Jun 20, 2024
13 checks passed
@ascorbic ascorbic deleted the plt-2207 branch June 20, 2024 10:08
@astrobot-houston astrobot-houston mentioned this pull request Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cookie not set when response is rewritten (experimental.rewriting)
3 participants