Skip to content

Commit

Permalink
Fixes adding set-cookie headers multiple times (#3026)
Browse files Browse the repository at this point in the history
* Fixes adding set-cookie headers multiple times

* Adds a changeset
  • Loading branch information
matthewp authored Apr 7, 2022
1 parent c3b083f commit 4b0f27d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/calm-dolphins-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix for adding set-cookie multiple times
19 changes: 18 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,24 @@ function writeHtmlResponse(res: http.ServerResponse, statusCode: number, html: s

async function writeWebResponse(res: http.ServerResponse, webResponse: Response) {
const { status, headers, body } = webResponse;
res.writeHead(status, Object.fromEntries(headers.entries()));

let _headers = {};
if('raw' in headers) {
// Node fetch allows you to get the raw headers, which includes multiples of the same type.
// This is needed because Set-Cookie *must* be called for each cookie, and can't be
// concatenated together.
type HeadersWithRaw = Headers & {
raw: () => Record<string, string[]>
};

for(const [key, value] of Object.entries((headers as HeadersWithRaw).raw())) {
res.setHeader(key, value);
}
} else {
_headers = Object.fromEntries(headers.entries());
}

res.writeHead(status, _headers);
if (body) {
if (body instanceof Readable) {
body.pipe(res);
Expand Down
11 changes: 11 additions & 0 deletions packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

export function post() {
const headers = new Headers();
headers.append('Set-Cookie', `foo=foo; HttpOnly`);
headers.append('Set-Cookie', `bar=bar; HttpOnly`);

return new Response('', {
status: 201,
headers,
});
}
8 changes: 8 additions & 0 deletions packages/astro/test/ssr-api-route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,13 @@ describe('API routes in SSR', () => {
const text = await response.text();
expect(text).to.equal(`ok`);
});

it('Can set multiple headers of the same type', async () => {
const response = await fixture.fetch('/login', {
method: 'POST',
});
const setCookie = response.headers.get('set-cookie');
expect(setCookie).to.equal('foo=foo; HttpOnly, bar=bar; HttpOnly');
});
});
});

0 comments on commit 4b0f27d

Please sign in to comment.