diff options
author | 2023-06-06 15:11:47 +0000 | |
---|---|---|
committer | 2023-06-06 15:11:47 +0000 | |
commit | a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485 (patch) | |
tree | 1451b4462c572b88d409faa2e2a01439012afcf3 /packages/integrations/node | |
parent | 4929332c3210d1634b8607c7736d9049860a2079 (diff) | |
download | astro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.tar.gz astro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.tar.zst astro-a1144f7fec0cb93eb1fd549beb9f5bc91ee1f485.zip |
[ci] format
Diffstat (limited to 'packages/integrations/node')
5 files changed, 231 insertions, 232 deletions
diff --git a/packages/integrations/node/src/createOutgoingHttpHeaders.ts b/packages/integrations/node/src/createOutgoingHttpHeaders.ts index 5b99cfa4f..80269489e 100644 --- a/packages/integrations/node/src/createOutgoingHttpHeaders.ts +++ b/packages/integrations/node/src/createOutgoingHttpHeaders.ts @@ -3,38 +3,40 @@ import type { OutgoingHttpHeaders } from 'http'; /** * Takes in a nullable WebAPI Headers object and produces a NodeJS OutgoingHttpHeaders object suitable for usage * with ServerResponse.writeHead(..) or ServerResponse.setHeader(..) - * + * * @param webHeaders WebAPI Headers object * @returns NodeJS OutgoingHttpHeaders object with multiple set-cookie handled as an array of values */ -export const createOutgoingHttpHeaders = (webHeaders: Headers | undefined | null): OutgoingHttpHeaders | undefined => { - if (!webHeaders) { - return undefined; - } +export const createOutgoingHttpHeaders = ( + webHeaders: Headers | undefined | null +): OutgoingHttpHeaders | undefined => { + if (!webHeaders) { + return undefined; + } - // re-type to access Header.getSetCookie() - const headers = webHeaders as HeadersWithGetSetCookie; + // re-type to access Header.getSetCookie() + const headers = webHeaders as HeadersWithGetSetCookie; - // at this point, a multi-value'd set-cookie header is invalid (it was concatenated as a single CSV, which is not valid for set-cookie) - const nodeHeaders: OutgoingHttpHeaders = Object.fromEntries(headers.entries()); + // at this point, a multi-value'd set-cookie header is invalid (it was concatenated as a single CSV, which is not valid for set-cookie) + const nodeHeaders: OutgoingHttpHeaders = Object.fromEntries(headers.entries()); - if (Object.keys(nodeHeaders).length === 0) { - return undefined; - } + if (Object.keys(nodeHeaders).length === 0) { + return undefined; + } - // if there is > 1 set-cookie header, we have to fix it to be an array of values - if (headers.has('set-cookie')) { - const cookieHeaders = headers.getSetCookie(); - if (cookieHeaders.length > 1) { - // the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie' - nodeHeaders['set-cookie'] = cookieHeaders; - } - } + // if there is > 1 set-cookie header, we have to fix it to be an array of values + if (headers.has('set-cookie')) { + const cookieHeaders = headers.getSetCookie(); + if (cookieHeaders.length > 1) { + // the Headers.entries() API already normalized all header names to lower case so we can safely index this as 'set-cookie' + nodeHeaders['set-cookie'] = cookieHeaders; + } + } - return nodeHeaders; + return nodeHeaders; }; interface HeadersWithGetSetCookie extends Headers { - // the @astrojs/webapi polyfill makes this available (as of undici@5.19.0), but tsc doesn't pick it up on the built-in Headers type from DOM lib - getSetCookie(): string[]; + // the @astrojs/webapi polyfill makes this available (as of undici@5.19.0), but tsc doesn't pick it up on the built-in Headers type from DOM lib + getSetCookie(): string[]; } diff --git a/packages/integrations/node/src/http-server.ts b/packages/integrations/node/src/http-server.ts index 9f8b3e891..8d463ba6f 100644 --- a/packages/integrations/node/src/http-server.ts +++ b/packages/integrations/node/src/http-server.ts @@ -60,9 +60,9 @@ export function createServer( let location: string; if (req.url!.includes('?')) { const [url = '', search] = req.url!.split('?'); - location = `${url}/?${search}` + location = `${url}/?${search}`; } else { - location = req.url + '/' + location = req.url + '/'; } res.statusCode = 301; diff --git a/packages/integrations/node/src/nodeMiddleware.ts b/packages/integrations/node/src/nodeMiddleware.ts index 492130daa..c0d439ba0 100644 --- a/packages/integrations/node/src/nodeMiddleware.ts +++ b/packages/integrations/node/src/nodeMiddleware.ts @@ -1,9 +1,9 @@ import type { NodeApp } from 'astro/app/node'; import type { IncomingMessage, ServerResponse } from 'http'; import type { Readable } from 'stream'; +import { createOutgoingHttpHeaders } from './createOutgoingHttpHeaders'; import { responseIterator } from './response-iterator'; import type { Options } from './types'; -import { createOutgoingHttpHeaders } from './createOutgoingHttpHeaders'; export default function (app: NodeApp, mode: Options['mode']) { return async function ( @@ -45,16 +45,16 @@ async function writeWebResponse(app: NodeApp, res: ServerResponse, webResponse: if (app.setCookieHeaders) { const setCookieHeaders: Array<string> = Array.from(app.setCookieHeaders(webResponse)); - + if (setCookieHeaders.length) { - for (const setCookieHeader of setCookieHeaders) { - webResponse.headers.append('set-cookie', setCookieHeader); - } + for (const setCookieHeader of setCookieHeaders) { + webResponse.headers.append('set-cookie', setCookieHeader); + } } } - const nodeHeaders = createOutgoingHttpHeaders(headers); - res.writeHead(status, nodeHeaders); + const nodeHeaders = createOutgoingHttpHeaders(headers); + res.writeHead(status, nodeHeaders); if (webResponse.body) { try { for await (const chunk of responseIterator(webResponse) as unknown as Readable) { diff --git a/packages/integrations/node/test/createOutgoingHttpHeaders.test.js b/packages/integrations/node/test/createOutgoingHttpHeaders.test.js index 1876c9a00..2f7063b1c 100644 --- a/packages/integrations/node/test/createOutgoingHttpHeaders.test.js +++ b/packages/integrations/node/test/createOutgoingHttpHeaders.test.js @@ -3,76 +3,74 @@ import { expect } from 'chai'; import { createOutgoingHttpHeaders } from '../dist/createOutgoingHttpHeaders.js'; describe('createOutgoingHttpHeaders', () => { + it('undefined input headers', async () => { + const result = createOutgoingHttpHeaders(undefined); + expect(result).to.equal(undefined); + }); - it('undefined input headers', async () => { - const result = createOutgoingHttpHeaders(undefined); - expect(result).to.equal(undefined); - }); + it('null input headers', async () => { + const result = createOutgoingHttpHeaders(undefined); + expect(result).to.equal(undefined); + }); - it('null input headers', async () => { - const result = createOutgoingHttpHeaders(undefined); - expect(result).to.equal(undefined); - }); + it('Empty Headers', async () => { + const headers = new Headers(); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.equal(undefined); + }); - it('Empty Headers', async () => { - const headers = new Headers(); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.equal(undefined); - }); + it('Headers with single key', async () => { + const headers = new Headers(); + headers.append('x-test', 'hello world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ 'x-test': 'hello world' }); + }); - it('Headers with single key', async () => { - const headers = new Headers(); - headers.append('x-test', 'hello world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ 'x-test': 'hello world' }); - }); + it('Headers with multiple keys', async () => { + const headers = new Headers(); + headers.append('x-test1', 'hello'); + headers.append('x-test2', 'world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ 'x-test1': 'hello', 'x-test2': 'world' }); + }); - it('Headers with multiple keys', async () => { - const headers = new Headers(); - headers.append('x-test1', 'hello'); - headers.append('x-test2', 'world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ 'x-test1': 'hello', 'x-test2': 'world' }); - }); + it('Headers with multiple values (not set-cookie)', async () => { + const headers = new Headers(); + headers.append('x-test', 'hello'); + headers.append('x-test', 'world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ 'x-test': 'hello, world' }); + }); - it('Headers with multiple values (not set-cookie)', async () => { - const headers = new Headers(); - headers.append('x-test', 'hello'); - headers.append('x-test', 'world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ 'x-test': 'hello, world' }); - }); + it('Headers with multiple values (set-cookie special case)', async () => { + const headers = new Headers(); + headers.append('set-cookie', 'hello'); + headers.append('set-cookie', 'world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] }); + }); - it('Headers with multiple values (set-cookie special case)', async () => { - const headers = new Headers(); - headers.append('set-cookie', 'hello'); - headers.append('set-cookie', 'world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] }); - }); + it('Headers with multiple values (set-cookie case handling)', async () => { + const headers = new Headers(); + headers.append('Set-cookie', 'hello'); + headers.append('Set-Cookie', 'world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] }); + }); - it('Headers with multiple values (set-cookie case handling)', async () => { - const headers = new Headers(); - headers.append('Set-cookie', 'hello'); - headers.append('Set-Cookie', 'world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ 'set-cookie': ['hello', 'world'] }); - }); - - it('Headers with all use cases', async () => { - const headers = new Headers(); - headers.append('x-single', 'single'); - headers.append('x-triple', 'one'); - headers.append('x-triple', 'two'); - headers.append('x-triple', 'three'); - headers.append('Set-cookie', 'hello'); - headers.append('Set-Cookie', 'world'); - const result = createOutgoingHttpHeaders(headers); - expect(result).to.deep.equal({ - 'x-single': 'single', - 'x-triple': 'one, two, three', - 'set-cookie': ['hello', 'world'], - }); - }); - -});
\ No newline at end of file + it('Headers with all use cases', async () => { + const headers = new Headers(); + headers.append('x-single', 'single'); + headers.append('x-triple', 'one'); + headers.append('x-triple', 'two'); + headers.append('x-triple', 'three'); + headers.append('Set-cookie', 'hello'); + headers.append('Set-Cookie', 'world'); + const result = createOutgoingHttpHeaders(headers); + expect(result).to.deep.equal({ + 'x-single': 'single', + 'x-triple': 'one, two, three', + 'set-cookie': ['hello', 'world'], + }); + }); +}); diff --git a/packages/integrations/node/test/headers.test.js.js b/packages/integrations/node/test/headers.test.js.js index 5b453dd56..17cfd3701 100644 --- a/packages/integrations/node/test/headers.test.js.js +++ b/packages/integrations/node/test/headers.test.js.js @@ -3,146 +3,145 @@ import { loadFixture, createRequestAndResponse } from './test-utils.js'; import { expect } from 'chai'; describe('Node Adapter Headers', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/headers/', - output: 'server', - adapter: nodejs({ mode: 'middleware' }), - }); - await fixture.build(); - }); - - it('Endpoint Simple Headers', async () => { - await runTest('/endpoints/simple', { - 'content-type': 'text/plain;charset=utf-8', - 'x-hello': 'world', - }); - }); - - it('Endpoint Astro Single Cookie Header', async () => { - await runTest('/endpoints/astro-cookies-single', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': 'from1=astro1', - }); - }); - - it('Endpoint Astro Multi Cookie Header', async () => { - await runTest('/endpoints/astro-cookies-multi', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': ['from1=astro1', 'from2=astro2'], - }); - }); - - it('Endpoint Response Single Cookie Header', async () => { - await runTest('/endpoints/response-cookies-single', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': 'hello1=world1', - }); - }); - - it('Endpoint Response Multi Cookie Header', async () => { - await runTest('/endpoints/response-cookies-multi', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': ['hello1=world1', 'hello2=world2'], - }); - }); - - it('Endpoint Complex Headers Kitchen Sink', async () => { - await runTest('/endpoints/kitchen-sink', { - 'content-type': 'text/plain;charset=utf-8', - 'x-single': 'single', - 'x-triple': 'one, two, three', - 'set-cookie': ['hello1=world1', 'hello2=world2'], - }); - }); - - it('Endpoint Astro and Response Single Cookie Header', async () => { - await runTest('/endpoints/astro-response-cookie-single', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': ['from1=response1', 'from1=astro1'], - }); - }); - - it('Endpoint Astro and Response Multi Cookie Header', async () => { - await runTest('/endpoints/astro-response-cookie-multi', { - 'content-type': 'text/plain;charset=utf-8', - 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'], - }); - }); - - it('Endpoint Response Empty Headers Object', async () => { - await runTest('/endpoints/response-empty-headers-object', { - 'content-type': 'text/plain;charset=UTF-8', - }); - }); - - it('Endpoint Response undefined Headers Object', async () => { - await runTest('/endpoints/response-undefined-headers-object', { - 'content-type': 'text/plain;charset=UTF-8', - }); - }); - - it('Component Astro Single Cookie Header', async () => { - await runTest('/astro/component-astro-cookies-single', { - 'content-type': 'text/html', - 'set-cookie': 'from1=astro1', - }); - }); - - it('Component Astro Multi Cookie Header', async () => { - await runTest('/astro/component-astro-cookies-multi', { - 'content-type': 'text/html', - 'set-cookie': ['from1=astro1', 'from2=astro2'], - }); - }); - - it('Component Response Single Cookie Header', async () => { - await runTest('/astro/component-response-cookies-single', { - 'content-type': 'text/html', - 'set-cookie': 'from1=value1', - }); - }); - - it('Component Response Multi Cookie Header', async () => { - await runTest('/astro/component-response-cookies-multi', { - 'content-type': 'text/html', - 'set-cookie': ['from1=value1', 'from2=value2'], - }); - }); - - it('Component Astro and Response Single Cookie Header', async () => { - await runTest('/astro/component-astro-response-cookie-single', { - 'content-type': 'text/html', - 'set-cookie': ['from1=response1', 'from1=astro1'], - }); - }); - - it('Component Astro and Response Multi Cookie Header', async () => { - await runTest('/astro/component-astro-response-cookie-multi', { - 'content-type': 'text/html', - 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'], - }); - }); - + /** @type {import('./test-utils').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/headers/', + output: 'server', + adapter: nodejs({ mode: 'middleware' }), + }); + await fixture.build(); + }); + + it('Endpoint Simple Headers', async () => { + await runTest('/endpoints/simple', { + 'content-type': 'text/plain;charset=utf-8', + 'x-hello': 'world', + }); + }); + + it('Endpoint Astro Single Cookie Header', async () => { + await runTest('/endpoints/astro-cookies-single', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': 'from1=astro1', + }); + }); + + it('Endpoint Astro Multi Cookie Header', async () => { + await runTest('/endpoints/astro-cookies-multi', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': ['from1=astro1', 'from2=astro2'], + }); + }); + + it('Endpoint Response Single Cookie Header', async () => { + await runTest('/endpoints/response-cookies-single', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': 'hello1=world1', + }); + }); + + it('Endpoint Response Multi Cookie Header', async () => { + await runTest('/endpoints/response-cookies-multi', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': ['hello1=world1', 'hello2=world2'], + }); + }); + + it('Endpoint Complex Headers Kitchen Sink', async () => { + await runTest('/endpoints/kitchen-sink', { + 'content-type': 'text/plain;charset=utf-8', + 'x-single': 'single', + 'x-triple': 'one, two, three', + 'set-cookie': ['hello1=world1', 'hello2=world2'], + }); + }); + + it('Endpoint Astro and Response Single Cookie Header', async () => { + await runTest('/endpoints/astro-response-cookie-single', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': ['from1=response1', 'from1=astro1'], + }); + }); + + it('Endpoint Astro and Response Multi Cookie Header', async () => { + await runTest('/endpoints/astro-response-cookie-multi', { + 'content-type': 'text/plain;charset=utf-8', + 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'], + }); + }); + + it('Endpoint Response Empty Headers Object', async () => { + await runTest('/endpoints/response-empty-headers-object', { + 'content-type': 'text/plain;charset=UTF-8', + }); + }); + + it('Endpoint Response undefined Headers Object', async () => { + await runTest('/endpoints/response-undefined-headers-object', { + 'content-type': 'text/plain;charset=UTF-8', + }); + }); + + it('Component Astro Single Cookie Header', async () => { + await runTest('/astro/component-astro-cookies-single', { + 'content-type': 'text/html', + 'set-cookie': 'from1=astro1', + }); + }); + + it('Component Astro Multi Cookie Header', async () => { + await runTest('/astro/component-astro-cookies-multi', { + 'content-type': 'text/html', + 'set-cookie': ['from1=astro1', 'from2=astro2'], + }); + }); + + it('Component Response Single Cookie Header', async () => { + await runTest('/astro/component-response-cookies-single', { + 'content-type': 'text/html', + 'set-cookie': 'from1=value1', + }); + }); + + it('Component Response Multi Cookie Header', async () => { + await runTest('/astro/component-response-cookies-multi', { + 'content-type': 'text/html', + 'set-cookie': ['from1=value1', 'from2=value2'], + }); + }); + + it('Component Astro and Response Single Cookie Header', async () => { + await runTest('/astro/component-astro-response-cookie-single', { + 'content-type': 'text/html', + 'set-cookie': ['from1=response1', 'from1=astro1'], + }); + }); + + it('Component Astro and Response Multi Cookie Header', async () => { + await runTest('/astro/component-astro-response-cookie-multi', { + 'content-type': 'text/html', + 'set-cookie': ['from1=response1', 'from2=response2', 'from3=astro1', 'from4=astro2'], + }); + }); }); async function runTest(url, expectedHeaders) { - const { handler } = await import('./fixtures/headers/dist/server/entry.mjs'); + const { handler } = await import('./fixtures/headers/dist/server/entry.mjs'); - let { req, res, done } = createRequestAndResponse({ - method: 'GET', - url, - }); + let { req, res, done } = createRequestAndResponse({ + method: 'GET', + url, + }); - handler(req, res); + handler(req, res); - req.send(); + req.send(); - await done; - const headers = res.getHeaders(); + await done; + const headers = res.getHeaders(); - expect(headers).to.deep.equal(expectedHeaders); -}
\ No newline at end of file + expect(headers).to.deep.equal(expectedHeaders); +} |