Fixes adding set-cookie headers multiple times (#3026)
* Fixes adding set-cookie headers multiple times * Adds a changeset
This commit is contained in:
parent
c3b083f286
commit
4b0f27d9ff
4 changed files with 42 additions and 1 deletions
5
.changeset/calm-dolphins-remain.md
Normal file
5
.changeset/calm-dolphins-remain.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix for adding set-cookie multiple times
|
|
@ -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);
|
||||
|
|
11
packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
vendored
Normal file
11
packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
vendored
Normal file
|
@ -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,
|
||||
});
|
||||
}
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue