summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Matthew Phillips <matthew@skypack.dev> 2023-05-03 11:26:02 -0400
committerGravatar GitHub <noreply@github.com> 2023-05-03 11:26:02 -0400
commit0883fd4875548a613df122f0b87a1ca8b7a7cf7d (patch)
tree39ca3acab42143f98828770858f0a67c4a570a8a
parent66ada56940bf28b6c4e2bd187a8eb6878e9332d1 (diff)
downloadastro-0883fd4875548a613df122f0b87a1ca8b7a7cf7d.tar.gz
astro-0883fd4875548a613df122f0b87a1ca8b7a7cf7d.tar.zst
astro-0883fd4875548a613df122f0b87a1ca8b7a7cf7d.zip
Ensure multiple cookies set in dev result in multiple set-cookie headers (#6973)
* Ensure multiple cookies set in dev result in multiple set-cookie headers * Adding a changeset * Try connecting to localhost instead * use localhost in the Host header * Use 0.0.0.0 * localhost it is
-rw-r--r--.changeset/twelve-feet-switch.md5
-rw-r--r--packages/astro/src/vite-plugin-astro-server/response.ts7
-rw-r--r--packages/astro/test/fixtures/ssr-api-route/src/pages/login.js15
-rw-r--r--packages/astro/test/ssr-api-route.test.js32
4 files changed, 45 insertions, 14 deletions
diff --git a/.changeset/twelve-feet-switch.md b/.changeset/twelve-feet-switch.md
new file mode 100644
index 000000000..b581fb4c3
--- /dev/null
+++ b/.changeset/twelve-feet-switch.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Ensure multiple cookies set in dev result in multiple set-cookie headers
diff --git a/packages/astro/src/vite-plugin-astro-server/response.ts b/packages/astro/src/vite-plugin-astro-server/response.ts
index 3c075405f..e2f38beb7 100644
--- a/packages/astro/src/vite-plugin-astro-server/response.ts
+++ b/packages/astro/src/vite-plugin-astro-server/response.ts
@@ -57,9 +57,10 @@ export async function writeWebResponse(res: http.ServerResponse, webResponse: Re
// Attach any set-cookie headers added via Astro.cookies.set()
const setCookieHeaders = Array.from(getSetCookiesFromResponse(webResponse));
- setCookieHeaders.forEach((cookie) => {
- headers.append('set-cookie', cookie);
- });
+ if(setCookieHeaders.length) {
+ // Always use `res.setHeader` because headers.append causes them to be concatenated.
+ res.setHeader('set-cookie', setCookieHeaders);
+ }
const _headers = Object.fromEntries(headers.entries());
diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/login.js b/packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
index f486927a0..dfce0b5d6 100644
--- a/packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
+++ b/packages/astro/test/fixtures/ssr-api-route/src/pages/login.js
@@ -1,11 +1,12 @@
-
-export function post() {
- const headers = new Headers();
- headers.append('Set-Cookie', `foo=foo; HttpOnly`);
- headers.append('Set-Cookie', `bar=bar; HttpOnly`);
-
+/** @type {import('astro').APIRoute} */
+export function post({ cookies }) {
+ cookies.set('foo', 'foo', {
+ httpOnly: true
+ });
+ cookies.set('bar', 'bar', {
+ httpOnly: true
+ });
return new Response('', {
status: 201,
- headers,
});
}
diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js
index cafbdf32c..419282b5a 100644
--- a/packages/astro/test/ssr-api-route.test.js
+++ b/packages/astro/test/ssr-api-route.test.js
@@ -2,6 +2,7 @@ import { expect } from 'chai';
import { File, FormData } from 'undici';
import testAdapter from './test-adapter.js';
import { loadFixture } from './test-utils.js';
+import net from 'net';
describe('API routes in SSR', () => {
/** @type {import('./test-utils').Fixture} */
@@ -95,11 +96,34 @@ describe('API routes in SSR', () => {
});
it('Can set multiple headers of the same type', async () => {
- const response = await fixture.fetch('/login', {
- method: 'POST',
+ const response = await new Promise(resolve => {
+ let { port } = devServer.address;
+ let host = 'localhost';
+ let socket = new net.Socket();
+ socket.connect(port, host);
+ socket.on('connect', () => {
+ let rawRequest = `POST /login HTTP/1.1\r\nHost: ${host}\r\n\r\n`;
+ socket.write(rawRequest);
+ });
+
+ let rawResponse = '';
+ socket.setEncoding('utf-8')
+ socket.on('data', chunk => {
+ rawResponse += chunk.toString();
+ socket.destroy();
+ });
+ socket.on('close', () => {
+ resolve(rawResponse);
+ });
});
- const setCookie = response.headers.get('set-cookie');
- expect(setCookie).to.equal('foo=foo; HttpOnly, bar=bar; HttpOnly');
+
+ let count = 0;
+ let exp = /set-cookie\:/g;
+ while(exp.exec(response)) {
+ count++;
+ }
+
+ expect(count).to.equal(2, 'Found two seperate set-cookie response headers')
});
});
});