diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2620ffbc504..60638805143 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -50,4 +50,4 @@ deprecations (removed features) here --> - [ ] In review - [ ] Merge ready -[cert]: https://github.com/nodejs/undici/blob/main/CONTRIBUTING.md +[cert]: https://github.com/nodejs/undici/blob/main/CONTRIBUTING.md#developers-certificate-of-origin diff --git a/docs/docs/api/Agent.md b/docs/docs/api/Agent.md index 43b8d30ff5c..5141ce3d3a7 100644 --- a/docs/docs/api/Agent.md +++ b/docs/docs/api/Agent.md @@ -2,7 +2,7 @@ Extends: `undici.Dispatcher` -Agent allow dispatching requests against multiple different origins. +Agent allows dispatching requests against multiple different origins. Requests are not guaranteed to be dispatched in order of invocation. diff --git a/lib/core/util.js b/lib/core/util.js index 71071aff47f..c7e1f16135a 100644 --- a/lib/core/util.js +++ b/lib/core/util.js @@ -13,7 +13,7 @@ const { InvalidArgumentError } = require('./errors') const { headerNameLowerCasedRecord } = require('./constants') const { tree } = require('./tree') -const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v)) +const [nodeMajor, nodeMinor] = process.versions.node.split('.', 2).map(v => Number(v)) class BodyAsyncIterable { constructor (body) { diff --git a/lib/handler/cache-revalidation-handler.js b/lib/handler/cache-revalidation-handler.js index 9672936d9de..393d16d52c6 100644 --- a/lib/handler/cache-revalidation-handler.js +++ b/lib/handler/cache-revalidation-handler.js @@ -9,7 +9,7 @@ const assert = require('node:assert') * here, which we then just pass on to the next handler (most likely a * CacheHandler). Note that this assumes the proper headers were already * included in the request to tell the origin that we want to revalidate the - * response (i.e. if-modified-since). + * response (i.e. if-modified-since or if-none-match). * * @see https://www.rfc-editor.org/rfc/rfc9111.html#name-validation * diff --git a/lib/interceptor/cache.js b/lib/interceptor/cache.js index 6d1225680e7..295c566f255 100644 --- a/lib/interceptor/cache.js +++ b/lib/interceptor/cache.js @@ -6,7 +6,7 @@ const util = require('../core/util') const CacheHandler = require('../handler/cache-handler') const MemoryCacheStore = require('../cache/memory-cache-store') const CacheRevalidationHandler = require('../handler/cache-revalidation-handler') -const { assertCacheStore, assertCacheMethods, makeCacheKey, parseCacheControlHeader } = require('../util/cache.js') +const { assertCacheStore, assertCacheMethods, makeCacheKey, normaliseHeaders, parseCacheControlHeader } = require('../util/cache.js') const { AbortError } = require('../core/errors.js') /** @@ -221,7 +221,7 @@ function handleResult ( // Check if the response is stale if (needsRevalidation(result, reqCacheControl)) { if (util.isStream(opts.body) && util.bodyLength(opts.body) !== 0) { - // If body is is stream we can't revalidate... + // If body is a stream we can't revalidate... // TODO (fix): This could be less strict... return dispatch(opts, new CacheHandler(globalOpts, cacheKey, handler)) } @@ -233,7 +233,7 @@ function handleResult ( } let headers = { - ...opts.headers, + ...normaliseHeaders(opts), 'if-modified-since': new Date(result.cachedAt).toUTCString() } diff --git a/lib/mock/mock-utils.js b/lib/mock/mock-utils.js index 7e79d88c507..a41825459a4 100644 --- a/lib/mock/mock-utils.js +++ b/lib/mock/mock-utils.js @@ -97,7 +97,7 @@ function safeUrl (path) { return path } - const pathSegments = path.split('?') + const pathSegments = path.split('?', 3) if (pathSegments.length !== 2) { return path diff --git a/lib/util/cache.js b/lib/util/cache.js index 41d1c1b7656..17039709bb9 100644 --- a/lib/util/cache.js +++ b/lib/util/cache.js @@ -12,7 +12,21 @@ function makeCacheKey (opts) { throw new Error('opts.origin is undefined') } - /** @type {Record} */ + const headers = normaliseHeaders(opts) + + return { + origin: opts.origin.toString(), + method: opts.method, + path: opts.path, + headers + } +} + +/** + * @param {Record} + * @return {Record} + */ +function normaliseHeaders (opts) { let headers if (opts.headers == null) { headers = {} @@ -38,12 +52,7 @@ function makeCacheKey (opts) { throw new Error('opts.headers is not an object') } - return { - origin: opts.origin.toString(), - method: opts.method, - path: opts.path, - headers - } + return headers } /** @@ -350,6 +359,7 @@ function assertCacheMethods (methods, name = 'CacheMethods') { module.exports = { makeCacheKey, + normaliseHeaders, assertCacheKey, assertCacheValue, parseCacheControlHeader, diff --git a/lib/web/fetch/index.js b/lib/web/fetch/index.js index 38bcfd3dfc2..645fa197d73 100644 --- a/lib/web/fetch/index.js +++ b/lib/web/fetch/index.js @@ -309,7 +309,9 @@ function finalizeAndReportTiming (response, initiatorType = 'other') { originalURL.href, initiatorType, globalThis, - cacheState + cacheState, + '', // bodyType + response.status ) } @@ -994,7 +996,7 @@ function fetchFinale (fetchParams, response) { // 3. Set fetchParams’s controller’s report timing steps to the following steps given a global object global: fetchParams.controller.reportTimingSteps = () => { // 1. If fetchParams’s request’s URL’s scheme is not an HTTP(S) scheme, then return. - if (fetchParams.request.url.protocol !== 'https:') { + if (!urlIsHttpHttpsScheme(fetchParams.request.url)) { return } @@ -1036,7 +1038,6 @@ function fetchFinale (fetchParams, response) { // fetchParams’s request’s URL, fetchParams’s request’s initiator type, global, cacheState, bodyInfo, // and responseStatus. if (fetchParams.request.initiatorType != null) { - // TODO: update markresourcetiming markResourceTiming(timingInfo, fetchParams.request.url.href, fetchParams.request.initiatorType, globalThis, cacheState, bodyInfo, responseStatus) } } diff --git a/lib/web/websocket/util.js b/lib/web/websocket/util.js index 3e9c5479043..ae8f076c0fb 100644 --- a/lib/web/websocket/util.js +++ b/lib/web/websocket/util.js @@ -206,7 +206,7 @@ function parseExtensions (extensions) { while (position.position < extensions.length) { const pair = collectASequenceOfCodePointsFast(';', extensions, position) - const [name, value = ''] = pair.split('=') + const [name, value = ''] = pair.split('=', 2) extensionList.set( removeHTTPWhitespace(name, true, false), diff --git a/package.json b/package.json index ea6856b8b1e..9c04f804d25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "undici", - "version": "7.5.0", + "version": "7.6.0", "description": "An HTTP/1.1 client, written from scratch for Node.js", "homepage": "https://undici.nodejs.org", "bugs": { @@ -108,7 +108,7 @@ }, "devDependencies": { "@fastify/busboy": "3.1.1", - "@matteo.collina/tspl": "^0.1.1", + "@matteo.collina/tspl": "^0.2.0", "@sinonjs/fake-timers": "^12.0.0", "@types/node": "^18.19.50", "abort-controller": "^3.0.0", diff --git a/test/client-connect.js b/test/client-connect.js index 72e575035ef..7d9e561f242 100644 --- a/test/client-connect.js +++ b/test/client-connect.js @@ -13,7 +13,7 @@ test('connect aborted after connect', async (t) => { t = tspl(t, { plan: 3 }) const signal = new EE() - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail() }) server.on('connect', (req, c, firstBodyChunk) => { diff --git a/test/client-head-reset-override.js b/test/client-head-reset-override.js index 4582aa0a79c..d38e2991b8f 100644 --- a/test/client-head-reset-override.js +++ b/test/client-head-reset-override.js @@ -10,7 +10,7 @@ test('override HEAD reset', async (t) => { t = tspl(t, { plan: 4 }) const expected = 'testing123' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.method === 'GET') { res.write(expected) } diff --git a/test/client-idempotent-body.js b/test/client-idempotent-body.js index 6f40efdd9e0..434fe52f0db 100644 --- a/test/client-idempotent-body.js +++ b/test/client-idempotent-body.js @@ -9,7 +9,7 @@ test('idempotent retry', async (t) => { t = tspl(t, { plan: 11 }) const body = 'world' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { let buf = '' req.on('data', data => { buf += data diff --git a/test/client-keep-alive.js b/test/client-keep-alive.js index f00e4d8a128..e91f2ae0a0e 100644 --- a/test/client-keep-alive.js +++ b/test/client-keep-alive.js @@ -341,7 +341,7 @@ test('Disable keep alive', async (t) => { t = tspl(t, { plan: 7 }) const ports = [] - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(ports.includes(req.socket.remotePort), false) ports.push(req.socket.remotePort) t.strictEqual(req.headers.connection, 'close') diff --git a/test/client-node-max-header-size.js b/test/client-node-max-header-size.js index 2d1d8cbbcf2..d4461c35a1e 100644 --- a/test/client-node-max-header-size.js +++ b/test/client-node-max-header-size.js @@ -10,7 +10,7 @@ describe("Node.js' --max-http-header-size cli option", () => { let server before(async () => { - server = createServer((req, res) => { + server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Length': 2 }) diff --git a/test/client-pipeline.js b/test/client-pipeline.js index bc2cd1d3a95..ec471a44b50 100644 --- a/test/client-pipeline.js +++ b/test/client-pipeline.js @@ -16,7 +16,7 @@ const { test('pipeline get', async (t) => { t = tspl(t, { plan: 17 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -75,7 +75,7 @@ test('pipeline get', async (t) => { test('pipeline echo', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -124,7 +124,7 @@ test('pipeline ignore request body', async (t) => { t = tspl(t, { plan: 2 }) let done - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') res.end() done() @@ -185,7 +185,7 @@ test('pipeline invalid handler', async (t) => { test('pipeline invalid handler return after destroy should not error', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -221,7 +221,7 @@ test('pipeline invalid handler return after destroy should not error', async (t) test('pipeline error body', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -263,7 +263,7 @@ test('pipeline error body', async (t) => { test('pipeline destroy body', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -305,7 +305,7 @@ test('pipeline destroy body', async (t) => { test('pipeline backpressure', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -340,7 +340,7 @@ test('pipeline backpressure', async (t) => { test('pipeline invalid handler return', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -381,7 +381,7 @@ test('pipeline invalid handler return', async (t) => { test('pipeline throw handler', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -410,7 +410,7 @@ test('pipeline throw handler', async (t) => { test('pipeline destroy and throw handler', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -444,7 +444,7 @@ test('pipeline abort res', async (t) => { t = tspl(t, { plan: 2 }) let _res - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') _res = res }) @@ -483,7 +483,7 @@ test('pipeline abort res', async (t) => { test('pipeline abort server res', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) after(() => server.close()) @@ -510,7 +510,7 @@ test('pipeline abort server res', async (t) => { test('pipeline abort duplex', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -543,7 +543,7 @@ test('pipeline abort duplex', async (t) => { test('pipeline abort piped res', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') }) after(() => server.close()) @@ -574,7 +574,7 @@ test('pipeline abort piped res', async (t) => { test('pipeline abort piped res 2', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') }) after(() => server.close()) @@ -609,7 +609,7 @@ test('pipeline abort piped res 2', async (t) => { test('pipeline abort piped res 3', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') }) after(() => server.close()) @@ -645,7 +645,7 @@ test('pipeline abort server res after headers', async (t) => { t = tspl(t, { plan: 1 }) let _res - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') _res = res }) @@ -675,7 +675,7 @@ test('pipeline w/ write abort server res after headers', async (t) => { t = tspl(t, { plan: 1 }) let _res - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) _res = res }) @@ -706,7 +706,7 @@ test('destroy in push', async (t) => { t = tspl(t, { plan: 3 }) let _res - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') _res = res }) @@ -763,7 +763,7 @@ test('pipeline args validation', async (t) => { test('pipeline factory throw not unhandled', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') }) after(() => server.close()) @@ -790,7 +790,7 @@ test('pipeline factory throw not unhandled', async (t) => { test('pipeline destroy before dispatch', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) after(() => server.close()) @@ -816,7 +816,7 @@ test('pipeline destroy before dispatch', async (t) => { test('pipeline legacy stream', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write(Buffer.alloc(16e3)) setImmediate(() => { res.end(Buffer.alloc(16e3)) @@ -847,7 +847,7 @@ test('pipeline legacy stream', async (t) => { test('pipeline objectMode', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify({ asd: 1 })) }) after(() => server.close()) @@ -877,7 +877,7 @@ test('pipeline objectMode', async (t) => { test('pipeline invalid opts', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify({ asd: 1 })) }) after(() => server.close()) @@ -904,7 +904,7 @@ test('pipeline invalid opts', async (t) => { test('pipeline CONNECT throw', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -932,7 +932,7 @@ test('pipeline CONNECT throw', async (t) => { test('pipeline body without destroy', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -962,7 +962,7 @@ test('pipeline body without destroy', async (t) => { test('pipeline ignore 1xx', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end('hello') }) @@ -993,7 +993,7 @@ test('pipeline ignore 1xx and use onInfo', async (t) => { t = tspl(t, { plan: 3 }) const infos = [] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end('hello') }) @@ -1030,7 +1030,7 @@ test('pipeline backpressure', async (t) => { const expected = Buffer.alloc(1e6).toString() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end(expected) }) @@ -1068,7 +1068,7 @@ test('pipeline backpressure', async (t) => { test('pipeline abort after headers', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.write('asd') setImmediate(() => { diff --git a/test/client-pipelining.js b/test/client-pipelining.js index b62357f03e0..9e1281b53a3 100644 --- a/test/client-pipelining.js +++ b/test/client-pipelining.js @@ -16,7 +16,7 @@ test('20 times GET with pipelining 10', async (t) => { let count = 0 let countGreaterThanOne = false - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { count++ setTimeout(function () { countGreaterThanOne = countGreaterThanOne || count > 1 @@ -83,7 +83,7 @@ test('A client should enqueue as much as twice its pipelining factor', async (t) let count = 0 let countGreaterThanOne = false - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { count++ t.ok(count <= 5) setTimeout(function () { @@ -137,7 +137,7 @@ test('pipeline 1 is 1 active request', async (t) => { t = tspl(t, { plan: 9 }) let res2 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') res2 = res }) @@ -185,7 +185,7 @@ test('pipelined chunked POST stream', async (t) => { let a = 0 let b = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', chunk => { // Make sure a and b don't interleave. t.ok(a === 9 || b === 0) @@ -254,7 +254,7 @@ test('pipelined chunked POST iterator', async (t) => { let a = 0 let b = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', chunk => { // Make sure a and b don't interleave. t.ok(a === 9 || b === 0) @@ -322,7 +322,7 @@ function errordInflightPost (bodyType) { t = tspl(t, { plan: 6 }) let serverRes - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { serverRes = res res.write('asd') @@ -380,7 +380,7 @@ errordInflightPost(consts.ASYNC_ITERATOR) test('pipelining non-idempotent', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { setTimeout(() => { res.end('asd') @@ -426,7 +426,7 @@ function pipeliningNonIdempotentWithBody (bodyType) { test(`pipelining non-idempotent w body ${bodyType}`, async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { setImmediate(() => { res.end('asd') @@ -489,7 +489,7 @@ function pipeliningHeadBusy (bodyType) { test(`pipelining HEAD busy ${bodyType}`, async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end('asd') }) @@ -561,7 +561,7 @@ test('pipelining empty pipeline before reset', async (t) => { t = tspl(t, { plan: 8 }) let c = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { if (c++ === 0) { res.end('asd') @@ -624,7 +624,7 @@ function pipeliningIdempotentBusy (bodyType) { test(`pipelining idempotent busy ${bodyType}`, async (t) => { t = tspl(t, { plan: 12 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end('asd') }) @@ -728,7 +728,7 @@ pipeliningIdempotentBusy(consts.ASYNC_ITERATOR) test('pipelining blocked', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let blocking = true let count = 0 diff --git a/test/client-post.js b/test/client-post.js index e666faf0714..375f9c54b61 100644 --- a/test/client-post.js +++ b/test/client-post.js @@ -10,7 +10,7 @@ const { Blob } = require('node:buffer') test('request post blob', { skip: !Blob }, async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { t.strictEqual(req.headers['content-type'], 'application/json') let str = '' for await (const chunk of req) { @@ -46,7 +46,7 @@ test('request post blob', { skip: !Blob }, async (t) => { test('request post arrayBuffer', { skip: !Blob }, async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let str = '' for await (const chunk of req) { str += chunk diff --git a/test/client-reconnect.js b/test/client-reconnect.js index 222922a5ea0..7a1725da2b0 100644 --- a/test/client-reconnect.js +++ b/test/client-reconnect.js @@ -21,7 +21,7 @@ test('multiple reconnect', async (t) => { Object.assign(timers, orgTimers) }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { n === 0 ? res.destroy() : res.end('ok') }) after(() => server.close()) diff --git a/test/client-request.js b/test/client-request.js index 9712820b3a3..295d953ba7f 100644 --- a/test/client-request.js +++ b/test/client-request.js @@ -17,7 +17,7 @@ const { parseFormDataString } = require('./utils/formdata') test('request dump head', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-length', 5 * 100) res.flushHeaders() res.write('hello'.repeat(100)) @@ -50,7 +50,7 @@ test('request dump head', async (t) => { test('request dump big', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-length', 999999999) while (res.write('asd')) { // Do nothing... @@ -85,7 +85,7 @@ test('request dump big', async (t) => { test('request dump', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.shouldKeepAlive = false res.setHeader('content-length', 5) res.end('hello') @@ -117,7 +117,7 @@ test('request dump', async (t) => { test('request dump with abort signal', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('hello') }) after(() => server.close()) @@ -145,7 +145,7 @@ test('request dump with abort signal', async (t) => { test('request hwm', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('hello') }) after(() => server.close()) @@ -172,7 +172,7 @@ test('request abort before headers', async (t) => { t = tspl(t, { plan: 6 }) const signal = new EE() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') signal.emit('abort') }) @@ -211,7 +211,7 @@ test('request abort before headers', async (t) => { test('request body destroyed on invalid callback', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -239,7 +239,7 @@ test('request body destroyed on invalid callback', async (t) => { test('trailers', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Trailer: 'Content-MD5' }) res.addTrailers({ 'Content-MD5': 'test' }) res.end() @@ -268,7 +268,7 @@ test('trailers', async (t) => { test('destroy socket abruptly', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { const lines = [ 'HTTP/1.1 200 OK', 'Date: Sat, 09 Oct 2010 14:28:02 GMT', @@ -309,7 +309,7 @@ test('destroy socket abruptly', async (t) => { test('destroy socket abruptly with keep-alive', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { const lines = [ 'HTTP/1.1 200 OK', 'Date: Sat, 09 Oct 2010 14:28:02 GMT', @@ -355,7 +355,7 @@ test('request json', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -378,7 +378,7 @@ test('request long multibyte json', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: 'あ'.repeat(100000) } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -401,7 +401,7 @@ test('request text', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -484,7 +484,7 @@ describe('headers', () => { describe('array', () => { let serverAddress - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(req.headers)) }) @@ -524,7 +524,7 @@ describe('headers', () => { describe('host', () => { let serverAddress - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.headers.host) }) @@ -583,7 +583,7 @@ test('request long multibyte text', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: 'あ'.repeat(100000) } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -606,7 +606,7 @@ test('request blob', async (t) => { t = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify(obj)) }) @@ -633,7 +633,7 @@ test('request arrayBuffer', async (t) => { t = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -659,7 +659,7 @@ test('request bytes', async (t) => { t = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -685,7 +685,7 @@ test('request body', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -712,7 +712,7 @@ test('request body', async (t) => { test('request post body no missing data', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -747,7 +747,7 @@ test('request post body no missing data', async (t) => { test('request post body no extra data handler', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -786,7 +786,7 @@ test('request post body no extra data handler', async (t) => { test('request with onInfo callback', async (t) => { t = tspl(t, { plan: 3 }) const infos = [] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ foo: 'bar' })) @@ -814,7 +814,7 @@ test('request with onInfo callback but socket is destroyed before end of respons t = tspl(t, { plan: 5 }) const infos = [] let response - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { response = res res.writeProcessing() }) @@ -849,7 +849,7 @@ test('request onInfo callback headers parsing', async (t) => { t = tspl(t, { plan: 4 }) const infos = [] - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { const lines = [ 'HTTP/1.1 103 Early Hints', 'Link: ; rel=preload; as=style', @@ -885,7 +885,7 @@ test('request raw responseHeaders', async (t) => { t = tspl(t, { plan: 4 }) const infos = [] - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { const lines = [ 'HTTP/1.1 103 Early Hints', 'Link: ; rel=preload; as=style', @@ -922,7 +922,7 @@ test('request formData', async (t) => { t = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -951,7 +951,7 @@ test('request text2', async (t) => { t = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) after(() => server.close()) @@ -985,7 +985,7 @@ test('request with FormData body', async (t) => { fd.set('key', 'value') fd.set('file', new Blob(['Hello, world!']), 'hello_world.txt') - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { const contentType = req.headers['content-type'] // ensure we received a multipart/form-data header t.ok(/^multipart\/form-data; boundary=-+formdata-undici-0\d+$/.test(contentType)) @@ -1034,7 +1034,7 @@ test('request post body Buffer from string', async (t) => { t = tspl(t, { plan: 2 }) const requestBody = Buffer.from('abcdefghijklmnopqrstuvwxyz') - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1066,7 +1066,7 @@ test('request post body Buffer from buffer', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = Buffer.from(fullBuffer.buffer, 8, 16) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1098,7 +1098,7 @@ test('request post body Uint8Array', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = new Uint8Array(fullBuffer.buffer, 8, 16) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1130,7 +1130,7 @@ test('request post body Uint32Array', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = new Uint32Array(fullBuffer.buffer, 8, 4) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1162,7 +1162,7 @@ test('request post body Float64Array', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = new Float64Array(fullBuffer.buffer, 8, 2) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1194,7 +1194,7 @@ test('request post body BigUint64Array', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = new BigUint64Array(fullBuffer.buffer, 8, 2) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1226,7 +1226,7 @@ test('request post body DataView', async (t) => { const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz') const requestBody = new DataView(fullBuffer.buffer, 8, 16) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let ret = '' for await (const chunk of req) { ret += chunk @@ -1258,7 +1258,7 @@ test('request multibyte json with setEncoding', async (t) => { const asd = Buffer.from('あいうえお') const data = JSON.stringify({ asd }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write(data.slice(0, 1)) setTimeout(() => { res.write(data.slice(1)) @@ -1286,7 +1286,7 @@ test('request multibyte text with setEncoding', async (t) => { t = tspl(t, { plan: 1 }) const data = Buffer.from('あいうえお') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write(data.slice(0, 1)) setTimeout(() => { res.write(data.slice(1)) @@ -1314,7 +1314,7 @@ test('request multibyte text with setEncoding', async (t) => { t = tspl(t, { plan: 1 }) const data = Buffer.from('あいうえお') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write(data.slice(0, 1)) setTimeout(() => { res.write(data.slice(1)) @@ -1342,7 +1342,7 @@ test('#3736 - Aborted Response (without consuming body)', async (t) => { const plan = tspl(t, { plan: 1 }) const controller = new AbortController() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.writeHead(200, 'ok', { 'content-type': 'text/plain' diff --git a/test/client-stream.js b/test/client-stream.js index ccdbedf1b09..8428ae990db 100644 --- a/test/client-stream.js +++ b/test/client-stream.js @@ -10,7 +10,7 @@ const EE = require('node:events') test('stream get', async (t) => { t = tspl(t, { plan: 9 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -53,7 +53,7 @@ test('stream get', async (t) => { test('stream promise get', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -90,7 +90,7 @@ test('stream promise get', async (t) => { test('stream GET destroy res', async (t) => { t = tspl(t, { plan: 14 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -150,7 +150,7 @@ test('stream GET destroy res', async (t) => { test('stream GET remote destroy', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') setImmediate(() => { res.destroy() @@ -195,7 +195,7 @@ test('stream GET remote destroy', async (t) => { test('stream response resume back pressure and non standard error', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write(Buffer.alloc(1e3)) setImmediate(() => { res.write(Buffer.alloc(1e7)) @@ -246,7 +246,7 @@ test('stream response resume back pressure and non standard error', async (t) => test('stream waits only for writable side', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(Buffer.alloc(1e3)) }) after(() => server.close()) @@ -311,7 +311,7 @@ test('stream args validation promise', async (t) => { test('stream destroy if not readable', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -339,7 +339,7 @@ test('stream destroy if not readable', async (t) => { test('stream server side destroy', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) after(() => server.close()) @@ -364,7 +364,7 @@ test('stream server side destroy', async (t) => { test('stream invalid return', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') }) after(() => server.close()) @@ -389,7 +389,7 @@ test('stream invalid return', async (t) => { test('stream body without destroy', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -417,7 +417,7 @@ test('stream body without destroy', async (t) => { test('stream factory abort', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -447,7 +447,7 @@ test('stream factory abort', async (t) => { test('stream factory throw', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -488,7 +488,7 @@ test('stream factory throw', async (t) => { test('stream CONNECT throw', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -512,7 +512,7 @@ test('stream CONNECT throw', async (t) => { test('stream abort after complete', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -541,7 +541,7 @@ test('stream abort after complete', async (t) => { test('stream abort before dispatch', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -570,7 +570,7 @@ test('stream abort before dispatch', async (t) => { test('trailers', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Trailer: 'Content-MD5' }) res.addTrailers({ 'Content-MD5': 'test' }) res.end() @@ -596,7 +596,7 @@ test('trailers', async (t) => { test('stream ignore 1xx', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end('hello') }) @@ -628,7 +628,7 @@ test('stream ignore 1xx and use onInfo', async (t) => { t = tspl(t, { plan: 4 }) const infos = [] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end('hello') }) @@ -666,7 +666,7 @@ test('stream backpressure', async (t) => { const expected = Buffer.alloc(1e6).toString() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() res.end(expected) }) @@ -698,7 +698,7 @@ test('stream backpressure', async (t) => { test('stream body destroyed on invalid callback', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -726,7 +726,7 @@ test('stream body destroyed on invalid callback', async (t) => { test('stream needDrain', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(Buffer.alloc(4096)) }) after(() => server.close()) @@ -782,7 +782,7 @@ test('stream needDrain', async (t) => { test('stream legacy needDrain', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(Buffer.alloc(4096)) }) after(() => server.close()) diff --git a/test/client-timeout.js b/test/client-timeout.js index c4ff9c2a59c..26cf21913c2 100644 --- a/test/client-timeout.js +++ b/test/client-timeout.js @@ -11,7 +11,7 @@ const timers = require('../lib/util/timers') test('refresh timeout on pause', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.flushHeaders() }) after(() => server.close()) @@ -61,7 +61,7 @@ test('start headers timeout after request body', async (t) => { Object.assign(timers, orgTimers) }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -119,7 +119,7 @@ test('start headers timeout after async iterator request body', async (t) => { Object.assign(timers, orgTimers) }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -169,7 +169,7 @@ test('start headers timeout after async iterator request body', async (t) => { test('parser resume with no body timeout', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) diff --git a/test/client-unref.js b/test/client-unref.js index 49df4244e8e..ac25d636a8a 100644 --- a/test/client-unref.js +++ b/test/client-unref.js @@ -11,7 +11,7 @@ if (isMainThread) { test('client automatically closes itself when idle', async t => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(server.close.bind(server)) diff --git a/test/client-upgrade.js b/test/client-upgrade.js index 7d76f8ee148..a1871a96501 100644 --- a/test/client-upgrade.js +++ b/test/client-upgrade.js @@ -11,7 +11,7 @@ const { kBusy } = require('../lib/core/symbols') test('basic upgrade', async (t) => { t = tspl(t, { plan: 6 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { t.ok(/upgrade: websocket/i.test(d)) c.write('HTTP/1.1 101\r\n') @@ -70,7 +70,7 @@ test('basic upgrade', async (t) => { test('basic upgrade promise', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -119,7 +119,7 @@ test('basic upgrade promise', async (t) => { test('upgrade error', async (t) => { t = tspl(t, { plan: 1 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -182,7 +182,7 @@ test('upgrade invalid opts', async (t) => { test('basic upgrade2', async (t) => { t = tspl(t, { plan: 3 }) - const server = http.createServer() + const server = http.createServer({ joinDuplicateHeaders: true }) server.on('upgrade', (req, c, head) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -232,7 +232,7 @@ test('upgrade wait for empty pipeline', async (t) => { t = tspl(t, { plan: 7 }) let canConnect = false - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() canConnect = true }) @@ -299,7 +299,7 @@ test('upgrade wait for empty pipeline', async (t) => { test('upgrade aborted', async (t) => { t = tspl(t, { plan: 6 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail() }) server.on('upgrade', (req, c, firstBodyChunk) => { @@ -339,7 +339,7 @@ test('basic aborted after res', async (t) => { t = tspl(t, { plan: 1 }) const signal = new EE() - const server = http.createServer() + const server = http.createServer({ joinDuplicateHeaders: true }) server.on('upgrade', (req, c, head) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -375,7 +375,7 @@ test('basic aborted after res', async (t) => { test('basic upgrade error', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -445,7 +445,7 @@ test('upgrade disconnect', async (t) => { test('upgrade invalid signal', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer(() => { + const server = net.createServer({ joinDuplicateHeaders: true }, () => { t.fail() }) after(() => server.close()) diff --git a/test/client-write-max-listeners.js b/test/client-write-max-listeners.js index c76ce60b0ab..09ab13cafb8 100644 --- a/test/client-write-max-listeners.js +++ b/test/client-write-max-listeners.js @@ -10,7 +10,7 @@ const { Readable } = require('node:stream') test('socket close listener does not leak', async (t) => { t = tspl(t, { plan: 32 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end('hello') diff --git a/test/client.js b/test/client.js index 680ff66be10..6b031be173a 100644 --- a/test/client.js +++ b/test/client.js @@ -22,7 +22,7 @@ const hasIPv6 = (() => { test('basic get', async (t) => { t = tspl(t, { plan: 24 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -94,7 +94,7 @@ test('basic get', async (t) => { test('basic get with custom request.reset=true', async (t) => { t = tspl(t, { plan: 26 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -167,7 +167,7 @@ test('basic get with custom request.reset=true', async (t) => { test('basic get with query params', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const searchParamsObject = buildParams(req.url) t.deepStrictEqual(searchParamsObject, { bool: 'true', @@ -220,7 +220,7 @@ test('basic get with query params', async (t) => { test('basic get with query params fails if url includes hashmark', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail() }) after(() => server.close()) @@ -254,7 +254,7 @@ test('basic get with query params fails if url includes hashmark', async (t) => test('basic get with empty query params', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const searchParamsObject = buildParams(req.url) t.deepStrictEqual(searchParamsObject, {}) @@ -291,7 +291,7 @@ test('basic get with empty query params', async (t) => { test('basic get with query params partially in path', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail() }) after(() => server.close()) @@ -323,7 +323,7 @@ test('basic get with query params partially in path', async (t) => { test('using throwOnError should throw (request)', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 400 res.end('hello') }) @@ -353,7 +353,7 @@ test('using throwOnError should throw (request)', async (t) => { test('using throwOnError should throw (stream)', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 400 res.end('hello') }) @@ -387,7 +387,7 @@ test('using throwOnError should throw (stream)', async (t) => { test('basic head', async (t) => { t = tspl(t, { plan: 14 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/123', req.url) t.strictEqual('HEAD', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -429,7 +429,7 @@ test('basic head', async (t) => { test('basic head (IPv6)', { skip: !hasIPv6 }, async (t) => { t = tspl(t, { plan: 15 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/123', req.url) t.strictEqual('HEAD', req.method) t.strictEqual(`[::1]:${server.address().port}`, req.headers.host) @@ -471,7 +471,7 @@ test('basic head (IPv6)', { skip: !hasIPv6 }, async (t) => { test('get with host header', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual('example.com', req.headers.host) @@ -504,7 +504,7 @@ test('get with host header', async (t) => { test('get with host header (IPv6)', { skip: !hasIPv6 }, async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual('[::1]', req.headers.host) @@ -537,7 +537,7 @@ test('get with host header (IPv6)', { skip: !hasIPv6 }, async (t) => { test('head with host header', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('HEAD', req.method) t.strictEqual('example.com', req.headers.host) @@ -588,7 +588,7 @@ test('basic POST with string', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, () => { @@ -615,7 +615,7 @@ test('basic POST with string', async (t) => { test('basic POST with empty string', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer(postServer(t, '')) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, '')) after(() => server.close()) server.listen(0, () => { @@ -643,7 +643,7 @@ test('basic POST with string and content-length', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, () => { @@ -678,7 +678,7 @@ test('basic POST with Buffer', async (t) => { const expected = readFileSync(__filename) - const server = createServer(postServer(t, expected.toString())) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected.toString())) after(() => server.close()) server.listen(0, () => { @@ -706,7 +706,7 @@ test('basic POST with stream', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, () => { @@ -742,7 +742,7 @@ test('basic POST with paused stream', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, () => { @@ -778,7 +778,7 @@ test('basic POST with paused stream', async (t) => { test('basic POST with custom stream', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.resume().on('end', () => { res.end('hello') }) @@ -835,7 +835,7 @@ test('basic POST with iterator', async (t) => { const expected = 'hello' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.resume().on('end', () => { res.end(expected) }) @@ -879,7 +879,7 @@ test('basic POST with iterator', async (t) => { test('basic POST with iterator with invalid data', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer(() => {}) + const server = createServer({ joinDuplicateHeaders: true }, () => {}) after(() => server.close()) const iterable = { @@ -910,7 +910,7 @@ test('basic POST with async iterator', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, () => { @@ -945,7 +945,7 @@ test('basic POST with transfer encoding: chunked', async (t) => { t = tspl(t, { plan: 8 }) let body - const server = createServer(function (req, res) { + const server = createServer({ joinDuplicateHeaders: true }, function (req, res) { t.strictEqual(req.url, '/') t.strictEqual(req.method, 'POST') t.strictEqual(req.headers['content-length'], undefined) @@ -997,7 +997,7 @@ test('basic POST with transfer encoding: chunked', async (t) => { test('basic POST with empty stream', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer(function (req, res) { + const server = createServer({ joinDuplicateHeaders: true }, function (req, res) { t.deepStrictEqual(req.headers['content-length'], '0') req.pipe(res) }) @@ -1043,7 +1043,7 @@ test('10 times GET', async (t) => { const num = 10 t = tspl(t, { plan: 3 * num }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) after(() => server.close()) @@ -1078,7 +1078,7 @@ test('10 times HEAD', async (t) => { const num = 10 t = tspl(t, { plan: num * 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) after(() => server.close()) @@ -1110,7 +1110,7 @@ test('10 times HEAD', async (t) => { test('Set-Cookie', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.setHeader('Set-Cookie', ['a cookie', 'another cookie', 'more cookies']) res.end('hello') @@ -1141,7 +1141,7 @@ test('Set-Cookie', async (t) => { test('ignore request header mutations', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers.test, 'test') res.end() }) @@ -1169,7 +1169,7 @@ test('ignore request header mutations', async (t) => { test('url-like url', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -1196,7 +1196,7 @@ test('an absolute url as path', async (t) => { const path = 'http://example.com' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, path) res.end() }) @@ -1222,7 +1222,7 @@ test('an absolute url as path', async (t) => { test('multiple destroy callback', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -1257,7 +1257,7 @@ test('multiple destroy callback', async (t) => { test('only one streaming req at a time', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -1315,7 +1315,7 @@ test('only one streaming req at a time', async (t) => { test('only one async iterating req at a time', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -1371,7 +1371,7 @@ test('only one async iterating req at a time', async (t) => { test('300 requests succeed', async (t) => { t = tspl(t, { plan: 300 * 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -1431,7 +1431,7 @@ test('request args validation promise', async (t) => { test('increase pipelining', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.resume() }) after(() => server.close()) @@ -1478,7 +1478,7 @@ test('destroy in push', async (t) => { t = tspl(t, { plan: 4 }) let _res - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('asd') _res = res }) @@ -1519,7 +1519,7 @@ test('destroy in push', async (t) => { test('non recoverable socket error fails pending request', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -1545,7 +1545,7 @@ test('non recoverable socket error fails pending request', async (t) => { test('POST empty with error', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -1576,7 +1576,7 @@ test('POST empty with error', async (t) => { test('busy', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -1604,7 +1604,7 @@ test('busy', async (t) => { test('connected', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { // needed so that disconnect is emitted res.setHeader('connection', 'close') req.pipe(res) @@ -1645,7 +1645,7 @@ test('connected', async (t) => { test('emit disconnect after destroy', async t => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -1674,7 +1674,7 @@ test('emit disconnect after destroy', async t => { test('end response before request', async t => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -1709,7 +1709,7 @@ test('end response before request', async t => { test('parser pause with no body timeout', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { let counter = 0 const t = setInterval(() => { counter++ @@ -1742,7 +1742,7 @@ test('parser pause with no body timeout', async (t) => { test('TypedArray and DataView body', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers['content-length'], '8') res.end() }) @@ -1768,7 +1768,7 @@ test('TypedArray and DataView body', async (t) => { test('async iterator empty chunk continues', async (t) => { t = tspl(t, { plan: 5 }) const serverChunks = ['hello', 'world'] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { let str = '' let i = 0 req.on('data', (chunk) => { @@ -1805,7 +1805,7 @@ test('async iterator empty chunk continues', async (t) => { test('async iterator error from server destroys early', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', (chunk) => { res.destroy() }) @@ -1843,7 +1843,7 @@ test('async iterator error from server destroys early', async (t) => { test('regular iterator error from server closes early', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', () => { process.nextTick(() => { res.destroy() @@ -1884,7 +1884,7 @@ test('regular iterator error from server closes early', async (t) => { test('async iterator early return closes early', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', () => { res.writeHead(200) res.end() @@ -1924,7 +1924,7 @@ test('async iterator yield unsupported TypedArray', { skip: !!require('stream')._isArrayBufferView }, async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('end', () => { res.writeHead(200) res.end() @@ -1956,7 +1956,7 @@ test('async iterator yield unsupported TypedArray', { test('async iterator yield object error', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('end', () => { res.writeHead(200) res.end() @@ -1988,7 +1988,7 @@ test('async iterator yield object error', async (t) => { test('Successfully get a Response when neither a Transfer-Encoding or Content-Length header is present', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.on('data', (data) => { }) req.on('end', () => { diff --git a/test/close-and-destroy.js b/test/close-and-destroy.js index 5d4f135dcd2..e52c0072553 100644 --- a/test/close-and-destroy.js +++ b/test/close-and-destroy.js @@ -9,7 +9,7 @@ const { kSocket, kSize } = require('../lib/core/symbols') test('close waits for queued requests to finish', async (t) => { t = tspl(t, { plan: 16 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { t.ok(true, 'request received') @@ -54,7 +54,7 @@ test('close waits for queued requests to finish', async (t) => { test('destroy invoked all pending callbacks', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.write('hello') @@ -88,7 +88,7 @@ test('destroy invoked all pending callbacks', async (t) => { test('destroy invoked all pending callbacks ticked', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.write('hello') @@ -120,7 +120,7 @@ test('destroy invoked all pending callbacks ticked', async (t) => { test('close waits until socket is destroyed', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) after(() => server.close()) @@ -157,7 +157,7 @@ test('close waits until socket is destroyed', async (t) => { test('close should still reconnect', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) after(() => server.close()) @@ -192,7 +192,7 @@ test('close should still reconnect', async (t) => { test('close should call callback once finished', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setImmediate(function () { res.end(req.url) }) @@ -266,7 +266,7 @@ test('close after and destroy should error', async (t) => { test('close socket and reconnect after maxRequestsPerClient reached', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) @@ -300,7 +300,7 @@ test('close socket and reconnect after maxRequestsPerClient reached', async (t) test('close socket and reconnect after maxRequestsPerClient reached (async)', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) @@ -336,7 +336,7 @@ test('close socket and reconnect after maxRequestsPerClient reached (async)', as test('should not close socket when no maxRequestsPerClient is provided', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(req.url) }) diff --git a/test/connect-pre-shared-session.js b/test/connect-pre-shared-session.js index 5ee7b308885..c10e3c82a3d 100644 --- a/test/connect-pre-shared-session.js +++ b/test/connect-pre-shared-session.js @@ -12,7 +12,7 @@ test('custom session passed to client will be used in tls connect call', async ( const mockConnect = mock.method(tls, 'connect') - const server = createServer(pem, (req, res) => { + const server = createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') diff --git a/test/content-length.js b/test/content-length.js index ece0747406a..6d8e7799c91 100644 --- a/test/content-length.js +++ b/test/content-length.js @@ -10,7 +10,7 @@ const { maybeWrapStream, consts } = require('./utils/async-iterators') test('request invalid content-length', async (t) => { t = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -103,7 +103,7 @@ function invalidContentLength (bodyType) { test(`request streaming ${bodyType} invalid content-length`, async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -165,7 +165,7 @@ function zeroContentLength (bodyType) { test(`request ${bodyType} streaming data when content-length=0`, async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -201,7 +201,7 @@ zeroContentLength(consts.ASYNC_ITERATOR) test('request streaming no body data when content-length=0', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -233,7 +233,7 @@ test('request streaming no body data when content-length=0', async (t) => { test('response invalid content length with close', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-length': 10 }) @@ -270,7 +270,7 @@ test('response invalid content length with close', async (t) => { }) test('request streaming with Readable.from(buf)', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) after(() => server.close()) @@ -302,7 +302,7 @@ test('request streaming with Readable.from(buf)', async (t) => { test('request DELETE, content-length=0, with body', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.shouldKeepAlive = false res.end() }) @@ -352,7 +352,7 @@ test('request DELETE, content-length=0, with body', async (t) => { test('content-length shouldSendContentLength=false', async (t) => { t = tspl(t, { plan: 15 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) server.on('request', (req, res) => { diff --git a/test/env-http-proxy-agent-nodejs-bundle.js b/test/env-http-proxy-agent-nodejs-bundle.js index 43746a318a5..f9f8d526d10 100644 --- a/test/env-http-proxy-agent-nodejs-bundle.js +++ b/test/env-http-proxy-agent-nodejs-bundle.js @@ -26,13 +26,13 @@ describe('EnvHttpProxyAgent and setGlobalDispatcher', () => { // Instead of using mocks, start a real server and a minimal proxy server // in order to exercise the actual paths in EnvHttpProxyAgent from the // Node.js bundle. - const server = http.createServer((req, res) => { res.end('Hello world') }) + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('Hello world') }) server.on('error', err => { console.log('Server error', err) }) server.listen(0) await once(server, 'listening') t.after(() => { server.close() }) - const proxy = http.createServer() + const proxy = http.createServer({ joinDuplicateHeaders: true }) proxy.on('connect', (req, clientSocket, head) => { // Check that the proxy is actually used to tunnel the request sent below. const [hostname, port] = req.url.split(':') diff --git a/test/eventsource/eventsource-attributes.js b/test/eventsource/eventsource-attributes.js index 0e046affdbd..42465c912c7 100644 --- a/test/eventsource/eventsource-attributes.js +++ b/test/eventsource/eventsource-attributes.js @@ -7,7 +7,7 @@ const { test, describe } = require('node:test') const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - eventhandler idl', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'dummy') }) diff --git a/test/eventsource/eventsource-close.js b/test/eventsource/eventsource-close.js index 5b6397df63a..aef42e95185 100644 --- a/test/eventsource/eventsource-close.js +++ b/test/eventsource/eventsource-close.js @@ -9,7 +9,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - close', () => { test('should not emit error when closing the EventSource Instance', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.connection, 'keep-alive') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('data: hello\n\n') @@ -32,7 +32,7 @@ describe('EventSource - close', () => { }) test('should set readyState to CLOSED', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.connection, 'keep-alive') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('data: hello\n\n') diff --git a/test/eventsource/eventsource-connect.js b/test/eventsource/eventsource-connect.js index 75508ee954d..018032044fa 100644 --- a/test/eventsource/eventsource-connect.js +++ b/test/eventsource/eventsource-connect.js @@ -8,7 +8,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - sending correct request headers', () => { test('should send request with connection keep-alive', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.connection, 'keep-alive') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() @@ -30,7 +30,7 @@ describe('EventSource - sending correct request headers', () => { }) test('should send request with sec-fetch-mode set to cors', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers['sec-fetch-mode'], 'cors') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() @@ -52,7 +52,7 @@ describe('EventSource - sending correct request headers', () => { }) test('should send request with pragma and cache-control set to no-cache', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers['cache-control'], 'no-cache') assert.strictEqual(req.headers.pragma, 'no-cache') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) @@ -75,7 +75,7 @@ describe('EventSource - sending correct request headers', () => { }) test('should send request with accept text/event-stream', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.accept, 'text/event-stream') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() @@ -99,7 +99,7 @@ describe('EventSource - sending correct request headers', () => { describe('EventSource - received response must have content-type to be text/event-stream', () => { test('should send request with accept text/event-stream', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() }) @@ -120,7 +120,7 @@ describe('EventSource - received response must have content-type to be text/even }) test('should send request with accept text/event-stream;', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream;' }) res.end() }) @@ -141,7 +141,7 @@ describe('EventSource - received response must have content-type to be text/even }) test('should handle content-type text/event-stream;charset=UTF-8 properly', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream;charset=UTF-8' }) res.end() }) @@ -162,7 +162,7 @@ describe('EventSource - received response must have content-type to be text/even }) test('should throw if content-type is text/html properly', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/html' }) res.end() }) diff --git a/test/eventsource/eventsource-constructor-stringify.js b/test/eventsource/eventsource-constructor-stringify.js index aee1d02bc6d..a8cd6b14986 100644 --- a/test/eventsource/eventsource-constructor-stringify.js +++ b/test/eventsource/eventsource-constructor-stringify.js @@ -8,7 +8,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - constructor stringify', () => { test('should stringify argument', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.connection, 'keep-alive') res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() diff --git a/test/eventsource/eventsource-constructor.js b/test/eventsource/eventsource-constructor.js index a5e25e3f1dc..49a818e4cce 100644 --- a/test/eventsource/eventsource-constructor.js +++ b/test/eventsource/eventsource-constructor.js @@ -8,7 +8,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - withCredentials', () => { test('withCredentials should be false by default', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() }) @@ -30,7 +30,7 @@ describe('EventSource - withCredentials', () => { }) test('withCredentials can be set to true', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() }) diff --git a/test/eventsource/eventsource-custom-dispatcher.js b/test/eventsource/eventsource-custom-dispatcher.js index e04c2f80673..4a852a56e7b 100644 --- a/test/eventsource/eventsource-custom-dispatcher.js +++ b/test/eventsource/eventsource-custom-dispatcher.js @@ -9,7 +9,7 @@ const { test } = require('node:test') test('EventSource allows setting custom dispatcher.', async (t) => { const { completed, deepStrictEqual } = tspl(t, { plan: 1 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) deepStrictEqual(req.headers['x-customer-header'], 'hello world') diff --git a/test/eventsource/eventsource-message.js b/test/eventsource/eventsource-message.js index d7843bc6891..9de1eae4b43 100644 --- a/test/eventsource/eventsource-message.js +++ b/test/eventsource/eventsource-message.js @@ -20,7 +20,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('retry: 100\n\n') await setTimeout(100) @@ -66,7 +66,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('event:message\n\n') await setTimeout(100) @@ -106,7 +106,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('event:custom\ndata:test\n\n') await setTimeout(100) @@ -143,7 +143,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('data:test\n\n') await setTimeout(100) @@ -180,7 +180,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('data\n\n') await setTimeout(100) @@ -217,7 +217,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('event:custom\ndata:\n\n') await setTimeout(100) @@ -254,7 +254,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('data:\n\n') await setTimeout(100) @@ -291,7 +291,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('event:custom\ndata\n\n') await setTimeout(100) @@ -328,7 +328,7 @@ describe('EventSource - message', () => { finishedPromise.reject = reject }) - const server = http.createServer(async (req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('event:custom\n\n') await setTimeout(100) diff --git a/test/eventsource/eventsource-reconnect.js b/test/eventsource/eventsource-reconnect.js index 50d5f6dadec..8459bb00d69 100644 --- a/test/eventsource/eventsource-reconnect.js +++ b/test/eventsource/eventsource-reconnect.js @@ -19,7 +19,7 @@ describe('EventSource - reconnect', () => { finishedPromise.reject = reject }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() }) @@ -52,7 +52,7 @@ describe('EventSource - reconnect', () => { finishedPromise.reject = reject }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.end() }) @@ -87,7 +87,7 @@ describe('EventSource - reconnect', () => { finishedPromise.reject = reject }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('retry: 100\n\n') res.end() @@ -126,7 +126,7 @@ describe('EventSource - reconnect', () => { finishedPromise.reject = reject }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Type': 'text/event-stream' }) res.write('id: 1337\n\n') if (requestCount++ !== 0) { diff --git a/test/eventsource/eventsource-redirecting.js b/test/eventsource/eventsource-redirecting.js index 07bd36ea790..20bfa983994 100644 --- a/test/eventsource/eventsource-redirecting.js +++ b/test/eventsource/eventsource-redirecting.js @@ -9,7 +9,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - redirecting', () => { [301, 302, 307, 308].forEach((statusCode) => { test(`Should redirect on ${statusCode} status code`, async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { if (res.req.url === '/redirect') { res.writeHead(statusCode, undefined, { Location: '/target' }) res.end() @@ -37,7 +37,7 @@ describe('EventSource - redirecting', () => { }) test('Stop trying to connect when getting a 204 response', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { if (res.req.url === '/redirect') { res.writeHead(301, undefined, { Location: '/target' }) res.end() @@ -63,7 +63,7 @@ describe('EventSource - redirecting', () => { }) test('Throw when missing a Location header', async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { if (res.req.url === '/redirect') { res.writeHead(301, undefined) res.end() @@ -86,7 +86,7 @@ describe('EventSource - redirecting', () => { }) test('Should set origin attribute of messages after redirecting', async () => { - const targetServer = http.createServer((req, res) => { + const targetServer = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { if (res.req.url === '/target') { res.writeHead(200, undefined, { 'Content-Type': 'text/event-stream' }) res.write('event: message\ndata: test\n\n') @@ -96,7 +96,7 @@ describe('EventSource - redirecting', () => { await events.once(targetServer, 'listening') const targetPort = targetServer.address().port - const sourceServer = http.createServer((req, res) => { + const sourceServer = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(301, undefined, { Location: `http://127.0.0.1:${targetPort}/target` }) res.end() }) diff --git a/test/eventsource/eventsource-request-status-error.js b/test/eventsource/eventsource-request-status-error.js index 3b73d22b851..694ae160213 100644 --- a/test/eventsource/eventsource-request-status-error.js +++ b/test/eventsource/eventsource-request-status-error.js @@ -9,7 +9,7 @@ const { EventSource } = require('../../lib/web/eventsource/eventsource') describe('EventSource - status error', () => { [204, 205, 210, 299, 404, 410, 503].forEach((statusCode) => { test(`Should error on ${statusCode} status code`, async () => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(statusCode, 'dummy', { 'Content-Type': 'text/event-stream' }) res.end() }) diff --git a/test/examples.js b/test/examples.js index e06b2d4ddb8..055f082b3fd 100644 --- a/test/examples.js +++ b/test/examples.js @@ -10,7 +10,7 @@ test('request examples', async (t) => { t = tspl(t, { plan: 7 }) let lastReq - const exampleServer = createServer((req, res) => { + const exampleServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { lastReq = req if (req.method === 'DELETE') { res.statusCode = 204 @@ -29,7 +29,7 @@ test('request examples', async (t) => { } }) - const errorServer = createServer((req, res) => { + const errorServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { lastReq = req res.statusCode = 400 res.setHeader('content-type', 'application/json') diff --git a/test/fetch/407-statuscode-window-null.js b/test/fetch/407-statuscode-window-null.js index e03042e4c09..26e763c59dc 100644 --- a/test/fetch/407-statuscode-window-null.js +++ b/test/fetch/407-statuscode-window-null.js @@ -9,7 +9,7 @@ const assert = require('node:assert') const { closeServerAsPromise } = require('../utils/node-http') test('Receiving a 407 status code w/ a window option present should reject', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 407 res.end() }).listen(0) diff --git a/test/fetch/abort.js b/test/fetch/abort.js index 73b4764fe81..8f4a1f321b6 100644 --- a/test/fetch/abort.js +++ b/test/fetch/abort.js @@ -9,7 +9,7 @@ const { once } = require('node:events') const { closeServerAsPromise } = require('../utils/node-http') test('allows aborting with custom errors', async (t) => { - const server = createServer().listen(0) + const server = createServer({ joinDuplicateHeaders: true }).listen(0) t.after(closeServerAsPromise(server)) await once(server, 'listening') diff --git a/test/fetch/abort2.js b/test/fetch/abort2.js index fec300b43df..f62e5c8c49a 100644 --- a/test/fetch/abort2.js +++ b/test/fetch/abort2.js @@ -16,7 +16,7 @@ test('parallel fetch with the same AbortController works as expected', async (t) bug: 'Ensure request is not aborted before enqueueing bytes into stream.' } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 200 res.end(JSON.stringify(body)) }) diff --git a/test/fetch/client-fetch.js b/test/fetch/client-fetch.js index 3003021390b..353a72aacf9 100644 --- a/test/fetch/client-fetch.js +++ b/test/fetch/client-fetch.js @@ -40,7 +40,7 @@ test('request json', (t, done) => { const { deepStrictEqual } = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) t.after(closeServerAsPromise(server)) @@ -56,7 +56,7 @@ test('request text', (t, done) => { const { strictEqual } = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) t.after(closeServerAsPromise(server)) @@ -72,7 +72,7 @@ test('request arrayBuffer', (t, done) => { const { deepStrictEqual } = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) t.after(closeServerAsPromise(server)) @@ -88,7 +88,7 @@ test('should set type of blob object to the value of the `Content-Type` header f const { strictEqual } = tspl(t, { plan: 1 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify(obj)) }) @@ -104,7 +104,7 @@ test('should set type of blob object to the value of the `Content-Type` header f test('pre aborted with readable request body', (t, done) => { const { strictEqual } = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) t.after(closeServerAsPromise(server)) @@ -129,7 +129,7 @@ test('pre aborted with readable request body', (t, done) => { test('pre aborted with closed readable request body', (t, done) => { const { ok, strictEqual } = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) t.after(closeServerAsPromise(server)) @@ -161,7 +161,7 @@ test('pre aborted with closed readable request body', (t, done) => { test('unsupported formData 1', (t, done) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'asdasdsad') res.end() }) @@ -190,7 +190,7 @@ test('multipart formdata not base64', async (t) => { const boundary = tempRes.headers.get('content-type').split('boundary=')[1] const formRaw = await tempRes.text() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'multipart/form-data; boundary=' + boundary) res.write(formRaw) res.end() @@ -223,7 +223,7 @@ test('multipart formdata base64', (t, done) => { '\r\n' + '------formdata-undici-0.5786922755719377--' - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.setHeader('content-type', 'multipart/form-data; boundary=----formdata-undici-0.5786922755719377') for (let offset = 0; offset < formRaw.length;) { @@ -274,7 +274,7 @@ test('busboy emit error', async (t) => { const tempRes = new Response(formData) const formRaw = await tempRes.text() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'multipart/form-data; boundary=wrongboundary') res.write(formRaw) res.end() @@ -303,7 +303,7 @@ test('parsing formData preserve full path on files', async (t) => { test('urlencoded formData', (t, done) => { const { strictEqual } = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'application/x-www-form-urlencoded') res.end('field1=value1&field2=value2') }) @@ -323,7 +323,7 @@ test('urlencoded formData', (t, done) => { test('text with BOM', (t, done) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'application/x-www-form-urlencoded') res.end('\uFEFFtest=\uFEFF') }) @@ -342,7 +342,7 @@ test('text with BOM', (t, done) => { test('formData with BOM', (t, done) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'application/x-www-form-urlencoded') res.end('\uFEFFtest=\uFEFF') }) @@ -361,7 +361,7 @@ test('formData with BOM', (t, done) => { test('locked blob body', (t, done) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(closeServerAsPromise(server)) @@ -379,7 +379,7 @@ test('locked blob body', (t, done) => { test('disturbed blob body', (t, done) => { const { ok, strictEqual } = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(closeServerAsPromise(server)) @@ -400,7 +400,7 @@ test('redirect with body', (t, done) => { const { strictEqual } = tspl(t, { plan: 3 }) let count = 0 - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let body = '' for await (const chunk of req) { body += chunk @@ -431,7 +431,7 @@ test('redirect with stream', (t, done) => { const location = '/asd' const body = 'hello!' - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.writeHead(302, { location }) let count = 0 const l = setInterval(() => { @@ -493,7 +493,7 @@ test('post FormData with Blob', (t, done) => { const body = new FormData() body.append('field1', new Blob(['asd1'])) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) t.after(closeServerAsPromise(server)) @@ -514,7 +514,7 @@ test('post FormData with File', (t, done) => { const body = new FormData() body.append('field1', new File(['asd1'], 'filename123')) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }) t.after(closeServerAsPromise(server)) @@ -545,7 +545,7 @@ test('custom agent', (t, done) => { const { ok, deepStrictEqual } = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) t.after(closeServerAsPromise(server)) @@ -572,7 +572,7 @@ test('custom agent node fetch', (t, done) => { const { ok, deepStrictEqual } = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify(obj)) }) t.after(closeServerAsPromise(server)) @@ -596,7 +596,7 @@ test('custom agent node fetch', (t, done) => { }) test('error on redirect', (t, done) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 302 res.end() }) @@ -614,7 +614,7 @@ test('error on redirect', (t, done) => { // https://github.com/nodejs/undici/issues/1527 test('fetching with Request object - issue #1527', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.ok(true) res.end() }).listen(0) @@ -635,7 +635,7 @@ test('do not decode redirect body', (t, done) => { const { ok, strictEqual } = tspl(t, { plan: 3 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/resource') { ok(true) res.statusCode = 301 @@ -663,7 +663,7 @@ test('decode non-redirect body with location header', (t, done) => { const { ok, strictEqual } = tspl(t, { plan: 2 }) const obj = { asd: true } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { ok(true) res.statusCode = 201 res.setHeader('location', '/resource/') @@ -688,7 +688,7 @@ test('Receiving non-Latin1 headers', async (t) => { 'inline; filename="100 % loading&perf.png"; filename*=UTF-8\'\'100%20%25%20loading%26perf.png' ] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { for (let i = 0; i < ContentDisposition.length; i++) { res.setHeader(`Content-Disposition-${i + 1}`, ContentDisposition[i]) } diff --git a/test/fetch/client-node-max-header-size.js b/test/fetch/client-node-max-header-size.js index 65d9251dc03..533d2377737 100644 --- a/test/fetch/client-node-max-header-size.js +++ b/test/fetch/client-node-max-header-size.js @@ -10,7 +10,7 @@ describe('fetch respects --max-http-header-size', () => { let server before(async () => { - server = createServer((req, res) => { + server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, 'OK', { 'Content-Length': 2 }) diff --git a/test/fetch/content-length.js b/test/fetch/content-length.js index 637ff0b800e..496b4de1b26 100644 --- a/test/fetch/content-length.js +++ b/test/fetch/content-length.js @@ -10,7 +10,7 @@ const { closeServerAsPromise } = require('../utils/node-http') // https://github.com/nodejs/undici/issues/1783 test('Content-Length is set when using a FormData body with fetch', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { // TODO: check the length's value once the boundary has a fixed length assert.ok('content-length' in req.headers) // request has content-length header assert.ok(!Number.isNaN(Number(req.headers['content-length']))) diff --git a/test/fetch/cookies.js b/test/fetch/cookies.js index 3bc69c6837b..ac30938dbad 100644 --- a/test/fetch/cookies.js +++ b/test/fetch/cookies.js @@ -12,7 +12,7 @@ const { createSecureServer } = require('node:http2') const { closeClientAndServerAsPromise } = require('../utils/node-http') test('Can receive set-cookie headers from a server using fetch - issue #1262', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('set-cookie', 'name=value; Domain=example.com') res.end() }).listen(0) @@ -32,7 +32,7 @@ test('Can receive set-cookie headers from a server using fetch - issue #1262', a }) test('Can send cookies to a server with fetch - issue #1463', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.headers.cookie, 'value') res.end() }).listen(0) @@ -54,7 +54,7 @@ test('Can send cookies to a server with fetch - issue #1463', async (t) => { test('Cookie header is delimited with a semicolon rather than a comma - issue #1905', async (t) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.cookie, 'FOO=lorem-ipsum-dolor-sit-amet; BAR=the-quick-brown-fox') res.end() }).listen(0) diff --git a/test/fetch/encoding.js b/test/fetch/encoding.js index 93c98274b08..9941fc68885 100644 --- a/test/fetch/encoding.js +++ b/test/fetch/encoding.js @@ -12,7 +12,7 @@ test('content-encoding header is case-iNsENsITIve', async (t) => { const contentCodings = 'GZiP, bR' const text = 'Hello, World!' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const gzip = createGzip() const brotli = createBrotliCompress() @@ -38,7 +38,7 @@ test('response decompression according to content-encoding should be handled in const contentCodings = 'deflate, gzip' const text = 'Hello, World!' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const gzip = createGzip() const deflate = createDeflate() diff --git a/test/fetch/exiting.js b/test/fetch/exiting.js index 0fb007be513..746a7fd97ee 100644 --- a/test/fetch/exiting.js +++ b/test/fetch/exiting.js @@ -8,7 +8,7 @@ const tspl = require('@matteo.collina/tspl') test('abort the request on the other side if the stream is canceled', async (t) => { const p = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200) res.write('hello') req.on('aborted', () => { diff --git a/test/fetch/fetch-leak.js b/test/fetch/fetch-leak.js index caf75fe357b..761a63f9700 100644 --- a/test/fetch/fetch-leak.js +++ b/test/fetch/fetch-leak.js @@ -14,7 +14,7 @@ test('do not leak', (t, done) => { throw new Error('gc is not available. Run with \'--expose-gc\'.') } const { ok } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(closeServerAsPromise(server)) diff --git a/test/fetch/fetch-timeouts.js b/test/fetch/fetch-timeouts.js index 038c23b5af9..41f9484e01d 100644 --- a/test/fetch/fetch-timeouts.js +++ b/test/fetch/fetch-timeouts.js @@ -24,7 +24,7 @@ test('Fetch very long request, timeout overridden so no error', (t, done) => { Object.assign(timers, orgTimers) }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, msToDelay) diff --git a/test/fetch/fetch-url-after-redirect.js b/test/fetch/fetch-url-after-redirect.js index e387848f8e4..c24c092e15b 100644 --- a/test/fetch/fetch-url-after-redirect.js +++ b/test/fetch/fetch-url-after-redirect.js @@ -9,7 +9,7 @@ const { promisify } = require('node:util') test('after redirecting the url of the response is set to the target url', async (t) => { // redirect-1 -> redirect-2 -> target - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { switch (res.req.url) { case '/redirect-1': res.writeHead(302, undefined, { Location: '/redirect-2' }) @@ -41,7 +41,7 @@ test('after redirecting the url of the response is set to the target url', async test('location header with non-ASCII character redirects to a properly encoded url', async (t) => { // redirect -> %EC%95%88%EB%85%95 (안녕), not %C3%AC%C2%95%C2%88%C3%AB%C2%85%C2%95 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (res.req.url.endsWith('/redirect')) { res.writeHead(302, undefined, { Location: `/${Buffer.from('안녕').toString('binary')}` }) res.end() diff --git a/test/fetch/fire-and-forget.js b/test/fetch/fire-and-forget.js index 5794f738cd2..40bb636e468 100644 --- a/test/fetch/fire-and-forget.js +++ b/test/fetch/fire-and-forget.js @@ -22,7 +22,7 @@ test('does not need the body to be consumed to continue', { timeout: 180_000, sk keepAliveTimeoutThreshold: 10 }) setGlobalDispatcher(agent) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200) res.end(blob) }) diff --git a/test/fetch/headers-case.js b/test/fetch/headers-case.js index 78c10b3d547..e0314565bf7 100644 --- a/test/fetch/headers-case.js +++ b/test/fetch/headers-case.js @@ -10,7 +10,7 @@ const { closeServerAsPromise } = require('../utils/node-http') test('Headers retain keys case-sensitive', async (t) => { const assert = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.ok(req.rawHeaders.includes('Content-Type')) res.end() diff --git a/test/fetch/headers.js b/test/fetch/headers.js index 02d500d6f80..1430abff1a9 100644 --- a/test/fetch/headers.js +++ b/test/fetch/headers.js @@ -694,7 +694,7 @@ test('Headers.prototype.getSetCookie', async (t) => { // https://github.com/nodejs/undici/issues/1935 await t.test('When Headers are cloned, so are the cookies (single entry)', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Set-Cookie', 'test=onetwo') res.end('Hello World!') }).listen(0) @@ -710,7 +710,7 @@ test('Headers.prototype.getSetCookie', async (t) => { }) await t.test('When Headers are cloned, so are the cookies (multiple entries)', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Set-Cookie', ['test=onetwo', 'test=onetwothree']) res.end('Hello World!') }).listen(0) diff --git a/test/fetch/integrity.js b/test/fetch/integrity.js index b88780175f8..5c34a87e20f 100644 --- a/test/fetch/integrity.js +++ b/test/fetch/integrity.js @@ -21,7 +21,7 @@ test('request with correct integrity checksum', (t, done) => { const body = 'Hello world!' const hash = createHash('sha256').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -40,7 +40,7 @@ test('request with wrong integrity checksum', async (t) => { const body = 'Hello world!' const hash = 'c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51b' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }).listen(0) @@ -60,7 +60,7 @@ test('request with integrity checksum on encoded body', (t, done) => { const body = 'Hello world!' const hash = createHash('sha256').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-encoding', 'gzip') res.end(gzipSync(body)) }) @@ -77,7 +77,7 @@ test('request with integrity checksum on encoded body', (t, done) => { }) test('request with a totally incorrect integrity', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }).listen(0) @@ -93,7 +93,7 @@ test('request with mixed in/valid integrities', async (t) => { const body = 'Hello world!' const hash = createHash('sha256').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }).listen(0) @@ -109,7 +109,7 @@ test('request with sha384 hash', { skip: !supportedHashes.includes('sha384') }, const body = 'Hello world!' const hash = createHash('sha384').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }).listen(0) @@ -131,7 +131,7 @@ test('request with sha512 hash', { skip: !supportedHashes.includes('sha512') }, const body = 'Hello world!' const hash = createHash('sha512').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }).listen(0) @@ -154,7 +154,7 @@ test('request with correct integrity checksum (base64url)', async (t) => { const body = 'Hello world!' const hash = createHash('sha256').update(body).digest('base64url') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -176,7 +176,7 @@ test('request with incorrect integrity checksum (base64url)', async (t) => { const body = 'Hello world!' const hash = createHash('sha256').update('invalid').digest('base64url') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -196,7 +196,7 @@ test('request with incorrect integrity checksum (only dash)', async (t) => { const body = 'Hello world!' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -216,7 +216,7 @@ test('request with incorrect integrity checksum (non-ascii character)', async (t const body = 'Hello world!' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -238,7 +238,7 @@ test('request with incorrect stronger integrity checksum (non-ascii character)', const sha256 = createHash('sha256').update(body).digest('base64') const sha384 = 'ä' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -263,7 +263,7 @@ test('request with correct integrity checksum (base64). mixed', async (t) => { const sha384 = createHash('sha384').update(body).digest('base64') const sha512 = createHash('sha512').update(body).digest('base64') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) @@ -309,7 +309,7 @@ test('request with correct integrity checksum (base64url). mixed', async (t) => const sha384 = createHash('sha384').update(body).digest('base64url') const sha512 = createHash('sha512').update(body).digest('base64url') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(body) }) diff --git a/test/fetch/issue-1711.js b/test/fetch/issue-1711.js index be48d160c20..ca78897ae5f 100644 --- a/test/fetch/issue-1711.js +++ b/test/fetch/issue-1711.js @@ -9,7 +9,7 @@ const { fetch } = require('../..') test('Redirecting a bunch does not cause a MaxListenersExceededWarning', async (t) => { let redirects = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (redirects === 15) { res.end('Okay goodbye') return @@ -36,7 +36,7 @@ test( 'aborting a Stream throws', () => { return new Promise((resolve, reject) => { - const httpServer = createServer((request, response) => { + const httpServer = createServer({ joinDuplicateHeaders: true }, (request, response) => { response.end(new Uint8Array(20000)) }).listen(async () => { const serverAddress = httpServer.address() diff --git a/test/fetch/issue-2009.js b/test/fetch/issue-2009.js index d77b60b6334..14432e81cb2 100644 --- a/test/fetch/issue-2009.js +++ b/test/fetch/issue-2009.js @@ -10,7 +10,7 @@ const { closeServerAsPromise } = require('../utils/node-http') test('issue 2009', async (t) => { const { doesNotReject } = tspl(t, { plan: 10 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('a', 'b') res.flushHeaders() diff --git a/test/fetch/issue-2021.js b/test/fetch/issue-2021.js index 5b949e507de..b88db725dbe 100644 --- a/test/fetch/issue-2021.js +++ b/test/fetch/issue-2021.js @@ -9,7 +9,7 @@ const { closeServerAsPromise } = require('../utils/node-http') // https://github.com/nodejs/undici/issues/2021 test('content-length header is removed on redirect', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/redirect') { res.writeHead(302, { Location: '/redirect2' }) res.end() diff --git a/test/fetch/issue-2171.js b/test/fetch/issue-2171.js index 82577f9494c..ba0c82674cf 100644 --- a/test/fetch/issue-2171.js +++ b/test/fetch/issue-2171.js @@ -8,7 +8,7 @@ const assert = require('node:assert') const { closeServerAsPromise } = require('../utils/node-http') test('error reason is forwarded - issue #2171', { skip: !AbortSignal.timeout }, async (t) => { - const server = createServer(() => {}).listen(0) + const server = createServer({ joinDuplicateHeaders: true }, () => {}).listen(0) t.after(closeServerAsPromise(server)) await once(server, 'listening') diff --git a/test/fetch/issue-2318.js b/test/fetch/issue-2318.js index 273e2b9a74c..fe27ac7ec35 100644 --- a/test/fetch/issue-2318.js +++ b/test/fetch/issue-2318.js @@ -10,7 +10,7 @@ const { closeServerAsPromise } = require('../utils/node-http') test('Undici overrides user-provided `Host` header', async (t) => { const { strictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.host, `localhost:${server.address().port}`) res.end() diff --git a/test/fetch/issue-2828.js b/test/fetch/issue-2828.js index 08e8ea714ca..98fd375b8e9 100644 --- a/test/fetch/issue-2828.js +++ b/test/fetch/issue-2828.js @@ -16,7 +16,7 @@ test('issue #2828, dispatcher is allowed in RequestInit options', async (t) => { } } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { deepStrictEqual(req.headers['x-my-header'], 'hello') res.end() }).listen(0) diff --git a/test/fetch/issue-2898-comment.js b/test/fetch/issue-2898-comment.js index c46b80b3ff7..d1d326b2c35 100644 --- a/test/fetch/issue-2898-comment.js +++ b/test/fetch/issue-2898-comment.js @@ -23,7 +23,7 @@ test('issue #2828, RequestInit dispatcher options overrides Request input dispat } } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers['x-my-header-a'], undefined) strictEqual(req.headers['x-my-header-b'], 'world') res.end() diff --git a/test/fetch/issue-2898.js b/test/fetch/issue-2898.js index 231b7615761..d6188ab696a 100644 --- a/test/fetch/issue-2898.js +++ b/test/fetch/issue-2898.js @@ -10,7 +10,7 @@ const { fetch } = require('../..') test('421 requests with a body work as expected', async (t) => { const expected = 'This is a 421 Misdirected Request response.' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 421 res.end(expected) }).listen(0) diff --git a/test/fetch/issue-3334.js b/test/fetch/issue-3334.js index 968b2a797b7..1fcfd0e86c7 100644 --- a/test/fetch/issue-3334.js +++ b/test/fetch/issue-3334.js @@ -10,7 +10,7 @@ test('a non-empty origin is not appended (issue #3334)', async (t) => { const { strictEqual } = tspl(t, { plan: 1 }) const origin = 'https://origin.example.com' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.origin, origin) res.end() }).listen(0) diff --git a/test/fetch/issue-3616.js b/test/fetch/issue-3616.js index ed9f739bba1..2de5c63672d 100644 --- a/test/fetch/issue-3616.js +++ b/test/fetch/issue-3616.js @@ -17,7 +17,7 @@ describe('https://github.com/nodejs/undici/issues/3616', () => { for (const encoding of cases) { test(encoding, async t => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'Content-Length': '0', Connection: 'close', diff --git a/test/fetch/issue-3624.js b/test/fetch/issue-3624.js index 37e722d7e4e..487fed7b210 100644 --- a/test/fetch/issue-3624.js +++ b/test/fetch/issue-3624.js @@ -9,7 +9,7 @@ const { fetch, FormData } = require('../..') // https://github.com/nodejs/undici/issues/3624 test('crlf is appended to formdata body (issue #3624)', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.pipe(res) }).listen(0) diff --git a/test/fetch/issue-3767.js b/test/fetch/issue-3767.js index fec7c71dbe6..aa742aaffe6 100644 --- a/test/fetch/issue-3767.js +++ b/test/fetch/issue-3767.js @@ -12,7 +12,7 @@ test('referrerPolicy unsafe-url is respected', async (t) => { const referrer = 'https://google.com/hello/world' - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { deepEqual(req.headers.referer, referrer) res.end() diff --git a/test/fetch/issue-4105.js b/test/fetch/issue-4105.js new file mode 100644 index 00000000000..8d4b480eca8 --- /dev/null +++ b/test/fetch/issue-4105.js @@ -0,0 +1,34 @@ +'use strict' + +const { once } = require('node:events') +const { createServer } = require('node:http') +const { test } = require('node:test') +const { fetch } = require('../..') +const { tspl } = require('@matteo.collina/tspl') +const { PerformanceObserver } = require('node:perf_hooks') + +const isAtLeastv22 = process.versions.node.split('.').map(Number)[0] >= 22 + +// https://github.com/nodejs/undici/issues/4105 +test('markResourceTiming responseStatus is set', { skip: !isAtLeastv22 }, async (t) => { + const { completed, deepEqual } = tspl(t, { plan: 1 }) + + const server = createServer((req, res) => { + res.statusCode = 200 + res.end('Hello World') + }).listen(3000) + + t.after(server.close.bind(server)) + await once(server, 'listening') + + new PerformanceObserver(items => { + items.getEntries().forEach(entry => { + deepEqual(entry.responseStatus, 200) + }) + }).observe({ type: 'resource', buffered: true }) + + const response = await fetch('http://localhost:3000') + await response.text() + + await completed +}) diff --git a/test/fetch/issue-node-46525.js b/test/fetch/issue-node-46525.js index b35eeb2a590..da7c2cd27b6 100644 --- a/test/fetch/issue-node-46525.js +++ b/test/fetch/issue-node-46525.js @@ -11,7 +11,7 @@ test('No warning when reusing AbortController', async (t) => { throw new Error('Got warning') } - const server = createServer((req, res) => res.end()).listen(0) + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => res.end()).listen(0) await once(server, 'listening') diff --git a/test/fetch/issue-rsshub-15532.js b/test/fetch/issue-rsshub-15532.js index 11491337de5..988e12ceb5c 100644 --- a/test/fetch/issue-rsshub-15532.js +++ b/test/fetch/issue-rsshub-15532.js @@ -10,7 +10,7 @@ const { tspl } = require('@matteo.collina/tspl') test('An invalid Origin header is not set', async (t) => { const { deepStrictEqual } = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { deepStrictEqual(req.headers.origin, undefined) res.end() diff --git a/test/fetch/long-lived-abort-controller.js b/test/fetch/long-lived-abort-controller.js index 561ebee0661..427b605e295 100644 --- a/test/fetch/long-lived-abort-controller.js +++ b/test/fetch/long-lived-abort-controller.js @@ -10,7 +10,7 @@ const { strictEqual } = require('node:assert') // const isNode18 = process.version.startsWith('v18') test('long-lived-abort-controller', { skip: true }, async (t) => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.write('Hello World!') res.end() diff --git a/test/fetch/pull-dont-push.js b/test/fetch/pull-dont-push.js index 27454bd6c58..7489b3fb0cd 100644 --- a/test/fetch/pull-dont-push.js +++ b/test/fetch/pull-dont-push.js @@ -14,7 +14,7 @@ test('pull dont\'t push', async (t) => { let count = 0 let socket const max = 1_000_000 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 200 socket = res.socket diff --git a/test/fetch/redirect-cross-origin-header.js b/test/fetch/redirect-cross-origin-header.js index 3756c22d417..8f0d58587e7 100644 --- a/test/fetch/redirect-cross-origin-header.js +++ b/test/fetch/redirect-cross-origin-header.js @@ -9,7 +9,7 @@ const { fetch } = require('../..') test('Cross-origin redirects clear forbidden headers', async (t) => { const { strictEqual } = tspl(t, { plan: 6 }) - const server1 = createServer((req, res) => { + const server1 = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.cookie, undefined) strictEqual(req.headers.authorization, undefined) strictEqual(req.headers['proxy-authorization'], undefined) @@ -17,7 +17,7 @@ test('Cross-origin redirects clear forbidden headers', async (t) => { res.end('redirected') }).listen(0) - const server2 = createServer((req, res) => { + const server2 = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.authorization, 'test') strictEqual(req.headers.cookie, 'ddd=dddd') diff --git a/test/fetch/redirect.js b/test/fetch/redirect.js index a9533bcc327..6d41ff30849 100644 --- a/test/fetch/redirect.js +++ b/test/fetch/redirect.js @@ -9,7 +9,7 @@ const { closeServerAsPromise } = require('../utils/node-http') // https://github.com/nodejs/undici/issues/1776 test('Redirecting with a body does not cancel the current request - #1776', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/redirect') { res.statusCode = 301 res.setHeader('location', '/redirect/') @@ -31,7 +31,7 @@ test('Redirecting with a body does not cancel the current request - #1776', asyn }) test('Redirecting with an empty body does not throw an error - #2027', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/redirect') { res.statusCode = 307 res.setHeader('location', '/redirect/') @@ -52,7 +52,7 @@ test('Redirecting with an empty body does not throw an error - #2027', async (t) }) test('Redirecting with a body does not fail to write body - #2543', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/redirect') { res.writeHead(307, { location: '/target' }) res.write('Moved Permanently') diff --git a/test/fetch/referrrer-policy.js b/test/fetch/referrrer-policy.js index e2e8ee90002..612d8e29d0d 100644 --- a/test/fetch/referrrer-policy.js +++ b/test/fetch/referrrer-policy.js @@ -73,7 +73,7 @@ describe('referrer-policy', () => { test(title, async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { switch (res.req.url) { case '/redirect': res.writeHead(302, undefined, { diff --git a/test/fetch/relative-url.js b/test/fetch/relative-url.js index 2a57e15c5e5..b6e28bda7ea 100644 --- a/test/fetch/relative-url.js +++ b/test/fetch/relative-url.js @@ -75,7 +75,7 @@ test('fetch', async (t) => { await assert.rejects(fetch('/relative/path'), TypeError('Failed to parse URL from /relative/path')) await t.test('Basic fetch', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.url, '/relative/path') res.end() }).listen(0) @@ -88,7 +88,7 @@ test('fetch', async (t) => { }) await t.test('fetch return', async (t) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.strictEqual(req.url, '/relative/path') res.end() }).listen(0) diff --git a/test/fetch/resource-timing.js b/test/fetch/resource-timing.js index b32fd08fb8b..4def7bf90e2 100644 --- a/test/fetch/resource-timing.js +++ b/test/fetch/resource-timing.js @@ -37,7 +37,7 @@ test('should create a PerformanceResourceTiming after each fetch request', (t, d obs.observe({ entryTypes: ['resource'] }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ok') }).listen(0, async () => { const body = await fetch(`http://localhost:${server.address().port}`) @@ -62,7 +62,7 @@ test('should include encodedBodySize in performance entry', (t, done) => { obs.observe({ entryTypes: ['resource'] }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ok') }).listen(0, async () => { const body = await fetch(`http://localhost:${server.address().port}`) @@ -98,7 +98,7 @@ test('timing entries should be in order', (t, done) => { obs.observe({ entryTypes: ['resource'] }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ok') }).listen(0, async () => { const body = await fetch(`http://localhost:${server.address().port}/redirect`) @@ -124,7 +124,7 @@ test('redirect timing entries should be included when redirecting', (t, done) => obs.observe({ entryTypes: ['resource'] }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/redirect') { res.statusCode = 307 res.setHeader('location', '/redirect/') diff --git a/test/fetch/user-agent.js b/test/fetch/user-agent.js index da8936c8cff..770f550725f 100644 --- a/test/fetch/user-agent.js +++ b/test/fetch/user-agent.js @@ -10,7 +10,7 @@ const { closeServerAsPromise } = require('../utils/node-http') const nodeBuild = require('../../undici-fetch.js') test('user-agent defaults correctly', async (t) => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(JSON.stringify({ userAgentHeader: req.headers['user-agent'] })) }) t.after(closeServerAsPromise(server)) diff --git a/test/fixtures/cache-tests/test-engine/server/server.mjs b/test/fixtures/cache-tests/test-engine/server/server.mjs index 58f098ba77f..54f644019c7 100644 --- a/test/fixtures/cache-tests/test-engine/server/server.mjs +++ b/test/fixtures/cache-tests/test-engine/server/server.mjs @@ -39,11 +39,12 @@ let server if (protocol.toLowerCase() === 'https') { const options = { key: fs.readFileSync(process.env.npm_config_keyfile), - cert: fs.readFileSync(process.env.npm_config_certfile) + cert: fs.readFileSync(process.env.npm_config_certfile), + joinDuplicateHeaders: true } server = https.createServer(options, handleMain) } else { - server = http.createServer(handleMain) + server = http.createServer({ joinDuplicateHeaders: true }, handleMain) } server.on('listening', () => { const host = (server.address().family === 'IPv6') diff --git a/test/fixtures/fetch.js b/test/fixtures/fetch.js index 36e572cd3d1..7d5790fa418 100644 --- a/test/fixtures/fetch.js +++ b/test/fixtures/fetch.js @@ -3,7 +3,7 @@ const { createServer } = require('node:http') const { fetch } = require('../..') -const server = createServer((_req, res) => { +const server = createServer({ joinDuplicateHeaders: true }, (_req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('hello world') }) diff --git a/test/fixtures/interceptors/retry-event-loop.js b/test/fixtures/interceptors/retry-event-loop.js index 0a92d0d27a6..3fcfa979637 100644 --- a/test/fixtures/interceptors/retry-event-loop.js +++ b/test/fixtures/interceptors/retry-event-loop.js @@ -7,7 +7,7 @@ const { interceptors: { retry } } = require('../../..') -const server = createServer() +const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(418, { 'Content-Type': 'text/plain' }) diff --git a/test/fixtures/undici.js b/test/fixtures/undici.js index 643142501ff..6bc6ba0fc3e 100644 --- a/test/fixtures/undici.js +++ b/test/fixtures/undici.js @@ -3,7 +3,7 @@ const { createServer } = require('node:http') const { request } = require('../..') -const server = createServer((_req, res) => { +const server = createServer({ joinDuplicateHeaders: true }, (_req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('hello world') }) diff --git a/test/fixtures/wpt/common/redirect.py b/test/fixtures/wpt/common/redirect.py index f2fd1ebd51d..1ddde9a579b 100644 --- a/test/fixtures/wpt/common/redirect.py +++ b/test/fixtures/wpt/common/redirect.py @@ -4,6 +4,9 @@ def main(request, response): The request should typically have two query parameters: status - The status to use for the redirection. Defaults to 302. location - The resource to redirect to. + + This utility optionally supports CORS (iff the `enable-cors` query param is + present). """ status = 302 if b"status" in request.GET: @@ -17,3 +20,10 @@ def main(request, response): location = request.GET.first(b"location") response.headers.set(b"Location", location) + + if request.GET.get(b"enable-cors") is not None: + origin = request.headers.get(b"Origin") + if origin: + response.headers.set(b"Content-Type", b"text/plain") + response.headers.set(b"Access-Control-Allow-Origin", origin) + response.headers.set(b"Access-Control-Allow-Credentials", 'true') diff --git a/test/fixtures/wpt/fetch/content-encoding/br/br-navigation.https.window.js b/test/fixtures/wpt/fetch/content-encoding/br/br-navigation.https.window.js new file mode 100644 index 00000000000..6fbb42ad3ab --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/br/br-navigation.https.window.js @@ -0,0 +1,6 @@ +// META: script=../../../service-workers/service-worker/resources/test-helpers.sub.js + +promise_test(async t => { + const frame = await with_iframe('./resources/hello.html.br'); + assert_equals(frame.contentDocument.body.textContent, 'Hello world'); +}, `Naigation to br encoded page`); diff --git a/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br b/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br new file mode 100644 index 00000000000..eff82bcb41e Binary files /dev/null and b/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br differ diff --git a/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br.headers b/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br.headers new file mode 100644 index 00000000000..c001132850f --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/br/resources/hello.html.br.headers @@ -0,0 +1,2 @@ +Content-type: text/html +Content-Encoding: br diff --git a/test/fixtures/wpt/fetch/content-encoding/gzip/gzip-navigation.https.window.js b/test/fixtures/wpt/fetch/content-encoding/gzip/gzip-navigation.https.window.js new file mode 100644 index 00000000000..0ef68766098 --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/gzip/gzip-navigation.https.window.js @@ -0,0 +1,6 @@ +// META: script=../../../service-workers/service-worker/resources/test-helpers.sub.js + +promise_test(async t => { + const frame = await with_iframe('./resources/hello.html.gz'); + assert_equals(frame.contentDocument.body.textContent, 'Hello world'); +}, `Naigation to gzip encoded page`); diff --git a/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz b/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz new file mode 100644 index 00000000000..87140901396 Binary files /dev/null and b/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz differ diff --git a/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz.headers b/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz.headers new file mode 100644 index 00000000000..937eff5d7d8 --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/gzip/resources/hello.html.gz.headers @@ -0,0 +1,2 @@ +Content-type: text/html +Content-Encoding: gzip diff --git a/test/fixtures/wpt/fetch/content-encoding/zstd/WEB_FEATURES.yml b/test/fixtures/wpt/fetch/content-encoding/zstd/WEB_FEATURES.yml new file mode 100644 index 00000000000..b5d970fdb14 --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/zstd/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: zstd + files: "**" diff --git a/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst b/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst new file mode 100644 index 00000000000..1e3598106fc Binary files /dev/null and b/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst differ diff --git a/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst.headers b/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst.headers new file mode 100644 index 00000000000..45763963093 --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/zstd/resources/hello.html.zst.headers @@ -0,0 +1,2 @@ +Content-type: text/html +Content-Encoding: zstd diff --git a/test/fixtures/wpt/fetch/content-encoding/zstd/zstd-navigation.https.window.js b/test/fixtures/wpt/fetch/content-encoding/zstd/zstd-navigation.https.window.js new file mode 100644 index 00000000000..27cf25ae782 --- /dev/null +++ b/test/fixtures/wpt/fetch/content-encoding/zstd/zstd-navigation.https.window.js @@ -0,0 +1,6 @@ +// META: script=../../../service-workers/service-worker/resources/test-helpers.sub.js + +promise_test(async t => { + const frame = await with_iframe('./resources/hello.html.zst'); + assert_equals(frame.contentDocument.body.textContent, 'Hello world'); +}, `Naigation to zstd encoded page`); diff --git a/test/fixtures/wpt/fetch/private-network-access/README.md b/test/fixtures/wpt/fetch/private-network-access/README.md index a69aab48723..cbb5b85b74d 100644 --- a/test/fixtures/wpt/fetch/private-network-access/README.md +++ b/test/fixtures/wpt/fetch/private-network-access/README.md @@ -8,3 +8,6 @@ See also: * [The specification](https://wicg.github.io/private-network-access/) * [The repository](https://github.com/WICG/private-network-access/) * [Open issues](https://github.com/WICG/private-network-access/issues/) + +Private Network Access is deprecated and will eventually be replaced by [Local +Network Access](https://github.com/explainers-by-googlers/local-network-access). diff --git a/test/fixtures/wpt/interfaces/DOM-Parsing.idl b/test/fixtures/wpt/interfaces/DOM-Parsing.idl deleted file mode 100644 index af262607936..00000000000 --- a/test/fixtures/wpt/interfaces/DOM-Parsing.idl +++ /dev/null @@ -1,10 +0,0 @@ -// GENERATED CONTENT - DO NOT EDIT -// Content was automatically extracted by Reffy into webref -// (https://github.com/w3c/webref) -// Source: DOM Parsing and Serialization (https://w3c.github.io/DOM-Parsing/) - -[Exposed=Window] -interface XMLSerializer { - constructor(); - DOMString serializeToString(Node root); -}; diff --git a/test/fixtures/wpt/interfaces/SVG.idl b/test/fixtures/wpt/interfaces/SVG.idl index 3a0b86126b5..5dff2947b51 100644 --- a/test/fixtures/wpt/interfaces/SVG.idl +++ b/test/fixtures/wpt/interfaces/SVG.idl @@ -418,10 +418,6 @@ interface SVGAnimatedPreserveAspectRatio { [SameObject] readonly attribute SVGPreserveAspectRatio animVal; }; -[Exposed=Window] -interface SVGPathElement : SVGGeometryElement { -}; - [Exposed=Window] interface SVGRectElement : SVGGeometryElement { [SameObject] readonly attribute SVGAnimatedLength x; diff --git a/test/fixtures/wpt/interfaces/css-mixins.idl b/test/fixtures/wpt/interfaces/css-mixins.idl index 6629b3861f6..86015e7dd0e 100644 --- a/test/fixtures/wpt/interfaces/css-mixins.idl +++ b/test/fixtures/wpt/interfaces/css-mixins.idl @@ -4,7 +4,17 @@ // Source: CSS Functions and Mixins Module (https://drafts.csswg.org/css-mixins-1/) [Exposed=Window] -interface CSSFunctionRule : CSSGroupingRule { }; +interface CSSFunctionRule : CSSGroupingRule { + readonly attribute CSSOMString name; + sequence getParameters(); + readonly attribute CSSOMString returnType; +}; + +dictionary FunctionParameter { + required CSSOMString name; + required CSSOMString type; + CSSOMString? defaultValue; +}; [Exposed=Window] interface CSSFunctionDescriptors : CSSStyleDeclaration { diff --git a/test/fixtures/wpt/interfaces/dom.idl b/test/fixtures/wpt/interfaces/dom.idl index 814040a2c40..7b4fcb920e2 100644 --- a/test/fixtures/wpt/interfaces/dom.idl +++ b/test/fixtures/wpt/interfaces/dom.idl @@ -124,6 +124,8 @@ interface mixin ParentNode { [CEReactions, Unscopable] undefined append((Node or DOMString)... nodes); [CEReactions, Unscopable] undefined replaceChildren((Node or DOMString)... nodes); + [CEReactions] undefined moveBefore(Node node, Node? child); + Element? querySelector(DOMString selectors); [NewObject] NodeList querySelectorAll(DOMString selectors); }; diff --git a/test/fixtures/wpt/interfaces/fedcm.idl b/test/fixtures/wpt/interfaces/fedcm.idl index f7038a6fee1..c26e2b14c73 100644 --- a/test/fixtures/wpt/interfaces/fedcm.idl +++ b/test/fixtures/wpt/interfaces/fedcm.idl @@ -12,6 +12,7 @@ interface IdentityCredential : Credential { static Promise disconnect(IdentityCredentialDisconnectOptions options); readonly attribute USVString? token; readonly attribute boolean isAutoSelected; + readonly attribute USVString configURL; }; dictionary DisconnectedAccount { @@ -78,6 +79,7 @@ dictionary IdentityProviderAPIConfig { required USVString login_url; USVString disconnect_endpoint; IdentityProviderBranding branding; + USVString account_label; }; dictionary IdentityProviderAccount { @@ -89,6 +91,7 @@ dictionary IdentityProviderAccount { sequence approved_clients; sequence login_hints; sequence domain_hints; + sequence label_hints; }; dictionary IdentityProviderAccountList { sequence accounts; diff --git a/test/fixtures/wpt/interfaces/html.idl b/test/fixtures/wpt/interfaces/html.idl index f48fd370281..97fabdf80fa 100644 --- a/test/fixtures/wpt/interfaces/html.idl +++ b/test/fixtures/wpt/interfaces/html.idl @@ -1483,6 +1483,7 @@ interface mixin CanvasPathDrawingStyles { interface mixin CanvasTextDrawingStyles { // text + attribute DOMString lang; // (default: "inherit") attribute DOMString font; // (default 10px sans-serif) attribute CanvasTextAlign textAlign; // (default: "start") attribute CanvasTextBaseline textBaseline; // (default: "alphabetic") @@ -2368,6 +2369,13 @@ partial interface Range { [CEReactions, NewObject] DocumentFragment createContextualFragment((TrustedHTML or DOMString) string); }; +[Exposed=Window] +interface XMLSerializer { + constructor(); + + DOMString serializeToString(Node root); +}; + [Exposed=Window] interface Navigator { // objects implementing this interface also implement the interfaces given below diff --git a/test/fixtures/wpt/interfaces/ppa.idl b/test/fixtures/wpt/interfaces/ppa.idl index a00d2deba87..ef3eb360bdf 100644 --- a/test/fixtures/wpt/interfaces/ppa.idl +++ b/test/fixtures/wpt/interfaces/ppa.idl @@ -10,13 +10,12 @@ partial interface Navigator { enum PrivateAttributionProtocol { "dap-12-histogram", "tee-00" }; dictionary PrivateAttributionAggregationService { - required DOMString url; required DOMString protocol; }; [SecureContext, Exposed=Window] interface PrivateAttributionAggregationServices { - readonly setlike; + readonly maplike; }; [SecureContext, Exposed=Window] @@ -27,7 +26,7 @@ interface PrivateAttribution { dictionary PrivateAttributionImpressionOptions { required unsigned long histogramIndex; unsigned long filterData = 0; - required DOMString conversionSite; + required USVString conversionSite; unsigned long lifetimeDays = 30; }; @@ -37,19 +36,19 @@ partial interface PrivateAttribution { }; dictionary PrivateAttributionConversionOptions { - required DOMString aggregationService; + required USVString aggregationService; double epsilon = 1.0; required unsigned long histogramSize; + unsigned long lookbackDays; + unsigned long filterData; + sequence impressionSites = []; + sequence intermediarySites = []; + PrivateAttributionLogic logic = "last-touch"; unsigned long value = 1; unsigned long maxValue = 1; - - unsigned long lookbackDays; - unsigned long filterData; - sequence impressionSites = []; - sequence intermediarySites = []; }; dictionary PrivateAttributionConversionResult { diff --git a/test/fixtures/wpt/interfaces/private-aggregation-api.idl b/test/fixtures/wpt/interfaces/private-aggregation-api.idl index c89a4687abb..bc5eb740718 100644 --- a/test/fixtures/wpt/interfaces/private-aggregation-api.idl +++ b/test/fixtures/wpt/interfaces/private-aggregation-api.idl @@ -7,6 +7,8 @@ SecureContext] interface PrivateAggregation { undefined contributeToHistogram(PAHistogramContribution contribution); + undefined contributeToHistogramOnEvent(DOMString event, + record contribution); undefined enableDebugMode(optional PADebugModeOptions options = {}); }; diff --git a/test/fixtures/wpt/interfaces/sanitizer-api.tentative.idl b/test/fixtures/wpt/interfaces/sanitizer-api.tentative.idl deleted file mode 100644 index 4e597aeec7b..00000000000 --- a/test/fixtures/wpt/interfaces/sanitizer-api.tentative.idl +++ /dev/null @@ -1,61 +0,0 @@ -// https://wicg.github.io/sanitizer-api/ - -enum SanitizerPresets { "default" }; -dictionary SetHTMLOptions { - (Sanitizer or SanitizerConfig or SanitizerPresets) sanitizer = "default"; -}; -dictionary SetHTMLUnsafeOptions { - (Sanitizer or SanitizerConfig or SanitizerPresets) sanitizer = {}; -}; - -[Exposed=Window] -interface Sanitizer { - constructor(optional (SanitizerConfig or SanitizerPresets) configuration = "default"); - - // Query configuration: - SanitizerConfig get(); - - // Modify a Sanitizer’s lists and fields: - undefined allowElement(SanitizerElementWithAttributes element); - undefined removeElement(SanitizerElement element); - undefined replaceElementWithChildren(SanitizerElement element); - undefined allowAttribute(SanitizerAttribute attribute); - undefined removeAttribute(SanitizerAttribute attribute); - undefined setComments(boolean allow); - undefined setDataAttributes(boolean allow); - - // Remove markup that executes script. May modify multiple lists: - undefined removeUnsafe(); -}; - -dictionary SanitizerElementNamespace { - required DOMString name; - DOMString? _namespace = "http://www.w3.org/1999/xhtml"; -}; - -// Used by "elements" -dictionary SanitizerElementNamespaceWithAttributes : SanitizerElementNamespace { - sequence attributes; - sequence removeAttributes; -}; - -typedef (DOMString or SanitizerElementNamespace) SanitizerElement; -typedef (DOMString or SanitizerElementNamespaceWithAttributes) SanitizerElementWithAttributes; - -dictionary SanitizerAttributeNamespace { - required DOMString name; - DOMString? _namespace = null; -}; -typedef (DOMString or SanitizerAttributeNamespace) SanitizerAttribute; - -dictionary SanitizerConfig { - sequence elements; - sequence removeElements; - sequence replaceWithChildrenElements; - - sequence attributes; - sequence removeAttributes; - - boolean comments; - boolean dataAttributes; -}; diff --git a/test/fixtures/wpt/interfaces/shared-storage.idl b/test/fixtures/wpt/interfaces/shared-storage.idl index 941c7414c4f..e3e221a3aa7 100644 --- a/test/fixtures/wpt/interfaces/shared-storage.idl +++ b/test/fixtures/wpt/interfaces/shared-storage.idl @@ -71,6 +71,7 @@ dictionary SharedStorageSetMethodOptions : SharedStorageModifierMethodOptions { [Exposed=(Window,SharedStorageWorklet)] interface SharedStorage { + Promise get(DOMString key); Promise set(DOMString key, DOMString value, optional SharedStorageSetMethodOptions options = {}); @@ -97,9 +98,6 @@ interface SharedStorage { [Exposed=Window] readonly attribute SharedStorageWorklet worklet; - [Exposed=SharedStorageWorklet] - Promise get(DOMString key); - [Exposed=SharedStorageWorklet] Promise length(); diff --git a/test/fixtures/wpt/interfaces/svg-paths.idl b/test/fixtures/wpt/interfaces/svg-paths.idl new file mode 100644 index 00000000000..2f0813572a1 --- /dev/null +++ b/test/fixtures/wpt/interfaces/svg-paths.idl @@ -0,0 +1,31 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into webref +// (https://github.com/w3c/webref) +// Source: SVG Paths (https://svgwg.org/specs/paths/) + +[LegacyNoInterfaceObject, Exposed=Window] +interface SVGPathSegment { + attribute DOMString type; + attribute FrozenArray values; +}; + +dictionary SVGPathDataSettings { + boolean normalize = false; +}; + +interface mixin SVGPathData { + sequence getPathData(optional SVGPathDataSettings settings = {}); + undefined setPathData(sequence pathData); +}; + +[Exposed=Window] +interface SVGPathElement : SVGGeometryElement { + + readonly attribute SVGAnimatedNumber pathLength; + + float getTotalLength(); + DOMPoint getPointAtLength(float distance); + SVGPathSegment? getPathSegmentAtLength(float distance); +}; + +SVGPathElement includes SVGPathData; diff --git a/test/fixtures/wpt/interfaces/turtledove.idl b/test/fixtures/wpt/interfaces/turtledove.idl index 2f34d763722..b9f50d47885 100644 --- a/test/fixtures/wpt/interfaces/turtledove.idl +++ b/test/fixtures/wpt/interfaces/turtledove.idl @@ -18,6 +18,7 @@ dictionary AuctionAd { sequence selectableBuyerAndSellerReportingIds; sequence allowedReportingOrigins; DOMString adRenderId; + USVString creativeScanningMetadata; }; dictionary AuctionAdInterestGroupSize { @@ -106,6 +107,7 @@ dictionary AuctionAdConfig { USVString trustedScoringSignalsURL; long maxTrustedScoringSignalsURLLength; USVString trustedScoringSignalsCoordinator; + boolean sendCreativeScanningMetadata; sequence interestGroupBuyers; Promise auctionSignals; Promise sellerSignals; @@ -218,12 +220,6 @@ dictionary PAExtendedHistogramContribution { bigint filteringId = 0; }; -[Exposed=InterestGroupScriptRunnerGlobalScope] -partial interface PrivateAggregation { - undefined contributeToHistogramOnEvent( - DOMString event, PAExtendedHistogramContribution contribution); -}; - [Exposed=InterestGroupBiddingAndScoringScriptRunnerGlobalScope] interface ForDebuggingOnly { undefined reportAdAuctionWin(USVString url); @@ -351,6 +347,8 @@ dictionary ScoringBrowserSignals { unsigned long crossOriginDataVersion; sequence adComponents; boolean forDebuggingOnlyInCooldownOrLockout = false; + USVString creativeScanningMetadata; + sequence adComponentsCreativeScanningMetadata; }; dictionary ReportingBrowserSignals { diff --git a/test/fixtures/wpt/interfaces/webaudio.idl b/test/fixtures/wpt/interfaces/webaudio.idl index d14eb96820f..286aeba4069 100644 --- a/test/fixtures/wpt/interfaces/webaudio.idl +++ b/test/fixtures/wpt/interfaces/webaudio.idl @@ -6,7 +6,8 @@ enum AudioContextState { "suspended", "running", - "closed" + "closed", + "interrupted" }; enum AudioContextRenderSizeCategory { @@ -80,7 +81,6 @@ interface AudioContext : BaseAudioContext { readonly attribute double baseLatency; readonly attribute double outputLatency; [SecureContext] readonly attribute (DOMString or AudioSinkInfo) sinkId; - [SecureContext] readonly attribute AudioRenderCapacity renderCapacity; attribute EventHandler onsinkchange; attribute EventHandler onerror; AudioTimestamp getOutputTimestamp (); @@ -116,33 +116,6 @@ dictionary AudioTimestamp { DOMHighResTimeStamp performanceTime; }; -[Exposed=Window] -interface AudioRenderCapacity : EventTarget { - undefined start(optional AudioRenderCapacityOptions options = {}); - undefined stop(); - attribute EventHandler onupdate; -}; - -dictionary AudioRenderCapacityOptions { - double updateInterval = 1; -}; - -[Exposed=Window] -interface AudioRenderCapacityEvent : Event { - constructor (DOMString type, optional AudioRenderCapacityEventInit eventInitDict = {}); - readonly attribute double timestamp; - readonly attribute double averageLoad; - readonly attribute double peakLoad; - readonly attribute double underrunRatio; -}; - -dictionary AudioRenderCapacityEventInit : EventInit { - double timestamp = 0; - double averageLoad = 0; - double peakLoad = 0; - double underrunRatio = 0; -}; - [Exposed=Window] interface OfflineAudioContext : BaseAudioContext { constructor(OfflineAudioContextOptions contextOptions); diff --git a/test/fixtures/wpt/interfaces/webgpu.idl b/test/fixtures/wpt/interfaces/webgpu.idl index d91a6a710b1..de1f7c1e52b 100644 --- a/test/fixtures/wpt/interfaces/webgpu.idl +++ b/test/fixtures/wpt/interfaces/webgpu.idl @@ -64,6 +64,7 @@ interface GPUAdapterInfo { readonly attribute DOMString description; readonly attribute unsigned long subgroupMinSize; readonly attribute unsigned long subgroupMaxSize; + readonly attribute boolean isFallbackAdapter; }; interface mixin NavigatorGPU { @@ -96,7 +97,6 @@ interface GPUAdapter { [SameObject] readonly attribute GPUSupportedFeatures features; [SameObject] readonly attribute GPUSupportedLimits limits; [SameObject] readonly attribute GPUAdapterInfo info; - readonly attribute boolean isFallbackAdapter; Promise requestDevice(optional GPUDeviceDescriptor descriptor = {}); }; @@ -936,12 +936,16 @@ interface GPUCommandEncoder { GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); + undefined copyBufferToBuffer( + GPUBuffer source, + GPUBuffer destination, + optional GPUSize64 size); undefined copyBufferToBuffer( GPUBuffer source, GPUSize64 sourceOffset, GPUBuffer destination, GPUSize64 destinationOffset, - GPUSize64 size); + optional GPUSize64 size); undefined copyBufferToTexture( GPUTexelCopyBufferInfo source, diff --git a/test/fixtures/wpt/interfaces/webnn.idl b/test/fixtures/wpt/interfaces/webnn.idl index 63554edbffd..8dc3a0ebc14 100644 --- a/test/fixtures/wpt/interfaces/webnn.idl +++ b/test/fixtures/wpt/interfaces/webnn.idl @@ -19,7 +19,7 @@ dictionary MLContextOptions { MLPowerPreference powerPreference = "default"; }; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface ML { Promise createContext(optional MLContextOptions options = {}); Promise createContext(GPUDevice gpuDevice); @@ -31,7 +31,7 @@ dictionary MLContextLostInfo { DOMString message; }; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface MLContext { undefined dispatch(MLGraph graph, MLNamedTensors inputs, MLNamedTensors outputs); @@ -71,7 +71,7 @@ dictionary MLSingleInputSupportLimits { MLSupportLimits output; }; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface MLGraph { undefined destroy(); }; @@ -97,7 +97,7 @@ dictionary MLOperandDescriptor { required sequence<[EnforceRange] unsigned long> shape; }; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface MLOperand { readonly attribute MLOperandDataType dataType; readonly attribute FrozenArray shape; @@ -114,7 +114,7 @@ dictionary MLTensorDescriptor : MLOperandDescriptor { boolean writable = false; }; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface MLTensor { readonly attribute MLOperandDataType dataType; readonly attribute FrozenArray shape; @@ -126,7 +126,7 @@ interface MLTensor { typedef record MLNamedOperands; -[SecureContext, Exposed=(Window, DedicatedWorker)] +[SecureContext, Exposed=(Window, Worker)] interface MLGraphBuilder { // Construct the graph builder from the context. constructor(MLContext context); @@ -286,6 +286,21 @@ partial dictionary MLOpSupportLimits { MLConv2dSupportLimits convTranspose2d; }; +dictionary MLCumulativeSumOptions : MLOperatorOptions { + boolean exclusive = false; + boolean reversed = false; +}; + +partial interface MLGraphBuilder { + MLOperand cumulativeSum(MLOperand input, + unsigned long axis, + optional MLCumulativeSumOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLSingleInputSupportLimits cumulativeSum; +}; + partial interface MLGraphBuilder { MLOperand add(MLOperand a, MLOperand b, optional MLOperatorOptions options = {}); MLOperand sub(MLOperand a, MLOperand b, optional MLOperatorOptions options = {}); @@ -310,6 +325,9 @@ partial interface MLGraphBuilder { MLOperand equal(MLOperand a, MLOperand b, optional MLOperatorOptions options = {}); + MLOperand notEqual(MLOperand a, + MLOperand b, + optional MLOperatorOptions options = {}); MLOperand greater(MLOperand a, MLOperand b, optional MLOperatorOptions options = {}); @@ -323,6 +341,15 @@ partial interface MLGraphBuilder { MLOperand b, optional MLOperatorOptions options = {}); MLOperand logicalNot(MLOperand a, optional MLOperatorOptions options = {}); + MLOperand logicalAnd(MLOperand a, + MLOperand b, + optional MLOperatorOptions options = {}); + MLOperand logicalOr(MLOperand a, + MLOperand b, + optional MLOperatorOptions options = {}); + MLOperand logicalXor(MLOperand a, + MLOperand b, + optional MLOperatorOptions options = {}); }; dictionary MLLogicalNotSupportLimits { @@ -332,11 +359,15 @@ dictionary MLLogicalNotSupportLimits { partial dictionary MLOpSupportLimits { MLBinarySupportLimits equal; + MLBinarySupportLimits notEqual; MLBinarySupportLimits greater; MLBinarySupportLimits greaterOrEqual; MLBinarySupportLimits lesser; MLBinarySupportLimits lesserOrEqual; MLLogicalNotSupportLimits logicalNot; + MLBinarySupportLimits logicalAnd; + MLBinarySupportLimits logicalOr; + MLBinarySupportLimits logicalXor; }; partial interface MLGraphBuilder { @@ -351,6 +382,7 @@ partial interface MLGraphBuilder { MLOperand neg(MLOperand input, optional MLOperatorOptions options = {}); MLOperand reciprocal(MLOperand input, optional MLOperatorOptions options = {}); MLOperand sin(MLOperand input, optional MLOperatorOptions options = {}); + MLOperand sign(MLOperand input, optional MLOperatorOptions options = {}); MLOperand sqrt(MLOperand input, optional MLOperatorOptions options = {}); MLOperand tan(MLOperand input, optional MLOperatorOptions options = {}); }; @@ -367,10 +399,40 @@ partial dictionary MLOpSupportLimits { MLSingleInputSupportLimits neg; MLSingleInputSupportLimits reciprocal; MLSingleInputSupportLimits sin; + MLSingleInputSupportLimits sign; MLSingleInputSupportLimits sqrt; MLSingleInputSupportLimits tan; }; +partial interface MLGraphBuilder { + MLOperand dequantizeLinear(MLOperand input, + MLOperand scale, + MLOperand zeroPoint, + optional MLOperatorOptions options = {}); +}; + +dictionary MLQuantizationSupportLimits { + MLSupportLimits input; + MLSupportLimits scale; + MLSupportLimits zeroPoint; + MLSupportLimits output; +}; + +partial dictionary MLOpSupportLimits { + MLQuantizationSupportLimits dequantizeLinear; +}; + +partial interface MLGraphBuilder { + MLOperand quantizeLinear(MLOperand input, + MLOperand scale, + MLOperand zeroPoint, + optional MLOperatorOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLQuantizationSupportLimits quantizeLinear; +}; + dictionary MLEluOptions : MLOperatorOptions { double alpha = 1; }; @@ -413,6 +475,26 @@ partial dictionary MLOpSupportLimits { MLGatherSupportLimits gather; }; +partial interface MLGraphBuilder { + MLOperand gatherElements(MLOperand input, + MLOperand indices, + optional MLGatherOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLGatherSupportLimits gatherElements; +}; + +partial interface MLGraphBuilder { + MLOperand gatherND(MLOperand input, + MLOperand indices, + optional MLOperatorOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLGatherSupportLimits gatherND; +}; + partial interface MLGraphBuilder { MLOperand gelu(MLOperand input, optional MLOperatorOptions options = {}); }; @@ -830,6 +912,51 @@ partial dictionary MLOpSupportLimits { MLSingleInputSupportLimits reshape; }; +dictionary MLReverseOptions : MLOperatorOptions { + sequence<[EnforceRange] unsigned long> axes; +}; + +partial interface MLGraphBuilder { + MLOperand reverse(MLOperand input, optional MLReverseOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLSingleInputSupportLimits reverse; +}; + +dictionary MLScatterOptions : MLOperatorOptions { + [EnforceRange] unsigned long axis = 0; +}; + +partial interface MLGraphBuilder { + MLOperand scatterElements(MLOperand input, + MLOperand indices, + MLOperand updates, + optional MLScatterOptions options = {}); +}; + +dictionary MLScatterSupportLimits { + MLSupportLimits input; + MLSupportLimits indices; + MLSupportLimits updates; + MLSupportLimits output; +}; + +partial dictionary MLOpSupportLimits { + MLScatterSupportLimits scatterElements; +}; + +partial interface MLGraphBuilder { + MLOperand scatterND(MLOperand input, + MLOperand indices, + MLOperand updates, + optional MLOperatorOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLScatterSupportLimits scatterND; +}; + partial interface MLGraphBuilder { MLOperand sigmoid(MLOperand input, optional MLOperatorOptions options = {}); }; @@ -838,14 +965,18 @@ partial dictionary MLOpSupportLimits { MLSingleInputSupportLimits sigmoid; }; +dictionary MLSliceOptions : MLOperatorOptions { + sequence<[EnforceRange] unsigned long> strides; +}; + partial interface MLGraphBuilder { MLOperand slice(MLOperand input, sequence<[EnforceRange] unsigned long> starts, sequence<[EnforceRange] unsigned long> sizes, - optional MLOperatorOptions options = {}); + optional MLSliceOptions options = {}); }; -partial dictionary MLOpSupportLimits { +partial dictionary MLOpSupportLimits { MLSingleInputSupportLimits slice; }; @@ -903,6 +1034,16 @@ partial dictionary MLOpSupportLimits { MLSingleInputSupportLimits tanh; }; +partial interface MLGraphBuilder { + MLOperand tile(MLOperand input, + sequence repetitions, + optional MLOperatorOptions options = {}); +}; + +partial dictionary MLOpSupportLimits { + MLSingleInputSupportLimits tile; +}; + dictionary MLTransposeOptions : MLOperatorOptions { sequence<[EnforceRange] unsigned long> permutation; }; diff --git a/test/fixtures/wpt/interfaces/webrtc-encoded-transform.idl b/test/fixtures/wpt/interfaces/webrtc-encoded-transform.idl index 0db2f2b9a81..8a6ba816016 100644 --- a/test/fixtures/wpt/interfaces/webrtc-encoded-transform.idl +++ b/test/fixtures/wpt/interfaces/webrtc-encoded-transform.idl @@ -75,6 +75,9 @@ dictionary RTCEncodedVideoFrameMetadata { sequence contributingSources; long long timestamp; // microseconds unsigned long rtpTimestamp; + DOMHighResTimeStamp receiveTime; + DOMHighResTimeStamp captureTime; + DOMHighResTimeStamp senderCaptureTimeOffset; DOMString mimeType; }; @@ -98,6 +101,9 @@ dictionary RTCEncodedAudioFrameMetadata { sequence contributingSources; short sequenceNumber; unsigned long rtpTimestamp; + DOMHighResTimeStamp receiveTime; + DOMHighResTimeStamp captureTime; + DOMHighResTimeStamp senderCaptureTimeOffset; DOMString mimeType; }; diff --git a/test/fixtures/wpt/interfaces/webtransport.idl b/test/fixtures/wpt/interfaces/webtransport.idl index 24fe5b7e61b..eb456336081 100644 --- a/test/fixtures/wpt/interfaces/webtransport.idl +++ b/test/fixtures/wpt/interfaces/webtransport.idl @@ -3,10 +3,18 @@ // (https://github.com/w3c/webref) // Source: WebTransport (https://w3c.github.io/webtransport/) +[Exposed=(Window,Worker), SecureContext, Transferable] +interface WebTransportDatagramsWritable : WritableStream { + attribute WebTransportSendGroup? sendGroup; + attribute long long sendOrder; +}; + [Exposed=(Window,Worker), SecureContext] interface WebTransportDatagramDuplexStream { + WebTransportDatagramsWritable createWritable( + optional WebTransportSendOptions options = {}); readonly attribute ReadableStream readable; - readonly attribute WritableStream writable; + readonly attribute WebTransportDatagramsWritable writable; readonly attribute unsigned long maxDatagramSize; attribute unrestricted double? incomingMaxAge; @@ -79,9 +87,12 @@ dictionary WebTransportCloseInfo { USVString reason = ""; }; -dictionary WebTransportSendStreamOptions { +dictionary WebTransportSendOptions { WebTransportSendGroup? sendGroup = null; long long sendOrder = 0; +}; + +dictionary WebTransportSendStreamOptions : WebTransportSendOptions { boolean waitUntilAvailable = false; }; diff --git a/test/fixtures/wpt/interfaces/webxr.idl b/test/fixtures/wpt/interfaces/webxr.idl index dea448d7440..1098000d6c2 100644 --- a/test/fixtures/wpt/interfaces/webxr.idl +++ b/test/fixtures/wpt/interfaces/webxr.idl @@ -70,6 +70,7 @@ enum XRVisibilityState { dictionary XRRenderStateInit { double depthNear; double depthFar; + boolean passthroughFullyObscured; double inlineVerticalFieldOfView; XRWebGLLayer? baseLayer; sequence? layers; @@ -78,6 +79,7 @@ dictionary XRRenderStateInit { [SecureContext, Exposed=Window] interface XRRenderState { readonly attribute double depthNear; readonly attribute double depthFar; + readonly attribute boolean? passthroughFullyObscured; readonly attribute double? inlineVerticalFieldOfView; readonly attribute XRWebGLLayer? baseLayer; }; diff --git a/test/fixtures/wpt/interfaces/xhr.idl b/test/fixtures/wpt/interfaces/xhr.idl index b4c27c8aca9..6ff75fd2774 100644 --- a/test/fixtures/wpt/interfaces/xhr.idl +++ b/test/fixtures/wpt/interfaces/xhr.idl @@ -88,12 +88,12 @@ interface ProgressEvent : Event { constructor(DOMString type, optional ProgressEventInit eventInitDict = {}); readonly attribute boolean lengthComputable; - readonly attribute unsigned long long loaded; - readonly attribute unsigned long long total; + readonly attribute double loaded; + readonly attribute double total; }; dictionary ProgressEventInit : EventInit { boolean lengthComputable = false; - unsigned long long loaded = 0; - unsigned long long total = 0; + double loaded = 0; + double total = 0; }; diff --git a/test/fixtures/wpt/resources/testdriver.js b/test/fixtures/wpt/resources/testdriver.js index 05301bf5589..15f3a4b7cc7 100644 --- a/test/fixtures/wpt/resources/testdriver.js +++ b/test/fixtures/wpt/resources/testdriver.js @@ -1428,7 +1428,7 @@ * Causes a virtual pressure source to report a new reading. * * Matches the `Update virtual pressure source - * `_ + * `_ * WebDriver command. * * @param {String} source_type - A `virtual pressure source type @@ -1437,6 +1437,8 @@ * @param {String} sample - A `virtual pressure state * `_ * such as "critical". + * @param {number} estimate - Optional, A `virtual own contribution estimate` + * `_ * @param {WindowProxy} [context=null] - Browsing context in which to * run the call, or null for the * current browsing context. @@ -1447,8 +1449,8 @@ * virtual pressure source of the given type does not * exist). */ - update_virtual_pressure_source: function(source_type, sample, context=null) { - return window.test_driver_internal.update_virtual_pressure_source(source_type, sample, context); + update_virtual_pressure_source: function(source_type, sample, estimate, context=null) { + return window.test_driver_internal.update_virtual_pressure_source(source_type, sample, estimate, context); }, /** @@ -1472,6 +1474,29 @@ */ remove_virtual_pressure_source: function(source_type, context=null) { return window.test_driver_internal.remove_virtual_pressure_source(source_type, context); + }, + + /** + * Sets which hashes are considered k-anonymous for the Protected + * Audience interest group with specified `owner` and `name`. + * + * Matches the `Set Protected Audience K-Anonymity + * + * WebDriver command. + * + * @param {String} owner - Origin of the owner of the interest group + * to modify + * @param {String} name - Name of the interest group to modify + * @param {Array} hashes - An array of strings, each of which is a + * base64 ecoded hash to consider k-anonymous. + * + * @returns {Promise} Fulfilled after the k-anonymity status for the + * specified Protected Audience interest group has + * been updated. + * + */ + set_protected_audience_k_anonymity: function(owner, name, hashes, context = null) { + return window.test_driver_internal.set_protected_audience_k_anonymity(owner, name, hashes, context); } }; @@ -1723,12 +1748,16 @@ throw new Error("create_virtual_pressure_source() is not implemented by testdriver-vendor.js"); }, - async update_virtual_pressure_source(source_type, sample, context=null) { + async update_virtual_pressure_source(source_type, sample, estimate, context=null) { throw new Error("update_virtual_pressure_source() is not implemented by testdriver-vendor.js"); }, async remove_virtual_pressure_source(source_type, context=null) { throw new Error("remove_virtual_pressure_source() is not implemented by testdriver-vendor.js"); + }, + + async set_protected_audience_k_anonymity(owner, name, hashes, context=null) { + throw new Error("set_protected_audience_k_anonymity() is not implemented by testdriver-vendor.js"); } }; })(); diff --git a/test/fixtures/wpt/resources/testharness.js b/test/fixtures/wpt/resources/testharness.js index 81cf6175588..bd668be20f8 100644 --- a/test/fixtures/wpt/resources/testharness.js +++ b/test/fixtures/wpt/resources/testharness.js @@ -1330,6 +1330,15 @@ "0xffff": "uffff", }; + const formatEscapeMap = { + "\\": "\\\\", + '"': '\\"' + }; + for (const p in replacements) { + formatEscapeMap[String.fromCharCode(p)] = "\\" + replacements[p]; + } + const formatEscapePattern = new RegExp(`[${Object.keys(formatEscapeMap).map(k => k === "\\" ? "\\\\" : k).join("")}]`, "g"); + /** * Convert a value to a nice, human-readable string * @@ -1380,12 +1389,7 @@ switch (typeof val) { case "string": - val = val.replace(/\\/g, "\\\\"); - for (var p in replacements) { - var replace = "\\" + replacements[p]; - val = val.replace(RegExp(String.fromCharCode(p), "g"), replace); - } - return '"' + val.replace(/"/g, '\\"') + '"'; + return '"' + val.replace(formatEscapePattern, match => formatEscapeMap[match]) + '"'; case "boolean": case "undefined": return String(val); @@ -4788,7 +4792,8 @@ return META_TITLE; } if ('location' in global_scope && 'pathname' in location) { - return location.pathname.substring(location.pathname.lastIndexOf('/') + 1, location.pathname.indexOf('.')); + var filename = location.pathname.substring(location.pathname.lastIndexOf('/') + 1); + return filename.substring(0, filename.indexOf('.')); } return "Untitled"; } diff --git a/test/fixtures/wpt/resources/web-bluetooth-bidi-test.js b/test/fixtures/wpt/resources/web-bluetooth-bidi-test.js new file mode 100644 index 00000000000..044ad1a43ae --- /dev/null +++ b/test/fixtures/wpt/resources/web-bluetooth-bidi-test.js @@ -0,0 +1,91 @@ +'use strict' + +// Convert `manufacturerData` to an array of bluetooth.BluetoothManufacturerData +// defined in +// https://webbluetoothcg.github.io/web-bluetooth/#bluetooth-bidi-definitions. +function convertToBidiManufacturerData(manufacturerData) { + const bidiManufacturerData = []; + for (const key in manufacturerData) { + bidiManufacturerData.push( + {key: parseInt(key), data: btoa(manufacturerData[key].buffer)}) + } + return bidiManufacturerData; +} + +class FakeBluetooth { + constructor() { + this.fake_central_ = null; + } + + // Returns a promise that resolves with a FakeCentral that clients can use + // to simulate events that a device in the Central/Observer role would + // receive as well as monitor the operations performed by the device in the + // Central/Observer role. + // + // A "Central" object would allow its clients to receive advertising events + // and initiate connections to peripherals i.e. operations of two roles + // defined by the Bluetooth Spec: Observer and Central. + // See Bluetooth 4.2 Vol 3 Part C 2.2.2 "Roles when Operating over an + // LE Physical Transport". + async simulateCentral({state}) { + if (this.fake_central_) { + throw 'simulateCentral() should only be called once'; + } + + await test_driver.bidi.bluetooth.simulate_adapter({state: state}); + this.fake_central_ = new FakeCentral(); + return this.fake_central_; + } +} + +// FakeCentral allows clients to simulate events that a device in the +// Central/Observer role would receive as well as monitor the operations +// performed by the device in the Central/Observer role. +class FakeCentral { + constructor() { + this.peripherals_ = new Map(); + } + + // Simulates a peripheral with |address|, |name|, |manufacturerData| and + // |known_service_uuids| that has already been connected to the system. If the + // peripheral existed already it updates its name, manufacturer data, and + // known UUIDs. |known_service_uuids| should be an array of + // BluetoothServiceUUIDs + // https://webbluetoothcg.github.io/web-bluetooth/#typedefdef-bluetoothserviceuuid + // + // Platforms offer methods to retrieve devices that have already been + // connected to the system or weren't connected through the UA e.g. a user + // connected a peripheral through the system's settings. This method is + // intended to simulate peripherals that those methods would return. + async simulatePreconnectedPeripheral( + {address, name, manufacturerData = {}, knownServiceUUIDs = []}) { + await test_driver.bidi.bluetooth.simulate_preconnected_peripheral({ + address: address, + name: name, + manufacturerData: convertToBidiManufacturerData(manufacturerData), + knownServiceUuids: knownServiceUUIDs + }); + + return this.fetchOrCreatePeripheral_(address); + } + + // Create a fake_peripheral object from the given address. + fetchOrCreatePeripheral_(address) { + let peripheral = this.peripherals_.get(address); + if (peripheral === undefined) { + peripheral = new FakePeripheral(address); + this.peripherals_.set(address, peripheral); + } + return peripheral; + } +} + +class FakePeripheral { + constructor(address) { + this.address = address; + } +} + +function initializeBluetoothBidiResources() { + navigator.bluetooth.test = new FakeBluetooth(); +} diff --git a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html index fc8edb4b896..0a35cc7c39c 100644 --- a/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html +++ b/test/fixtures/wpt/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html @@ -2,9 +2,10 @@ Service Worker GlobalScope onerror event + - + diff --git a/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html b/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html index 7e2a604621d..5ef91dd1b11 100644 --- a/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html +++ b/test/fixtures/wpt/service-workers/service-worker/controlled-dedicatedworker-postMessage.https.html @@ -1,5 +1,6 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html b/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html index 8f39b7fdbf8..c3f390a5a45 100644 --- a/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html +++ b/test/fixtures/wpt/service-workers/service-worker/controlled-iframe-postMessage.https.html @@ -1,5 +1,6 @@ + diff --git a/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html b/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html new file mode 100644 index 00000000000..2785142a3cf --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/detached-register-crash.https.html @@ -0,0 +1,14 @@ + + +Assures navigator.serviceWorker.register() doesn't crash when rejecting being called in a detached frame + + + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html new file mode 100644 index 00000000000..d6135d95c88 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/content-encoding.https.html @@ -0,0 +1,25 @@ + + +Navigation Preload with content encoding + + + + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-scope.py b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-scope.py new file mode 100644 index 00000000000..bd9601d1578 --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-scope.py @@ -0,0 +1,7 @@ +import gzip + +def main(request, response): + response.headers.set(b"Content-Type", b"text/html; charset=UTF-8") + response.headers.set(b"Content-Encoding", b"gzip") + response.content = gzip.compress(bytes(u"Hello World", 'utf-8')) + diff --git a/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js new file mode 100644 index 00000000000..f30e5ed274d --- /dev/null +++ b/test/fixtures/wpt/service-workers/service-worker/navigation-preload/resources/content-encoding-worker.js @@ -0,0 +1,8 @@ +self.addEventListener('activate', event => { + event.waitUntil( + self.registration.navigationPreload.enable()); + }); + +self.addEventListener('fetch', event => { + event.respondWith(event.preloadResponse); + }); diff --git a/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html b/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html index a39ceadd9f3..82475eabc4a 100644 --- a/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html +++ b/test/fixtures/wpt/service-workers/service-worker/request-end-to-end.https.html @@ -29,12 +29,16 @@ 'TypeError.') assert_equals(result.credentials, 'include', 'request.credentials'); assert_equals(result.redirect, 'manual', 'request.redirect'); - assert_equals(result.headers['user-agent'], undefined, - 'Default User-Agent header should not be passed to ' + - 'onfetch event.') assert_equals(result.append_header_error, 'TypeError', 'Appending a new header to the request must throw a ' + 'TypeError.') + + // `assert_equals()` is not used here to create a stable failure + // baseline, because the User-Agent header would be version-dependent + // if set. + assert_true(result.headers['user-agent'] === undefined, + 'Default User-Agent header should not be passed to ' + + 'onfetch event.') }); }, 'Test FetchEvent.request passed to onfetch'); diff --git a/test/fixtures/wpt/xhr/progressevent-constructor.html b/test/fixtures/wpt/xhr/progressevent-constructor.html index 0e771f4459f..3b9c774b874 100644 --- a/test/fixtures/wpt/xhr/progressevent-constructor.html +++ b/test/fixtures/wpt/xhr/progressevent-constructor.html @@ -40,6 +40,36 @@ assert_equals(ev.loaded, 2) }, "ECMAScript value conversion test.") test(function() { + var ev = new ProgressEvent(null, { loaded: 1, total: 2 }) + assert_equals(ev.type, "null") + assert_equals(ev.loaded, 1) + assert_equals(ev.total, 2) +}, "Positive integer number test.") +test(function () { + var ev = new ProgressEvent(null, { loaded: 0, total: 1 }) + assert_equals(ev.type, "null") + assert_equals(ev.loaded, 0) + assert_equals(ev.total, 1) +}, "Zero test.") +test(function () { + var ev = new ProgressEvent(null, { loaded: 1.5, total: 3.5 }) + assert_equals(ev.type, "null") + assert_equals(ev.loaded, 1.5) + assert_equals(ev.total, 3.5) +}, "Decimal number test.") +test(function () { + var ev = new ProgressEvent(null, { loaded: 1.5, total: 5 }) + assert_equals(ev.type, "null") + assert_equals(ev.loaded, 1.5) + assert_equals(ev.total, 5) +}, "Mixed integer and decimal number test.") +test(function () { + var ev = new ProgressEvent(null, { loaded: -1, total: -5.5 }) + assert_equals(ev.type, "null") + assert_equals(ev.loaded, -1) + assert_equals(ev.total, -5.5) +}, "Negative number.") +test(function () { var ev = new ProgressEvent("Xx", { lengthcomputable: true}) assert_equals(ev.type, "Xx") assert_equals(ev.lengthComputable, false) diff --git a/test/fixtures/wpt/xhr/progressevent-interface.html b/test/fixtures/wpt/xhr/progressevent-interface.html index 7552ff73d3f..ec8d471d783 100644 --- a/test/fixtures/wpt/xhr/progressevent-interface.html +++ b/test/fixtures/wpt/xhr/progressevent-interface.html @@ -23,8 +23,8 @@ }, "interface prototype object") var attributes = [ ["boolean", "lengthComputable"], - ["unsigned long long", "loaded"], - ["unsigned long long", "total"] + ["double", "loaded"], + ["double", "total"] ]; attributes.forEach(function(a) { test(function() { diff --git a/test/fixtures/wpt/xhr/resources/redirect.py b/test/fixtures/wpt/xhr/resources/redirect.py index 3839b635e02..e2786b45031 100644 --- a/test/fixtures/wpt/xhr/resources/redirect.py +++ b/test/fixtures/wpt/xhr/resources/redirect.py @@ -1,10 +1,15 @@ import time +from urllib.parse import parse_qs from wptserve.utils import isomorphic_encode def main(request, response): code = int(request.GET.first(b"code", 302)) location = request.GET.first(b"location", isomorphic_encode(request.url_parts.path + u"?followed")) + if location: + location = parse_qs(u"location=" + location.decode(u"UTF-8"))[u"location"][0] + if location.startswith(u"redirect.py"): + location += u"&code=" + str(code) if b"delay" in request.GET: delay = float(request.GET.first(b"delay")) diff --git a/test/fixtures/wpt/xhr/send-redirect.htm b/test/fixtures/wpt/xhr/send-redirect.htm index 7d73f0f64cc..de3899f5e5d 100644 --- a/test/fixtures/wpt/xhr/send-redirect.htm +++ b/test/fixtures/wpt/xhr/send-redirect.htm @@ -10,36 +10,73 @@
diff --git a/test/fixtures/wpt/xhr/setrequestheader-case-insensitive.htm b/test/fixtures/wpt/xhr/setrequestheader-case-insensitive.htm index 1aed30d1c2a..ce10482cad8 100644 --- a/test/fixtures/wpt/xhr/setrequestheader-case-insensitive.htm +++ b/test/fixtures/wpt/xhr/setrequestheader-case-insensitive.htm @@ -9,26 +9,28 @@
diff --git a/test/get-head-body.js b/test/get-head-body.js index 4e58bc0f5a5..4168cf23090 100644 --- a/test/get-head-body.js +++ b/test/get-head-body.js @@ -12,7 +12,7 @@ const { wrapWithAsyncIterable } = require('./utils/async-iterators') test('GET and HEAD with body should reset connection', async (t) => { t = tspl(t, { plan: 8 + 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) @@ -140,7 +140,7 @@ test('GET and HEAD with body should reset connection', async (t) => { test('HEAD should reset connection', async (t) => { t = tspl(t, { plan: 8 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) diff --git a/test/headers-as-array.js b/test/headers-as-array.js index 693979e92b7..9fd4e738af8 100644 --- a/test/headers-as-array.js +++ b/test/headers-as-array.js @@ -9,7 +9,7 @@ test('handle headers as array', async (t) => { t = tspl(t, { plan: 3 }) const headers = ['a', '1', 'b', '2', 'c', '3'] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers.a, '1') t.strictEqual(req.headers.b, '2') t.strictEqual(req.headers.c, '3') @@ -34,7 +34,7 @@ test('handle multi-valued headers as array', async (t) => { t = tspl(t, { plan: 4 }) const headers = ['a', '1', 'b', '2', 'c', '3', 'd', '4', 'd', '5'] - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers.a, '1') t.strictEqual(req.headers.b, '2') t.strictEqual(req.headers.c, '3') @@ -60,7 +60,7 @@ test('handle headers with array', async (t) => { t = tspl(t, { plan: 4 }) const headers = { a: '1', b: '2', c: '3', d: ['4'] } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers.a, '1') t.strictEqual(req.headers.b, '2') t.strictEqual(req.headers.c, '3') @@ -86,7 +86,7 @@ test('handle multi-valued headers', async (t) => { t = tspl(t, { plan: 4 }) const headers = { a: '1', b: '2', c: '3', d: ['4', '5'] } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.headers.a, '1') t.strictEqual(req.headers.b, '2') t.strictEqual(req.headers.c, '3') @@ -112,7 +112,7 @@ test('fail if headers array is odd', async (t) => { t = tspl(t, { plan: 2 }) const headers = ['a', '1', 'b', '2', 'c', '3', 'd'] - const server = createServer((req, res) => { res.end() }) + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -135,7 +135,7 @@ test('fail if headers is not an object or an array', async (t) => { t = tspl(t, { plan: 2 }) const headers = 'not an object or an array' - const server = createServer((req, res) => { res.end() }) + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) diff --git a/test/headers-crlf.js b/test/headers-crlf.js index 8660259dbbd..ee440e06045 100644 --- a/test/headers-crlf.js +++ b/test/headers-crlf.js @@ -9,7 +9,7 @@ const { createServer } = require('node:http') test('CRLF Injection in Nodejs ‘undici’ via host', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.end() }) after(() => server.close()) diff --git a/test/http-100.js b/test/http-100.js index d961a2c421b..055a01faaa5 100644 --- a/test/http-100.js +++ b/test/http-100.js @@ -10,7 +10,7 @@ const { once } = require('node:events') test('ignore informational response', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() req.pipe(res) }) @@ -42,7 +42,7 @@ test('ignore informational response', async (t) => { test('error 103 body', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { socket.write('HTTP/1.1 103 Early Hints\r\n') socket.write('Content-Length: 1\r\n') socket.write('\r\n') @@ -71,7 +71,7 @@ test('error 103 body', async (t) => { test('error 100 body', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { socket.write('HTTP/1.1 100 Early Hints\r\n') socket.write('\r\n') }) @@ -97,7 +97,7 @@ test('error 100 body', async (t) => { test('error 101 upgrade', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((socket) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (socket) => { socket.write('HTTP/1.1 101 Switching Protocols\r\nUpgrade: example/1\r\nConnection: Upgrade\r\n') socket.write('\r\n') }) @@ -123,7 +123,7 @@ test('error 101 upgrade', async (t) => { test('1xx response without timeouts', async t => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeProcessing() setTimeout(() => req.pipe(res), 2000) }) diff --git a/test/http-req-destroy.js b/test/http-req-destroy.js index ea7624c611d..6c748b950f6 100644 --- a/test/http-req-destroy.js +++ b/test/http-req-destroy.js @@ -11,7 +11,7 @@ function doNotKillReqSocket (bodyType) { test(`do not kill req socket ${bodyType}`, async (t) => { t = tspl(t, { plan: 3 }) - const server1 = createServer((req, res) => { + const server1 = createServer({ joinDuplicateHeaders: true }, (req, res) => { const client = new undici.Client(`http://localhost:${server2.address().port}`) after(() => client.close()) client.request({ @@ -32,7 +32,7 @@ function doNotKillReqSocket (bodyType) { }) after(() => server1.close()) - const server2 = createServer((req, res) => { + const server2 = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { req.pipe(res) }, 100) diff --git a/test/https.js b/test/https.js index 418fb969f45..89e55b6a5ae 100644 --- a/test/https.js +++ b/test/https.js @@ -9,7 +9,7 @@ const pem = require('https-pem') test('https get with tls opts', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer(pem, (req, res) => { + const server = createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -45,7 +45,7 @@ test('https get with tls opts', async (t) => { test('https get with tls opts ip', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer(pem, (req, res) => { + const server = createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') diff --git a/test/inflight-and-close.js b/test/inflight-and-close.js index 075cdba1668..3e0a532bb9c 100644 --- a/test/inflight-and-close.js +++ b/test/inflight-and-close.js @@ -8,7 +8,7 @@ const http = require('node:http') test('inflight and close', async (t) => { t = tspl(t, { plan: 3 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200) res.end('Response body') res.socket.end() // Close the connection immediately with every response diff --git a/test/interceptors/cache-fastimers-fix.js b/test/interceptors/cache-fastimers-fix.js index 65650ceefc4..6fd45d861c3 100644 --- a/test/interceptors/cache-fastimers-fix.js +++ b/test/interceptors/cache-fastimers-fix.js @@ -9,7 +9,7 @@ const { setTimeout: sleep } = require('timers/promises') test('revalidates the request when the response is stale', async () => { let count = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Cache-Control', 'public, max-age=1') res.end('hello world ' + count++) }) diff --git a/test/interceptors/cache.js b/test/interceptors/cache.js index dc120c60b7b..6ea6ec35ea2 100644 --- a/test/interceptors/cache.js +++ b/test/interceptors/cache.js @@ -10,7 +10,7 @@ const { Client, interceptors, cacheStores: { MemoryCacheStore } } = require('../ describe('Cache Interceptor', () => { test('caches request', async () => { let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { requestsToOrigin++ res.setHeader('cache-control', 's-maxage=10') res.end('asd') @@ -53,7 +53,7 @@ describe('Cache Interceptor', () => { test('vary directives used to decide which response to use', async () => { let requestsToOrigin = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { requestsToOrigin++ res.setHeader('cache-control', 's-maxage=10') res.setHeader('vary', 'a') @@ -135,22 +135,30 @@ describe('Cache Interceptor', () => { let requestsToOrigin = 0 let revalidationRequests = 0 - const server = createServer((req, res) => { + let serverError + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('date', 0) res.setHeader('cache-control', 's-maxage=1, stale-while-revalidate=10') - if (req.headers['if-modified-since']) { - revalidationRequests++ + try { + if (req.headers['if-modified-since']) { + equal(req.headers['if-modified-since'].length, 29) + + revalidationRequests++ - if (revalidationRequests === 2) { - res.end('updated') + if (revalidationRequests === 3) { + res.end('updated') + } else { + res.statusCode = 304 + res.end() + } } else { - res.statusCode = 304 - res.end() + requestsToOrigin++ + res.end('asd') } - } else { - requestsToOrigin++ - res.end('asd') + } catch (err) { + serverError = err + res.end() } }).listen(0) @@ -188,6 +196,10 @@ describe('Cache Interceptor', () => { // Send initial request. This should reach the origin { const res = await client.request(request) + if (serverError) { + throw serverError + } + equal(requestsToOrigin, 1) equal(revalidationRequests, 0) strictEqual(await res.body.text(), 'asd') @@ -198,16 +210,42 @@ describe('Cache Interceptor', () => { // Response is now stale, the origin should get a revalidation request { const res = await client.request(request) + if (serverError) { + throw serverError + } + equal(requestsToOrigin, 1) equal(revalidationRequests, 1) strictEqual(await res.body.text(), 'asd') } + // Response is still stale, extra header should be overwritten, and the + // origin should get a revalidation request + { + const res = await client.request({ + ...request, + headers: { + 'if-modified-SINCE': 'Thu, 01 Jan 1970 00:00:00 GMT' + } + }) + if (serverError) { + throw serverError + } + + equal(requestsToOrigin, 1) + equal(revalidationRequests, 2) + strictEqual(await res.body.text(), 'asd') + } + // Response is still stale, but revalidation should fail now. { const res = await client.request(request) + if (serverError) { + throw serverError + } + equal(requestsToOrigin, 1) - equal(revalidationRequests, 2) + equal(revalidationRequests, 3) strictEqual(await res.body.text(), 'updated') } }) @@ -220,7 +258,7 @@ describe('Cache Interceptor', () => { let requestsToOrigin = 0 let revalidationRequests = 0 let serverError - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('date', 0) res.setHeader('cache-control', 's-maxage=1, stale-while-revalidate=10') @@ -230,7 +268,7 @@ describe('Cache Interceptor', () => { equal(req.headers['if-none-match'], '"asd123"') - if (revalidationRequests === 2) { + if (revalidationRequests === 3) { res.end('updated') } else { res.statusCode = 304 @@ -296,6 +334,24 @@ describe('Cache Interceptor', () => { strictEqual(await res.body.text(), 'asd') } + // Response is still stale, extra headers should be overwritten, and the + // origin should get a revalidation request + { + const res = await client.request({ + ...request, + headers: { + 'if-NONE-match': '"nonsense-etag"' + } + }) + if (serverError) { + throw serverError + } + + equal(requestsToOrigin, 1) + equal(revalidationRequests, 2) + strictEqual(await res.body.text(), 'asd') + } + // Response is still stale, but revalidation should fail now. { const res = await client.request(request) @@ -304,7 +360,7 @@ describe('Cache Interceptor', () => { } equal(requestsToOrigin, 1) - equal(revalidationRequests, 2) + equal(revalidationRequests, 3) strictEqual(await res.body.text(), 'updated') } }) @@ -317,7 +373,7 @@ describe('Cache Interceptor', () => { let requestsToOrigin = 0 let revalidationRequests = 0 let serverError - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('date', 0) res.setHeader('cache-control', 's-maxage=1, stale-while-revalidate=10') @@ -327,13 +383,13 @@ describe('Cache Interceptor', () => { if (ifNoneMatch) { revalidationRequests++ notEqual(req.headers.a, undefined) - notEqual(req.headers.b, undefined) + notEqual(req.headers['b-mixed-case'], undefined) res.statusCode = 304 res.end() } else { requestsToOrigin++ - res.setHeader('vary', 'a, b') + res.setHeader('vary', 'a, B-MIXED-CASe') res.setHeader('etag', '"asd"') res.end('asd') } @@ -360,15 +416,17 @@ describe('Cache Interceptor', () => { const request = { origin: 'localhost', path: '/', - method: 'GET', - headers: { - a: 'asd', - b: 'asd' - } + method: 'GET' } { - const response = await client.request(request) + const response = await client.request({ + ...request, + headers: { + a: 'asd', + 'b-Mixed-case': 'asd' + } + }) if (serverError) { throw serverError } @@ -380,7 +438,13 @@ describe('Cache Interceptor', () => { clock.tick(1500) { - const response = await client.request(request) + const response = await client.request({ + ...request, + headers: { + a: 'asd', + 'B-mixed-CASE': 'asd' + } + }) if (serverError) { throw serverError } @@ -392,7 +456,7 @@ describe('Cache Interceptor', () => { }) test('unsafe methods cause resource to be purged from cache', async () => { - const server = createServer((_, res) => res.end('asd')).listen(0) + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => res.end('asd')).listen(0) after(() => server.close()) await once(server, 'listening') @@ -441,7 +505,7 @@ describe('Cache Interceptor', () => { }) test('unsafe methods aren\'t cached', async () => { - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { res.setHeader('cache-control', 'public, s-maxage=1') res.end('') }).listen(0) @@ -485,7 +549,7 @@ describe('Cache Interceptor', () => { ] let requestToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { requestToOrigin++ res.setHeader('cache-control', 's-maxage=10, no-cache=should-be-stripped') res.setHeader('should-not-be-stripped', 'asd') @@ -540,7 +604,7 @@ describe('Cache Interceptor', () => { test('cacheByDefault', async () => { let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { requestsToOrigin++ res.end('asd') }).listen(0) @@ -583,7 +647,7 @@ describe('Cache Interceptor', () => { }) let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { res.setHeader('date', 0) requestsToOrigin++ @@ -665,7 +729,7 @@ describe('Cache Interceptor', () => { }) let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { requestsToOrigin++ res.setHeader('date', 0) res.setHeader('cache-control', 'public, s-maxage=100') @@ -727,7 +791,7 @@ describe('Cache Interceptor', () => { let requestsToOrigin = 0 let revalidationRequests = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('date', 0) res.setHeader('cache-control', 'public, s-maxage=1, stale-while-revalidate=10') @@ -796,7 +860,7 @@ describe('Cache Interceptor', () => { }) let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { requestsToOrigin++ res.setHeader('date', 0) res.setHeader('cache-control', 'public, s-maxage=10') @@ -855,7 +919,7 @@ describe('Cache Interceptor', () => { test('no-cache', async () => { let requestsToOrigin = 0 let revalidationRequests = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.headers['if-modified-since']) { revalidationRequests++ res.statusCode = 304 @@ -914,7 +978,7 @@ describe('Cache Interceptor', () => { }) test('no-store', async () => { - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { res.setHeader('cache-control', 'public, s-maxage=100') res.end('asd') }).listen(0) @@ -946,7 +1010,7 @@ describe('Cache Interceptor', () => { test('only-if-cached', async () => { let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { res.setHeader('cache-control', 'public, s-maxage=100') res.end('asd') requestsToOrigin++ @@ -1014,7 +1078,7 @@ describe('Cache Interceptor', () => { }) let requestsToOrigin = 0 - const server = createServer((_, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (_, res) => { res.setHeader('date', 0) requestsToOrigin++ diff --git a/test/interceptors/dns.js b/test/interceptors/dns.js index 75fc21faec6..0d7e633bff6 100644 --- a/test/interceptors/dns.js +++ b/test/interceptors/dns.js @@ -33,7 +33,7 @@ test('Should automatically resolve IPs (dual stack)', async t => { t = tspl(t, { plan: 8 }) const hostsnames = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -201,7 +201,7 @@ test('Should recover on network errors (dual stack - 4)', async t => { t = tspl(t, { plan: 7 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -290,7 +290,7 @@ test('Should recover on network errors (dual stack - 6)', async t => { t = tspl(t, { plan: 7 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -466,7 +466,7 @@ test('Should automatically resolve IPs (dual stack disabled - 4)', async t => { t = tspl(t, { plan: 6 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -537,7 +537,7 @@ test('Should automatically resolve IPs (dual stack disabled - 6)', async t => { t = tspl(t, { plan: 6 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -611,7 +611,7 @@ test('Should we handle TTL (4)', async t => { const clock = FakeTimers.install() let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -714,7 +714,7 @@ test('Should we handle TTL (6)', async t => { const clock = FakeTimers.install() let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -818,7 +818,7 @@ test('Should set lowest TTL between resolved and option maxTTL', async t => { const clock = FakeTimers.install() let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -911,7 +911,7 @@ test('Should use all dns entries (dual stack)', async t => { let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1001,7 +1001,7 @@ test('Should use all dns entries (dual stack disabled - 4)', async t => { let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1097,7 +1097,7 @@ test('Should use all dns entries (dual stack disabled - 6)', async t => { let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1195,7 +1195,7 @@ test('Should handle single family resolved (dual stack)', async t => { const clock = FakeTimers.install() let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1286,7 +1286,7 @@ test('Should prefer affinity (dual stack - 4)', async t => { const clock = FakeTimers.install() let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1388,7 +1388,7 @@ test('Should prefer affinity (dual stack - 6)', async t => { const clock = FakeTimers.install() let counter = 0 let lookupCounter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1488,8 +1488,8 @@ test('Should use resolved ports (4)', async t => { t = tspl(t, { plan: 5 }) let lookupCounter = 0 - const server1 = createServer() - const server2 = createServer() + const server1 = createServer({ joinDuplicateHeaders: true }) + const server2 = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1556,8 +1556,8 @@ test('Should use resolved ports (6)', async t => { t = tspl(t, { plan: 5 }) let lookupCounter = 0 - const server1 = createServer() - const server2 = createServer() + const server1 = createServer({ joinDuplicateHeaders: true }) + const server2 = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1624,8 +1624,8 @@ test('Should handle max cached items', async t => { t = tspl(t, { plan: 9 }) let counter = 0 - const server1 = createServer() - const server2 = createServer() + const server1 = createServer({ joinDuplicateHeaders: true }) + const server2 = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -1833,7 +1833,7 @@ test('#3937 - Handle host correctly', async t => { t = tspl(t, { plan: 10 }) const hostsnames = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', diff --git a/test/interceptors/dump-interceptor.js b/test/interceptors/dump-interceptor.js index ba6dbe83c02..cc29f4d30ba 100644 --- a/test/interceptors/dump-interceptor.js +++ b/test/interceptors/dump-interceptor.js @@ -17,7 +17,7 @@ if (platform() === 'win32') { test('Should dump on abort', async t => { t = tspl(t, { plan: 2 }) let offset = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const max = 1024 * 1024 const buffer = Buffer.alloc(max) @@ -79,7 +79,7 @@ test('Should dump on abort', async t => { test('Should dump on already aborted request', async t => { t = tspl(t, { plan: 3 }) let offset = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const max = 1024 const buffer = Buffer.alloc(max) @@ -139,7 +139,7 @@ test('Should dump on already aborted request', async t => { test('Should dump response body up to limit (default)', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const buffer = Buffer.alloc(1024 * 1024) res.writeHead(200, { 'Content-Length': buffer.length, @@ -181,7 +181,7 @@ test('Should dump response body up to limit (default)', async t => { test('Should dump response body up to limit and ignore trailers', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked', @@ -225,7 +225,7 @@ test('Should dump response body up to limit and ignore trailers', async t => { test('Should forward common error', async t => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) @@ -358,7 +358,7 @@ test('Should throw on bad opts', async t => { test('Should dump response body up to limit (opts)', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const buffer = Buffer.alloc(1 * 1024) res.writeHead(200, { 'Content-Length': buffer.length, @@ -399,7 +399,7 @@ test('Should dump response body up to limit (opts)', async t => { test('Should abort if content length grater than max size', async t => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const buffer = Buffer.alloc(2 * 1024) res.writeHead(200, { 'Content-Length': buffer.length, @@ -438,7 +438,7 @@ test('Should abort if content length grater than max size', async t => { test('Should dump response body up to limit (dispatch opts)', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const buffer = Buffer.alloc(1 * 1024) res.writeHead(200, { 'Content-Length': buffer.length, @@ -481,7 +481,7 @@ test('Should dump response body up to limit (dispatch opts)', async t => { test('Should abort if content length grater than max size (dispatch opts)', async t => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const buffer = Buffer.alloc(2 * 1024) res.writeHead(200, { 'Content-Length': buffer.length, diff --git a/test/interceptors/redirect-issue-3803.js b/test/interceptors/redirect-issue-3803.js index a66bfa237a9..ee5d72591a4 100644 --- a/test/interceptors/redirect-issue-3803.js +++ b/test/interceptors/redirect-issue-3803.js @@ -9,7 +9,7 @@ const { tspl } = require('@matteo.collina/tspl') test('redirecting works with a FormData body', async (t) => { const plan = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/1') { res.writeHead(302, undefined, { location: '/2' }) res.end() diff --git a/test/interceptors/redirect.js b/test/interceptors/redirect.js index c337f1f45ae..59db5d3d90c 100644 --- a/test/interceptors/redirect.js +++ b/test/interceptors/redirect.js @@ -752,7 +752,7 @@ test('should redirect to relative URL according to RFC 7231', async t => { test('Cross-origin redirects clear forbidden headers', async (t) => { const { strictEqual } = tspl(t, { plan: 6 }) - const server1 = createServer((req, res) => { + const server1 = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.cookie, undefined) strictEqual(req.headers.authorization, undefined) strictEqual(req.headers['proxy-authorization'], undefined) @@ -760,7 +760,7 @@ test('Cross-origin redirects clear forbidden headers', async (t) => { res.end('redirected') }).listen(0) - const server2 = createServer((req, res) => { + const server2 = createServer({ joinDuplicateHeaders: true }, (req, res) => { strictEqual(req.headers.authorization, 'test') strictEqual(req.headers.cookie, 'ddd=dddd') diff --git a/test/interceptors/response-error.js b/test/interceptors/response-error.js index 157d5130b2f..925cd96e8ba 100644 --- a/test/interceptors/response-error.js +++ b/test/interceptors/response-error.js @@ -8,7 +8,7 @@ const { interceptors, Client } = require('../..') const { responseError } = interceptors test('should throw error for error response', async () => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400, { 'content-type': 'text/plain' }) @@ -49,7 +49,7 @@ test('should throw error for error response', async () => { }) test('should not throw error for ok response', async () => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) @@ -84,7 +84,7 @@ test('should not throw error for ok response', async () => { }) test('should throw error for error response, parsing JSON', async () => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400, { 'content-type': 'application/json; charset=utf-8' }) @@ -127,7 +127,7 @@ test('should throw error for error response, parsing JSON', async () => { }) test('should throw error for error response, parsing JSON without charset', async () => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400, { 'content-type': 'application/json' }) @@ -195,7 +195,7 @@ test('should throw error for networking errors response', async () => { }) test('should throw error for error response without content type', async () => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400, {}) diff --git a/test/interceptors/retry.js b/test/interceptors/retry.js index 9ec033d09da..b97aa36d099 100644 --- a/test/interceptors/retry.js +++ b/test/interceptors/retry.js @@ -13,7 +13,7 @@ test('Should retry status code', async t => { t = tspl(t, { plan: 4 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const retryOptions = { retry: (err, { state, opts }, done) => { counter++ @@ -122,7 +122,7 @@ test('Should use retry-after header for retries', async t => { t = tspl(t, { plan: 3 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let checkpoint const dispatchOptions = { method: 'PUT', @@ -178,7 +178,7 @@ test('Should use retry-after header for retries (date)', async t => { t = tspl(t, { plan: 3 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let checkpoint const requestOptions = { method: 'PUT', @@ -236,7 +236,7 @@ test('Should retry with defaults', async t => { t = tspl(t, { plan: 2 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/', @@ -290,7 +290,7 @@ test('Should retry with defaults', async t => { test('Should pass context from other interceptors', async t => { t = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'GET', path: '/' @@ -329,7 +329,7 @@ test('Should handle 206 partial content', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.ok(true, 'pass') res.setHeader('content-length', '6') @@ -397,7 +397,7 @@ test('Should handle 206 partial content - bad-etag', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.ok(true, 'pass') res.setHeader('etag', 'asd') @@ -463,7 +463,7 @@ test('Should handle 206 partial content - bad-etag', async t => { test('retrying a request with a body', async t => { t = tspl(t, { plan: 2 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestOptions = { method: 'POST', path: '/', @@ -528,7 +528,7 @@ test('retrying a request with a body', async t => { test('should not error if request is not meant to be retried', async t => { t = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400) res.end('Bad request') diff --git a/test/issue-2065.js b/test/issue-2065.js index 9037fb557c3..2d17b879cfe 100644 --- a/test/issue-2065.js +++ b/test/issue-2065.js @@ -10,7 +10,7 @@ const { File } = require('node:buffer') test('undici.request with a FormData body should set content-length header', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.ok(req.headers['content-length']) res.end() }).listen(0) diff --git a/test/issue-2590.js b/test/issue-2590.js index 1da0b23f20a..e24fe4e953b 100644 --- a/test/issue-2590.js +++ b/test/issue-2590.js @@ -8,7 +8,7 @@ const { once } = require('node:events') test('aborting request with custom reason', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer(() => {}).listen(0) + const server = createServer({ joinDuplicateHeaders: true }, () => {}).listen(0) after(() => server.close()) await once(server, 'listening') diff --git a/test/issue-3356.js b/test/issue-3356.js index 1f671fbe3e1..40cecde1386 100644 --- a/test/issue-3356.js +++ b/test/issue-3356.js @@ -12,7 +12,7 @@ test('https://github.com/nodejs/undici/issues/3356', { skip: process.env.CITGM } t = tspl(t, { plan: 3 }) let shouldRetry = true - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) if (shouldRetry) { diff --git a/test/issue-3934.js b/test/issue-3934.js index 19c1544c213..3898f1144c6 100644 --- a/test/issue-3934.js +++ b/test/issue-3934.js @@ -8,7 +8,7 @@ const { Agent, RetryAgent, request } = require('..') // https://github.com/nodejs/undici/issues/3934 test('WrapHandler works with multiple header values', async (t) => { - const server = createServer(async (_req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (_req, res) => { const headers = [ ['set-cookie', 'a'], ['set-cookie', 'b'], diff --git a/test/issue-3959.js b/test/issue-3959.js index 2d83a6030e0..59bfab50789 100644 --- a/test/issue-3959.js +++ b/test/issue-3959.js @@ -8,7 +8,7 @@ const { interceptors } = require('..') describe('Cache with Vary headers', () => { async function runCacheTest (store) { let requestCount = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { requestCount++ res.setHeader('Vary', 'Accept-Encoding') res.setHeader('Cache-Control', 'max-age=60') diff --git a/test/issue-803.js b/test/issue-803.js index 5c2eb21b6e5..12540100f8d 100644 --- a/test/issue-803.js +++ b/test/issue-803.js @@ -10,7 +10,7 @@ test('https://github.com/nodejs/undici/issues/803', { timeout: 60000 }, async (t t = tspl(t, { plan: 2 }) const SIZE = 5900373096 - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { const chunkSize = res.writableHighWaterMark << 5 const parts = (SIZE / chunkSize) | 0 const lastPartSize = SIZE % chunkSize diff --git a/test/jest/instanceof-error.test.js b/test/jest/instanceof-error.test.js index 30667262dee..c93b81d6e42 100644 --- a/test/jest/instanceof-error.test.js +++ b/test/jest/instanceof-error.test.js @@ -23,7 +23,7 @@ it('Real use-case', async () => { const ac = new AbortController() ac.abort() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }).listen(0) diff --git a/test/jest/test.js b/test/jest/test.js index 4be7556e27e..02fed2d902e 100644 --- a/test/jest/test.js +++ b/test/jest/test.js @@ -5,7 +5,7 @@ const { createServer } = require('node:http') /* global test, expect */ test('should work in jest', async () => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { expect(req.url).toBe('/') expect(req.method).toBe('POST') expect(req.headers.host).toBe(`localhost:${server.address().port}`) diff --git a/test/max-headers.js b/test/max-headers.js index 0f1422a60b4..9edd8d1efdc 100644 --- a/test/max-headers.js +++ b/test/max-headers.js @@ -14,7 +14,7 @@ test('handle a lot of headers', async (t) => { headers[n] = String(n) } - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, headers) res.end() }) diff --git a/test/max-response-size.js b/test/max-response-size.js index 1e0d904469a..648a4cb08a0 100644 --- a/test/max-response-size.js +++ b/test/max-response-size.js @@ -9,7 +9,7 @@ describe('max response size', async (t) => { test('default max default size should allow all responses', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) after(() => server.close()) server.on('request', (req, res) => { @@ -39,7 +39,7 @@ describe('max response size', async (t) => { test('max response size set to zero should allow only empty responses', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) after(() => server.close()) server.on('request', (req, res) => { @@ -69,7 +69,7 @@ describe('max response size', async (t) => { test('should throw an error if the response is too big', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) after(() => server.close()) server.on('request', (req, res) => { diff --git a/test/mock-agent.js b/test/mock-agent.js index aac6585e5e8..5f6488f04eb 100644 --- a/test/mock-agent.js +++ b/test/mock-agent.js @@ -269,7 +269,7 @@ test('MockAgent - .close should clean up registered clients', async (t) => { test('MockAgent - [kClients] should match encapsulated agent', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -299,7 +299,7 @@ test('MockAgent - [kClients] should match encapsulated agent', async (t) => { test('MockAgent - basic intercept with MockAgent.request', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -343,7 +343,7 @@ test('MockAgent - basic intercept with MockAgent.request', async (t) => { test('MockAgent - basic intercept with request', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -386,7 +386,7 @@ test('MockAgent - basic intercept with request', async (t) => { test('MockAgent - should support local agents', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -432,7 +432,7 @@ test('MockAgent - should support local agents', async (t) => { test('MockAgent - should support specifying custom agents to mock', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -479,7 +479,7 @@ test('MockAgent - should support specifying custom agents to mock', async (t) => test('MockAgent - basic Client intercept with request', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -524,7 +524,7 @@ test('MockAgent - basic Client intercept with request', async (t) => { test('MockAgent - basic intercept with multiple pools', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -576,7 +576,7 @@ test('MockAgent - basic intercept with multiple pools', async (t) => { test('MockAgent - should handle multiple responses for an interceptor', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -639,7 +639,7 @@ test('MockAgent - should handle multiple responses for an interceptor', async (t test('MockAgent - should call original Pool dispatch if request not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -668,7 +668,7 @@ test('MockAgent - should call original Pool dispatch if request not found', asyn test('MockAgent - should call original Client dispatch if request not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -697,7 +697,7 @@ test('MockAgent - should call original Client dispatch if request not found', as test('MockAgent - should handle string responses', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -761,7 +761,7 @@ test('MockAgent - should handle basic concurrency for requests', { jobs: 5 }, as test('MockAgent - handle delays to simulate work', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -799,7 +799,7 @@ test('MockAgent - handle delays to simulate work', async (t) => { test('MockAgent - should persist requests', async (t) => { t = tspl(t, { plan: 8 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1060,7 +1060,7 @@ test('MockAgent - clearCallHistory should clear call history logs', async (t) => test('MockAgent - handle persists with delayed requests', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1106,7 +1106,7 @@ test('MockAgent - handle persists with delayed requests', async (t) => { test('MockAgent - calling close on a mock pool should not affect other mock pools', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1164,7 +1164,7 @@ test('MockAgent - calling close on a mock pool should not affect other mock pool test('MockAgent - close removes all registered mock clients', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1220,7 +1220,7 @@ test('MockAgent - close clear all registered mock call history logs', async (t) test('MockAgent - close removes all registered mock pools', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1254,7 +1254,7 @@ test('MockAgent - close removes all registered mock pools', async (t) => { test('MockAgent - should handle replyWithError', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1282,7 +1282,7 @@ test('MockAgent - should handle replyWithError', async (t) => { test('MockAgent - should support setting a reply to respond a set amount of times', async (t) => { t = tspl(t, { plan: 9 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -1333,7 +1333,7 @@ test('MockAgent - should support setting a reply to respond a set amount of time test('MockAgent - persist overrides times', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1389,7 +1389,7 @@ test('MockAgent - persist overrides times', async (t) => { test('MockAgent - matcher should not find mock dispatch if path is of unsupported type', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.end('hello') @@ -1422,7 +1422,7 @@ test('MockAgent - matcher should not find mock dispatch if path is of unsupporte test('MockAgent - should match path with regex', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1468,7 +1468,7 @@ test('MockAgent - should match path with regex', async (t) => { test('MockAgent - should match path with function', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1502,7 +1502,7 @@ test('MockAgent - should match path with function', async (t) => { test('MockAgent - should match method with regex', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1536,7 +1536,7 @@ test('MockAgent - should match method with regex', async (t) => { test('MockAgent - should match method with function', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1570,7 +1570,7 @@ test('MockAgent - should match method with function', async (t) => { test('MockAgent - should match body with regex', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1606,7 +1606,7 @@ test('MockAgent - should match body with regex', async (t) => { test('MockAgent - should match body with function', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1642,7 +1642,7 @@ test('MockAgent - should match body with function', async (t) => { test('MockAgent - should match headers with string', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('should not be called') t.fail('should not be called') t.end() @@ -1715,7 +1715,7 @@ test('MockAgent - should match headers with string', async (t) => { test('MockAgent - should match headers with regex', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('should not be called') t.fail('should not be called') t.end() @@ -1788,7 +1788,7 @@ test('MockAgent - should match headers with regex', async (t) => { test('MockAgent - should match headers with function', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('should not be called') t.fail('should not be called') t.end() @@ -1861,7 +1861,7 @@ test('MockAgent - should match headers with function', async (t) => { test('MockAgent - should match url with regex', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1895,7 +1895,7 @@ test('MockAgent - should match url with regex', async (t) => { test('MockAgent - should match url with function', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1929,7 +1929,7 @@ test('MockAgent - should match url with function', async (t) => { test('MockAgent - handle default reply headers', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -1967,7 +1967,7 @@ test('MockAgent - handle default reply headers', async (t) => { test('MockAgent - handle default reply trailers', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -2005,7 +2005,7 @@ test('MockAgent - handle default reply trailers', async (t) => { test('MockAgent - return calculated content-length if specified', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -2043,7 +2043,7 @@ test('MockAgent - return calculated content-length if specified', async (t) => { test('MockAgent - return calculated content-length for object response if specified', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -2081,7 +2081,7 @@ test('MockAgent - return calculated content-length for object response if specif test('MockAgent - should activate and deactivate mock clients', async (t) => { t = tspl(t, { plan: 9 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2142,7 +2142,7 @@ test('MockAgent - should activate and deactivate mock clients', async (t) => { test('MockAgent - enableNetConnect should allow all original dispatches to be called if dispatch not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2179,7 +2179,7 @@ test('MockAgent - enableNetConnect should allow all original dispatches to be ca test('MockAgent - enableNetConnect with a host string should allow all original dispatches to be called if mockDispatch not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2216,7 +2216,7 @@ test('MockAgent - enableNetConnect with a host string should allow all original test('MockAgent - enableNetConnect when called with host string multiple times should allow all original dispatches to be called if mockDispatch not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2254,7 +2254,7 @@ test('MockAgent - enableNetConnect when called with host string multiple times s test('MockAgent - enableNetConnect with a host regex should allow all original dispatches to be called if mockDispatch not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2291,7 +2291,7 @@ test('MockAgent - enableNetConnect with a host regex should allow all original d test('MockAgent - enableNetConnect with a function should allow all original dispatches to be called if mockDispatch not found', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2344,7 +2344,7 @@ test('MockAgent - enableNetConnect with an unknown input should throw', async (t test('MockAgent - enableNetConnect should throw if dispatch not matched for path and the origin was not allowed by net connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2375,7 +2375,7 @@ test('MockAgent - enableNetConnect should throw if dispatch not matched for path test('MockAgent - enableNetConnect should throw if dispatch not matched for method and the origin was not allowed by net connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2406,7 +2406,7 @@ test('MockAgent - enableNetConnect should throw if dispatch not matched for meth test('MockAgent - enableNetConnect should throw if dispatch not matched for body and the origin was not allowed by net connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2439,7 +2439,7 @@ test('MockAgent - enableNetConnect should throw if dispatch not matched for body test('MockAgent - enableNetConnect should throw if dispatch not matched for headers and the origin was not allowed by net connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2476,7 +2476,7 @@ test('MockAgent - enableNetConnect should throw if dispatch not matched for head test('MockAgent - disableNetConnect should throw if dispatch not found by net connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(req.url, '/foo') t.strictEqual(req.method, 'GET') res.setHeader('content-type', 'text/plain') @@ -2508,7 +2508,7 @@ test('MockAgent - disableNetConnect should throw if dispatch not found by net co test('MockAgent - headers function interceptor', async (t) => { t = tspl(t, { plan: 8 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2570,7 +2570,7 @@ test('MockAgent - clients are not garbage collected', async (t) => { const samples = 250 t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not be called') t.end() res.end('should not be called') @@ -2833,7 +2833,7 @@ test('MockAgent - Sending ReadableStream body', async (t) => { const mockAgent = new MockAgent() setGlobalDispatcher(mockAgent) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') req.pipe(res) }) diff --git a/test/mock-client.js b/test/mock-client.js index 9b8f416ec34..fd77f0047b8 100644 --- a/test/mock-client.js +++ b/test/mock-client.js @@ -198,7 +198,7 @@ test('MockClient - close should run without error', async (t) => { test('MockClient - should be able to set as globalDispatcher', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -234,7 +234,7 @@ test('MockClient - should be able to set as globalDispatcher', async (t) => { test('MockClient - should support query params', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -275,7 +275,7 @@ test('MockClient - should support query params', async (t) => { test('MockClient - should intercept query params with hardcoded path', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -315,7 +315,7 @@ test('MockClient - should intercept query params with hardcoded path', async (t) test('MockClient - should intercept query params regardless of key ordering', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -363,7 +363,7 @@ test('MockClient - should intercept query params regardless of key ordering', as test('MockClient - should be able to use as a local dispatcher', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -399,7 +399,7 @@ test('MockClient - should be able to use as a local dispatcher', async (t) => { test('MockClient - basic intercept with MockClient.request', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') diff --git a/test/mock-pool.js b/test/mock-pool.js index b52d3406cce..4e079451741 100644 --- a/test/mock-pool.js +++ b/test/mock-pool.js @@ -184,7 +184,7 @@ test('MockPool - close should run without error', async (t) => { test('MockPool - should be able to set as globalDispatcher', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -220,7 +220,7 @@ test('MockPool - should be able to set as globalDispatcher', async (t) => { test('MockPool - should be able to use as a local dispatcher', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') @@ -256,7 +256,7 @@ test('MockPool - should be able to use as a local dispatcher', async (t) => { test('MockPool - basic intercept with MockPool.request', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('should not be called') t.fail('should not be called') diff --git a/test/no-strict-content-length.js b/test/no-strict-content-length.js index aa3d1725cb2..4779bfcd862 100644 --- a/test/no-strict-content-length.js +++ b/test/no-strict-content-length.js @@ -28,7 +28,7 @@ describe('strictContentLength: false', () => { test('request invalid content-length', async (t) => { t = tspl(t, { plan: 8 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -146,7 +146,7 @@ describe('strictContentLength: false', () => { test('request streaming content-length less than body size', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -183,7 +183,7 @@ describe('strictContentLength: false', () => { test('request streaming content-length greater than body size', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -220,7 +220,7 @@ describe('strictContentLength: false', () => { test('request streaming data when content-length=0', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -257,7 +257,7 @@ describe('strictContentLength: false', () => { test('request async iterating content-length less than body size', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -294,7 +294,7 @@ describe('strictContentLength: false', () => { test('request async iterator content-length greater than body size', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -330,7 +330,7 @@ describe('strictContentLength: false', () => { test('request async iterator data when content-length=0', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) diff --git a/test/node-fetch/main.js b/test/node-fetch/main.js index 1473caf198c..149292b2a56 100644 --- a/test/node-fetch/main.js +++ b/test/node-fetch/main.js @@ -1621,7 +1621,7 @@ describe('node-fetch', () => { it('should support http request', { timeout: 5000 }, async function (t) { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) diff --git a/test/node-fetch/utils/server.js b/test/node-fetch/utils/server.js index 233c30da106..a6cfb2d3459 100644 --- a/test/node-fetch/utils/server.js +++ b/test/node-fetch/utils/server.js @@ -7,7 +7,7 @@ const Busboy = require('@fastify/busboy') module.exports = class TestServer { constructor () { - this.server = http.createServer(this.router) + this.server = http.createServer({ joinDuplicateHeaders: true }, this.router) // Node 8 default keepalive timeout is 5000ms // make it shorter here as we want to close server quickly at the end of tests this.server.keepAliveTimeout = 1000 diff --git a/test/node-test/abort-controller.js b/test/node-test/abort-controller.js index 6db151e5d16..f8249c13039 100644 --- a/test/node-test/abort-controller.js +++ b/test/node-test/abort-controller.js @@ -24,7 +24,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { test(`Abort ${controllerName} before creating request`, async (t) => { const p = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { p.fail() }) t.after(closeServerAsPromise(server)) @@ -48,7 +48,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 3 }) let count = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (count === 1) { p.fail('The second request should never be executed') } @@ -87,7 +87,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 1 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { abortController.abort() res.setHeader('content-type', 'text/plain') res.end('hello world') @@ -110,7 +110,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 1 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.flushHeaders() abortController.abort() @@ -134,7 +134,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 2 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.write('hello') }) @@ -163,7 +163,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 1 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { abortController.abort() res.setHeader('content-type', 'text/plain') res.end('hello world') @@ -192,7 +192,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 1 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.flushHeaders() abortController.abort() @@ -222,7 +222,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) { const p = tspl(t, { plan: 2 }) const abortController = new AbortControllerImpl() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.write('hello') }) diff --git a/test/node-test/abort-event-emitter.js b/test/node-test/abort-event-emitter.js index ad7231331cb..6f7a010f649 100644 --- a/test/node-test/abort-event-emitter.js +++ b/test/node-test/abort-event-emitter.js @@ -14,7 +14,7 @@ test('Abort before sending request (no body)', async (t) => { const p = tspl(t, { plan: 4 }) let count = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (count === 1) { p.fail('The second request should never be executed') } @@ -63,7 +63,7 @@ test('Abort before sending request (no body) async iterator', async (t) => { const p = tspl(t, { plan: 3 }) let count = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (count === 1) { t.fail('The second request should never be executed') } @@ -109,7 +109,7 @@ test('Abort while waiting response (no body)', async (t) => { const p = tspl(t, { plan: 1 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { ee.emit('abort') res.setHeader('content-type', 'text/plain') res.end('hello world') @@ -132,7 +132,7 @@ test('Abort while waiting response (write headers started) (no body)', async (t) const p = tspl(t, { plan: 1 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.flushHeaders() ee.emit('abort') @@ -156,7 +156,7 @@ test('Abort while waiting response (write headers and write body started) (no bo const p = tspl(t, { plan: 2 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.write('hello') }) @@ -184,7 +184,7 @@ function waitingWithBody (body, type) { const p = tspl(t, { plan: 1 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { ee.emit('abort') res.setHeader('content-type', 'text/plain') res.end('hello world') @@ -213,7 +213,7 @@ function writeHeadersStartedWithBody (body, type) { const p = tspl(t, { plan: 1 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.flushHeaders() ee.emit('abort') @@ -243,7 +243,7 @@ function writeBodyStartedWithBody (body, type) { const p = tspl(t, { plan: 2 }) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.write('hello') }) diff --git a/test/node-test/agent.js b/test/node-test/agent.js index c5238d7b570..6f7d7ffe53c 100644 --- a/test/node-test/agent.js +++ b/test/node-test/agent.js @@ -45,7 +45,7 @@ test('agent should call callback after closing internal pools', async (t) => { const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end(wanted) }) @@ -97,7 +97,7 @@ test('agent should close internal pools', async (t) => { const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end(wanted) }) @@ -138,7 +138,7 @@ test('agent should destroy internal pools and call callback', async (t) => { const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end(wanted) }) @@ -200,7 +200,7 @@ test('agent should destroy internal pools', async t => { const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end(wanted) }) @@ -239,7 +239,7 @@ test('multiple connections', async t => { const connections = 3 const p = tspl(t, { plan: 6 * connections }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Connection: 'keep-alive', 'Keep-Alive': 'timeout=1s' @@ -299,7 +299,7 @@ test('agent factory supports URL parameter', async (t) => { } }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('asd') }) @@ -337,7 +337,7 @@ test('agent factory supports string parameter', async (t) => { } }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('asd') }) @@ -357,7 +357,7 @@ test('with globalAgent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -392,7 +392,7 @@ test('with local agent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -443,7 +443,7 @@ test('with globalAgent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -484,7 +484,7 @@ test('with a local agent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -544,7 +544,7 @@ test('with globalAgent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -585,7 +585,7 @@ test('with a local agent', async t => { const p = tspl(t, { plan: 6 }) const wanted = 'payload' - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -681,7 +681,7 @@ test('dispatch validations', async t => { } } - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('asd') }) @@ -726,7 +726,7 @@ test('drain', async t => { } } - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('asd') }) @@ -747,7 +747,7 @@ test('drain', async t => { test('global api', async t => { const p = tspl(t, { plan: 6 * 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/bar') { p.strictEqual(req.method, 'PUT') p.strictEqual(req.url, '/bar') diff --git a/test/node-test/async_hooks.js b/test/node-test/async_hooks.js index 63d42dd1082..a454266a880 100644 --- a/test/node-test/async_hooks.js +++ b/test/node-test/async_hooks.js @@ -37,7 +37,7 @@ hook.enable() test('async hooks', async (t) => { const p = tspl(t, { plan: 31 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') readFile(__filename, (err, buf) => { p.ifError(err) @@ -148,7 +148,7 @@ test('async hooks', async (t) => { test('async hooks client is destroyed', async (t) => { const p = tspl(t, { plan: 7 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') readFile(__filename, (err, buf) => { p.ifError(err) @@ -187,7 +187,7 @@ test('async hooks client is destroyed', async (t) => { test('async hooks pipeline handler', async (t) => { const p = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) t.after(closeServerAsPromise(server)) diff --git a/test/node-test/autoselectfamily.js b/test/node-test/autoselectfamily.js index 4baf1ab0aa1..1314a328676 100644 --- a/test/node-test/autoselectfamily.js +++ b/test/node-test/autoselectfamily.js @@ -67,7 +67,7 @@ test('with autoSelectFamily enable the request succeeds when using request', { s const p = tspl(t, { plan: 3 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) @@ -107,7 +107,7 @@ test('with autoSelectFamily enable the request succeeds when using a client', { const p = tspl(t, { plan: 3 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) @@ -148,7 +148,7 @@ test('with autoSelectFamily disabled the request fails when using request', { sk const p = tspl(t, { plan: 1 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) @@ -176,7 +176,7 @@ test('with autoSelectFamily disabled via Agent.Options["autoSelectFamily"] the r const p = tspl(t, { plan: 1 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) @@ -204,7 +204,7 @@ test('with autoSelectFamily disabled the request fails when using a client', { s const p = tspl(t, { plan: 1 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) @@ -233,7 +233,7 @@ test('with autoSelectFamily disabled via Client.Options["autoSelectFamily"] the const p = tspl(t, { plan: 1 }) createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) diff --git a/test/node-test/balanced-pool.js b/test/node-test/balanced-pool.js index 725c31ed190..d2f3bdd0bb1 100644 --- a/test/node-test/balanced-pool.js +++ b/test/node-test/balanced-pool.js @@ -52,7 +52,7 @@ test('basic get', async (t) => { const p = tspl(t, { plan: 16 }) let server1Called = 0 - const server1 = createServer((req, res) => { + const server1 = createServer({ joinDuplicateHeaders: true }, (req, res) => { server1Called++ p.strictEqual('/', req.url) p.strictEqual('GET', req.method) @@ -64,7 +64,7 @@ test('basic get', async (t) => { await promisify(server1.listen).call(server1, 0) let server2Called = 0 - const server2 = createServer((req, res) => { + const server2 = createServer({ joinDuplicateHeaders: true }, (req, res) => { server2Called++ p.strictEqual('/', req.url) p.strictEqual('GET', req.method) @@ -109,7 +109,7 @@ test('connect/disconnect event(s)', async (t) => { const p = tspl(t, { plan: clients * 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Connection: 'keep-alive', 'Keep-Alive': 'timeout=1s' @@ -151,7 +151,7 @@ test('connect/disconnect event(s)', async (t) => { test('busy', async (t) => { const p = tspl(t, { plan: 8 * 6 + 2 + 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -205,7 +205,7 @@ test('factory option with basic get request', async (t) => { const client = new BalancedPool([], opts) let serverCalled = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { serverCalled++ p.strictEqual('/', req.url) p.strictEqual('GET', req.method) @@ -298,7 +298,7 @@ class TestServer { } start () { - this.server = createServer((req, res) => { + this.server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (this._shouldHangupOnClient()) { req.destroy(new Error('(ツ)')) return diff --git a/test/node-test/ca-fingerprint.js b/test/node-test/ca-fingerprint.js index bad8aeff555..54b9d7adc31 100644 --- a/test/node-test/ca-fingerprint.js +++ b/test/node-test/ca-fingerprint.js @@ -17,7 +17,7 @@ const caFingerprint = getFingerprint(pem.cert.toString() test('Validate CA fingerprint with a custom connector', async t => { const p = tspl(t, { plan: 2 }) - const server = https.createServer(pem, (req, res) => { + const server = https.createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('hello') }) @@ -64,7 +64,7 @@ test('Validate CA fingerprint with a custom connector', async t => { test('Bad CA fingerprint with a custom connector', async t => { const p = tspl(t, { plan: 2 }) - const server = https.createServer(pem, (req, res) => { + const server = https.createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.end('hello') }) diff --git a/test/node-test/client-abort.js b/test/node-test/client-abort.js index 52395f0dbfb..cf0c6fc1553 100644 --- a/test/node-test/client-abort.js +++ b/test/node-test/client-abort.js @@ -11,7 +11,7 @@ class OnAbortError extends Error {} test('aborted response errors', async (t) => { const p = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { // TODO: res.write will cause body to emit 'error' twice // due to bug in readable-stream. @@ -42,7 +42,7 @@ test('aborted response errors', async (t) => { test('aborted req', async (t) => { const p = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(Buffer.alloc(4 + 1, 'a')) }) t.after(server.close.bind(server)) @@ -72,7 +72,7 @@ test('aborted req', async (t) => { test('abort', async (t) => { const p = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(server.close.bind(server)) @@ -113,7 +113,7 @@ test('abort', async (t) => { test('abort pipelined', async (t) => { const p = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) t.after(server.close.bind(server)) @@ -183,7 +183,7 @@ test('abort pipelined', async (t) => { test('propagate unallowed throws in request.onError', async (t) => { const p = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(server.close.bind(server)) diff --git a/test/node-test/client-connect.js b/test/node-test/client-connect.js index 28271d348cf..e201cedaaad 100644 --- a/test/node-test/client-connect.js +++ b/test/node-test/client-connect.js @@ -11,7 +11,7 @@ const { closeServerAsPromise } = require('../utils/node-http') test('basic connect', async (t) => { const p = tspl(t, { plan: 3 }) - const server = http.createServer((c) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (c) => { p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -60,7 +60,7 @@ test('basic connect', async (t) => { test('connect error', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((c) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (c) => { p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -115,7 +115,7 @@ test('connect wait for empty pipeline', async (t) => { const p = tspl(t, { plan: 7 }) let canConnect = false - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() canConnect = true }) @@ -184,7 +184,7 @@ test('connect wait for empty pipeline', async (t) => { test('connect aborted', async (t) => { const p = tspl(t, { plan: 6 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.ok(0) }) server.on('connect', (req, c, firstBodyChunk) => { @@ -225,7 +225,7 @@ test('connect aborted', async (t) => { test('basic connect error', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((c) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (c) => { p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -264,7 +264,7 @@ test('basic connect error', async (t) => { test('connect invalid signal', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.ok(0) }) server.on('connect', (req, c, firstBodyChunk) => { diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index 8b7991a3156..0f467f75cb4 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -94,7 +94,7 @@ test('dispatch invalid opts', (t) => { test('basic dispatch get', async (t) => { const p = tspl(t, { plan: 11 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -147,7 +147,7 @@ test('basic dispatch get', async (t) => { test('trailers dispatch get', async (t) => { const p = tspl(t, { plan: 12 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.strictEqual('/', req.url) p.strictEqual('GET', req.method) p.strictEqual(`localhost:${server.address().port}`, req.headers.host) @@ -209,7 +209,7 @@ test('trailers dispatch get', async (t) => { test('dispatch onHeaders error', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(closeServerAsPromise(server)) @@ -246,7 +246,7 @@ test('dispatch onHeaders error', async (t) => { test('dispatch onComplete error', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) t.after(closeServerAsPromise(server)) @@ -283,7 +283,7 @@ test('dispatch onComplete error', async (t) => { test('dispatch onData error', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -320,7 +320,7 @@ test('dispatch onData error', async (t) => { test('dispatch onConnect error', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -358,7 +358,7 @@ test('dispatch onConnect error', async (t) => { test('connect call onUpgrade once', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((c) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (c) => { p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -422,7 +422,7 @@ test('connect call onUpgrade once', async (t) => { test('dispatch onHeaders missing', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -455,7 +455,7 @@ test('dispatch onHeaders missing', async (t) => { test('dispatch onData missing', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -488,7 +488,7 @@ test('dispatch onData missing', async (t) => { test('dispatch onComplete missing', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -521,7 +521,7 @@ test('dispatch onComplete missing', async (t) => { test('dispatch onError missing', async (t) => { const p = tspl(t, { plan: 1 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -558,7 +558,7 @@ test('dispatch onError missing', async (t) => { test('dispatch CONNECT onUpgrade missing', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -589,7 +589,7 @@ test('dispatch CONNECT onUpgrade missing', async (t) => { test('dispatch upgrade onUpgrade missing', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -620,7 +620,7 @@ test('dispatch upgrade onUpgrade missing', async (t) => { test('dispatch pool onError missing', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -647,7 +647,7 @@ test('dispatch pool onError missing', async (t) => { test('dispatch onBodySent not a function', async (t) => { const p = tspl(t, { plan: 2 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -677,7 +677,7 @@ test('dispatch onBodySent not a function', async (t) => { test('dispatch onBodySent buffer', async (t) => { const p = tspl(t, { plan: 3 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -714,7 +714,7 @@ test('dispatch onBodySent buffer', async (t) => { test('dispatch onBodySent stream', async (t) => { const p = tspl(t, { plan: 8 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -756,7 +756,7 @@ test('dispatch onBodySent stream', async (t) => { }) test('dispatch onBodySent async-iterable', (t, done) => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ad') }) t.after(closeServerAsPromise(server)) @@ -792,7 +792,7 @@ test('dispatch onBodySent async-iterable', (t, done) => { }) test('dispatch onBodySent throws error', (t, done) => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ended') }) t.after(closeServerAsPromise(server)) @@ -823,7 +823,7 @@ test('dispatch onBodySent throws error', (t, done) => { }) test('dispatches in expected order', async (t) => { - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('ended') }) t.after(closeServerAsPromise(server)) @@ -929,7 +929,7 @@ test('dispatches in expected order for http2', async (t) => { test('Issue#3065 - fix bad destroy handling', async (t) => { const p = tspl(t, { plan: 4 }) - const server = https.createServer(pem, (req, res) => { + const server = https.createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }) res.end('ended') }) diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index 39f04678dc6..83a7e8a5064 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -20,7 +20,7 @@ class IteratorError extends Error {} test('GET errors and reconnect with pipelining 1', async (t) => { const p = tspl(t, { plan: 9 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { // first request received, destroying @@ -65,7 +65,7 @@ test('GET errors and reconnect with pipelining 1', async (t) => { }) test('GET errors and reconnect with pipelining 3', async (t) => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const requestsThatWillError = 3 let requests = 0 @@ -126,7 +126,7 @@ function errorAndPipelining (type) { test(`POST with a ${type} that errors and pipelining 1 should reconnect`, async (t) => { const p = tspl(t, { plan: 12 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { p.strictEqual('/', req.url) p.strictEqual('POST', req.method) @@ -201,7 +201,7 @@ function errorAndChunkedEncodingPipelining (type) { test(`POST with chunked encoding, ${type} body that errors and pipelining 1 should reconnect`, async (t) => { const p = tspl(t, { plan: 12 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { p.strictEqual('/', req.url) p.strictEqual('POST', req.method) @@ -600,7 +600,7 @@ test('invalid options throws', (t, done) => { test('POST which fails should error response', async (t) => { const p = tspl(t, { plan: 6 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { req.once('data', () => { res.destroy() @@ -693,7 +693,7 @@ test('client destroy cleanup', async (t) => { const _err = new Error('kaboom') let client - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { req.once('data', () => { client.destroy(_err, (err) => { @@ -728,7 +728,7 @@ test('client destroy cleanup', async (t) => { test('throwing async-iterator causes error', async (t) => { const p = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end(Buffer.alloc(4 + 1, 'a')) }) t.after(closeServerAsPromise(server)) @@ -757,7 +757,7 @@ test('client async-iterator destroy cleanup', async (t) => { const _err = new Error('kaboom') let client - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { req.once('data', () => { client.destroy(_err, (err) => { @@ -788,7 +788,7 @@ test('client async-iterator destroy cleanup', async (t) => { test('GET errors body', async (t) => { const p = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { res.write('asd') setTimeout(() => { @@ -816,7 +816,7 @@ test('GET errors body', async (t) => { test('validate request body', async (t) => { const p = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) t.after(closeServerAsPromise(server)) @@ -884,7 +884,7 @@ function socketFailWrite (type) { test(`socket fail while writing ${type} request body`, async (t) => { const p = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { }) t.after(closeServerAsPromise(server)) @@ -924,7 +924,7 @@ function socketFailEndWrite (type) { test(`socket fail while ending ${type} request body`, async (t) => { const p = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { res.end() }) @@ -971,7 +971,7 @@ socketFailEndWrite(consts.ASYNC_ITERATOR) test('queued request should not fail on socket destroy', async (t) => { const p = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end() }) @@ -1010,7 +1010,7 @@ test('queued request should not fail on socket destroy', async (t) => { test('queued request should fail on client destroy', async (t) => { const p = tspl(t, { plan: 6 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end() }) @@ -1054,7 +1054,7 @@ test('queued request should fail on client destroy', async (t) => { test('retry idempotent inflight', async (t) => { const p = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end() }) @@ -1161,7 +1161,7 @@ test('default port for http and https', async (t) => { test('CONNECT throws in next tick', async (t) => { const p = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end() }) @@ -1225,7 +1225,7 @@ test('invalid signal', async (t) => { test('invalid body chunk does not crash', async (t) => { const p = tspl(t, { plan: 1 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.end() }) @@ -1269,7 +1269,7 @@ test('socket errors', async (t) => { test('headers overflow', (t, done) => { const p = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(200, { 'x-test-1': '1', @@ -1296,7 +1296,7 @@ test('headers overflow', (t, done) => { test('SocketError should expose socket details (net)', async (t) => { const p = tspl(t, { plan: 8 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { res.destroy() @@ -1330,7 +1330,7 @@ test('SocketError should expose socket details (net)', async (t) => { test('SocketError should expose socket details (tls)', async (t) => { const p = tspl(t, { plan: 8 }) - const server = https.createServer(pem) + const server = https.createServer({ ...pem, joinDuplicateHeaders: true }) server.once('request', (req, res) => { res.destroy() @@ -1369,7 +1369,7 @@ test('SocketError should expose socket details (tls)', async (t) => { test('parser error', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer() + const server = net.createServer({ joinDuplicateHeaders: true }) server.once('connection', (socket) => { socket.write('asd\n\r213123') }) diff --git a/test/node-test/diagnostics-channel/error.js b/test/node-test/diagnostics-channel/error.js index ce6e0978146..1a62055d533 100644 --- a/test/node-test/diagnostics-channel/error.js +++ b/test/node-test/diagnostics-channel/error.js @@ -8,7 +8,7 @@ const { createServer } = require('node:http') test('Diagnostics channel - error', (t) => { const assert = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) after(server.close.bind(server)) diff --git a/test/node-test/diagnostics-channel/get.js b/test/node-test/diagnostics-channel/get.js index 397dfa3bc5f..20b2672c22a 100644 --- a/test/node-test/diagnostics-channel/get.js +++ b/test/node-test/diagnostics-channel/get.js @@ -8,7 +8,7 @@ const { createServer } = require('node:http') test('Diagnostics channel - get', (t) => { const assert = tspl(t, { plan: 32 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Content-Type', 'text/plain') res.setHeader('trailer', 'foo') res.write('hello') diff --git a/test/node-test/diagnostics-channel/post-stream.js b/test/node-test/diagnostics-channel/post-stream.js index 881873a7c1c..27cafe2af56 100644 --- a/test/node-test/diagnostics-channel/post-stream.js +++ b/test/node-test/diagnostics-channel/post-stream.js @@ -9,7 +9,7 @@ const { createServer } = require('node:http') test('Diagnostics channel - post stream', (t) => { const assert = tspl(t, { plan: 33 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.resume() res.setHeader('Content-Type', 'text/plain') res.setHeader('trailer', 'foo') diff --git a/test/node-test/diagnostics-channel/post.js b/test/node-test/diagnostics-channel/post.js index 1408ffbf023..d18de2a567a 100644 --- a/test/node-test/diagnostics-channel/post.js +++ b/test/node-test/diagnostics-channel/post.js @@ -8,7 +8,7 @@ const { createServer } = require('node:http') test('Diagnostics channel - post', (t) => { const assert = tspl(t, { plan: 33 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { req.resume() res.setHeader('Content-Type', 'text/plain') res.setHeader('trailer', 'foo') diff --git a/test/node-test/large-body.js b/test/node-test/large-body.js index 8707fe04d03..615e7319865 100644 --- a/test/node-test/large-body.js +++ b/test/node-test/large-body.js @@ -8,7 +8,7 @@ const { strictEqual } = require('node:assert') test('socket should not be reused unless body is consumed', async (t) => { const LARGE_BODY = 'x'.repeat(10000000) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (req.url === '/foo') { res.end(LARGE_BODY) return diff --git a/test/node-test/unix.js b/test/node-test/unix.js index cdeda6d1b3d..6ea46146583 100644 --- a/test/node-test/unix.js +++ b/test/node-test/unix.js @@ -14,7 +14,7 @@ test('http unix get', { skip }, async (t) => { let client const p = tspl(t, { plan: 7 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.equal('/', req.url) p.equal('GET', req.method) p.equal('localhost', req.headers.host) @@ -63,7 +63,7 @@ test('http unix get pool', { skip }, async (t) => { let client const p = tspl(t, { plan: 7 }) - const server = http.createServer((req, res) => { + const server = http.createServer({ joinDuplicateHeaders: true }, (req, res) => { p.equal('/', req.url) p.equal('GET', req.method) p.equal('localhost', req.headers.host) @@ -112,7 +112,7 @@ test('https get with tls opts', { skip }, async (t) => { let client const p = tspl(t, { plan: 6 }) - const server = https.createServer(pem, (req, res) => { + const server = https.createServer({ ...pem, joinDuplicateHeaders: true }, (req, res) => { p.equal('/', req.url) p.equal('GET', req.method) res.setHeader('content-type', 'text/plain') diff --git a/test/node-test/validations.js b/test/node-test/validations.js index f23f910ed21..5f25b834dcb 100644 --- a/test/node-test/validations.js +++ b/test/node-test/validations.js @@ -9,7 +9,7 @@ test('validations', async t => { let client const p = tspl(t, { plan: 10 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('content-type', 'text/plain') res.end('hello') p.fail('server should never be called') diff --git a/test/pipeline-pipelining.js b/test/pipeline-pipelining.js index 27ea1bb21ed..bb4cf22e84f 100644 --- a/test/pipeline-pipelining.js +++ b/test/pipeline-pipelining.js @@ -10,7 +10,7 @@ const { kBusy, kPending, kRunning } = require('../lib/core/symbols') test('pipeline pipelining', async (t) => { t = tspl(t, { plan: 10 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.deepStrictEqual(req.headers['transfer-encoding'], undefined) res.end() }) @@ -54,7 +54,7 @@ test('pipeline pipelining retry', async (t) => { t = tspl(t, { plan: 13 }) let count = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (count++ === 0) { res.destroy() } else { diff --git a/test/pool-connection-error-memory-leak.js b/test/pool-connection-error-memory-leak.js index fc9c7deb4cf..7ecaa601c4e 100644 --- a/test/pool-connection-error-memory-leak.js +++ b/test/pool-connection-error-memory-leak.js @@ -102,7 +102,7 @@ test('Pool client count does not grow on repeated connection errors', async (t) // This test specifically verifies the fix in pool-base.js for connectionError event test('Pool clients are removed on connectionError event', async (t) => { // Create a server we'll use to track connection events - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('ok') }) diff --git a/test/pool.js b/test/pool.js index b75cd530d43..2b847af70d3 100644 --- a/test/pool.js +++ b/test/pool.js @@ -79,7 +79,7 @@ test('connect/disconnect event(s)', async (t) => { t = tspl(t, { plan: clients * 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Connection: 'keep-alive', 'Keep-Alive': 'timeout=1s' @@ -122,7 +122,7 @@ test('connect/disconnect event(s)', async (t) => { test('basic get', async (t) => { t = tspl(t, { plan: 14 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -170,7 +170,7 @@ test('basic get', async (t) => { test('URL as arg', async (t) => { t = tspl(t, { plan: 9 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -214,7 +214,7 @@ test('URL as arg', async (t) => { test('basic get error async/await', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) after(() => server.close()) @@ -241,7 +241,7 @@ test('basic get error async/await', async (t) => { test('basic get with async/await', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -267,7 +267,7 @@ test('basic get with async/await', async (t) => { test('stream get async/await', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -291,7 +291,7 @@ test('stream get async/await', async (t) => { test('stream get error async/await', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.destroy() }) after(() => server.close()) @@ -314,7 +314,7 @@ test('stream get error async/await', async (t) => { test('pipeline get', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -425,7 +425,7 @@ test('backpressure algorithm', async (t) => { test('busy', async (t) => { t = tspl(t, { plan: 8 * 16 + 2 + 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -488,7 +488,7 @@ test('invalid pool dispatch options', async (t) => { test('pool upgrade promise', async (t) => { t = tspl(t, { plan: 2 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -537,7 +537,7 @@ test('pool upgrade promise', async (t) => { test('pool connect', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((c) => { + const server = createServer({ joinDuplicateHeaders: true }, (c) => { t.fail() }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -581,7 +581,7 @@ test('pool connect', async (t) => { test('pool dispatch', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -631,7 +631,7 @@ test('pool pipeline args validation', async (t) => { test('300 requests succeed', async (t) => { t = tspl(t, { plan: 300 * 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -663,7 +663,7 @@ test('300 requests succeed', async (t) => { test('pool connect error', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((c) => { + const server = createServer({ joinDuplicateHeaders: true }, (c) => { t.fail() }) server.on('connect', (req, socket, firstBodyChunk) => { @@ -690,7 +690,7 @@ test('pool connect error', async (t) => { test('pool upgrade error', async (t) => { t = tspl(t, { plan: 1 }) - const server = net.createServer((c) => { + const server = net.createServer({ joinDuplicateHeaders: true }, (c) => { c.on('data', (d) => { c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') @@ -726,7 +726,7 @@ test('pool upgrade error', async (t) => { test('pool dispatch error', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -784,7 +784,7 @@ test('pool dispatch error', async (t) => { test('pool request abort in queue', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -831,7 +831,7 @@ test('pool request abort in queue', async (t) => { test('pool stream abort in queue', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -878,7 +878,7 @@ test('pool stream abort in queue', async (t) => { test('pool pipeline abort in queue', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -925,7 +925,7 @@ test('pool pipeline abort in queue', async (t) => { test('pool stream constructor error destroy body', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -981,7 +981,7 @@ test('pool stream constructor error destroy body', async (t) => { test('pool request constructor error destroy body', async (t) => { t = tspl(t, { plan: 4 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -1033,7 +1033,7 @@ test('pool request constructor error destroy body', async (t) => { test('pool close waits for all requests', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -1081,7 +1081,7 @@ test('pool close waits for all requests', async (t) => { test('pool destroyed', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -1108,7 +1108,7 @@ test('pool destroyed', async (t) => { test('pool destroy fails queued requests', async (t) => { t = tspl(t, { plan: 6 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) diff --git a/test/promises.js b/test/promises.js index 1eddfc216f6..3aaf909cd71 100644 --- a/test/promises.js +++ b/test/promises.js @@ -10,7 +10,7 @@ const { wrapWithAsyncIterable } = require('./utils/async-iterators') test('basic get, async await support', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') @@ -63,7 +63,7 @@ test('basic POST with string, async await support', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, async () => { @@ -93,7 +93,7 @@ test('basic POST with Buffer, async await support', async (t) => { const expected = readFileSync(__filename) - const server = createServer(postServer(t, expected.toString())) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected.toString())) after(() => server.close()) server.listen(0, async () => { @@ -123,7 +123,7 @@ test('basic POST with stream, async await support', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, async () => { @@ -160,7 +160,7 @@ test('basic POST with async-iterator, async await support', async (t) => { const expected = readFileSync(__filename, 'utf8') - const server = createServer(postServer(t, expected)) + const server = createServer({ joinDuplicateHeaders: true }, postServer(t, expected)) after(() => server.close()) server.listen(0, async () => { @@ -202,7 +202,7 @@ test('20 times GET with pipelining 10, async await support', async (t) => { let count = 0 let countGreaterThanOne = false - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { count++ await sleep(10) countGreaterThanOne = countGreaterThanOne || count > 1 @@ -263,7 +263,7 @@ async function makeRequestAndExpectUrl (client, i, t) { test('pool, async await support', async (t) => { t = tspl(t, { plan: 5 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') diff --git a/test/proxy-agent.js b/test/proxy-agent.js index 6dcdfee450c..a412b4adebf 100644 --- a/test/proxy-agent.js +++ b/test/proxy-agent.js @@ -875,7 +875,7 @@ test('ProxyAgent keeps customized host in request headers - #3019', async (t) => function buildServer () { return new Promise((resolve) => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.listen(0, () => resolve(server)) }) } @@ -886,7 +886,8 @@ function buildSSLServer () { certs.root.crt ], key: certs.server.key, - cert: certs.server.crt + cert: certs.server.crt, + joinDuplicateHeaders: true } return new Promise((resolve) => { const server = https.createServer(serverOptions) @@ -898,7 +899,7 @@ function buildProxy (listener) { return new Promise((resolve) => { const server = listener ? createProxy(createServer(listener)) - : createProxy(createServer()) + : createProxy(createServer({ joinDuplicateHeaders: true })) server.listen(0, () => resolve(server)) }) } @@ -909,7 +910,8 @@ function buildSSLProxy () { certs.root.crt ], key: certs.proxy.key, - cert: certs.proxy.crt + cert: certs.proxy.crt, + joinDuplicateHeaders: true } return new Promise((resolve) => { diff --git a/test/proxy.js b/test/proxy.js index 30d1290a6ff..86cae7bfc93 100644 --- a/test/proxy.js +++ b/test/proxy.js @@ -154,14 +154,14 @@ test('connect through proxy (with pool)', async (t) => { function buildServer () { return new Promise((resolve, reject) => { - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.listen(0, () => resolve(server)) }) } function buildProxy () { return new Promise((resolve, reject) => { - const server = createProxy(createServer()) + const server = createProxy(createServer({ joinDuplicateHeaders: true })) server.listen(0, () => resolve(server)) }) } diff --git a/test/request-crlf.js b/test/request-crlf.js index 4e6921e2fb0..38d5e58b61e 100644 --- a/test/request-crlf.js +++ b/test/request-crlf.js @@ -9,7 +9,7 @@ const { once } = require('node:events') test('should validate content-type CRLF Injection', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('should not receive any request') res.statusCode = 200 res.end('hello') diff --git a/test/request-signal.js b/test/request-signal.js index fd4d2f885a5..73df93897a8 100644 --- a/test/request-signal.js +++ b/test/request-signal.js @@ -8,7 +8,7 @@ const { request } = require('..') test('pre abort signal w/ reason', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -29,7 +29,7 @@ test('pre abort signal w/ reason', async (t) => { test('post abort signal', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) @@ -53,7 +53,7 @@ test('post abort signal', async (t) => { test('post abort signal w/ reason', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('asd') }) after(() => server.close()) diff --git a/test/request-timeout.js b/test/request-timeout.js index 19f602fff8b..d56d2a9c14a 100644 --- a/test/request-timeout.js +++ b/test/request-timeout.js @@ -28,7 +28,7 @@ beforeEach(() => { test('request timeout', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 2000) @@ -50,7 +50,7 @@ test('request timeout', async (t) => { test('request timeout with readable body', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -80,7 +80,7 @@ test('body timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('hello') }) after(() => server.close()) @@ -115,7 +115,7 @@ test('overridden request timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -148,7 +148,7 @@ test('overridden body timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.write('hello') }) after(() => server.close()) @@ -183,7 +183,7 @@ test('With EE signal', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -219,7 +219,7 @@ test('With abort-controller signal', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -256,7 +256,7 @@ test('Abort before timeout (EE)', async (t) => { after(() => clock.uninstall()) const ee = new EventEmitter() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -292,7 +292,7 @@ test('Abort before timeout (abort-controller)', async (t) => { after(() => clock.uninstall()) const abortController = new AbortController() - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -327,7 +327,7 @@ test('Timeout with pipelining', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -368,7 +368,7 @@ test('Global option', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -403,7 +403,7 @@ test('Request options overrides global option', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 100) @@ -432,7 +432,7 @@ test('Request options overrides global option', async (t) => { test('client.destroy should cancel the timeout', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) after(() => server.close()) @@ -463,7 +463,7 @@ test('client.close should wait for the timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) @@ -543,7 +543,7 @@ test('Disable request timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 32e3) @@ -586,7 +586,7 @@ test('Disable request timeout for a single request', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 32e3) @@ -629,7 +629,7 @@ test('stream timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 301e3) @@ -665,7 +665,7 @@ test('stream custom timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { res.end('hello') }, 31e3) @@ -703,7 +703,7 @@ test('pipeline timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { req.pipe(res) }, 301e3) @@ -758,7 +758,7 @@ test('pipeline timeout', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { setTimeout(() => { req.pipe(res) }, 31e3) @@ -815,7 +815,7 @@ test('client.close should not deadlock', async (t) => { }) after(() => clock.uninstall()) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { }) after(() => server.close()) diff --git a/test/request-timeout2.js b/test/request-timeout2.js index a294b2fb9c1..48293f81e95 100644 --- a/test/request-timeout2.js +++ b/test/request-timeout2.js @@ -10,7 +10,7 @@ const { Readable } = require('node:stream') test('request timeout with slow readable body', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer(async (req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { let str = '' for await (const x of req) { str += x diff --git a/test/request.js b/test/request.js index 38f8cdc1aae..059a321f2ba 100644 --- a/test/request.js +++ b/test/request.js @@ -8,13 +8,13 @@ const { request, errors } = require('..') test('no-slash/one-slash pathname should be included in req.path', async (t) => { t = tspl(t, { plan: 24 }) - const pathServer = createServer((req, res) => { + const pathServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 res.end('hello') }) - const requestedServer = createServer((req, res) => { + const requestedServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(`/localhost:${pathServer.address().port}`, req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) @@ -72,13 +72,13 @@ test('no-slash/one-slash pathname should be included in req.path', async (t) => test('protocol-relative URL as pathname should be included in req.path', async (t) => { t = tspl(t, { plan: 12 }) - const pathServer = createServer((req, res) => { + const pathServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 res.end('hello') }) - const requestedServer = createServer((req, res) => { + const requestedServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(`//localhost:${pathServer.address().port}`, req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) @@ -119,13 +119,13 @@ test('protocol-relative URL as pathname should be included in req.path', async ( test('Absolute URL as pathname should be included in req.path', async (t) => { t = tspl(t, { plan: 12 }) - const pathServer = createServer((req, res) => { + const pathServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 res.end('hello') }) - const requestedServer = createServer((req, res) => { + const requestedServer = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual(`/http://localhost:${pathServer.address().port}`, req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) @@ -193,7 +193,7 @@ describe('DispatchOptions#reset', () => { test('Should include "connection:close" if reset true', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.connection, 'close') @@ -220,7 +220,7 @@ describe('DispatchOptions#reset', () => { test('Should include "connection:keep-alive" if reset false', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.connection, 'keep-alive') @@ -247,7 +247,7 @@ describe('DispatchOptions#reset', () => { test('Should react to manual set of "connection:close" header', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.connection, 'close') @@ -278,7 +278,7 @@ describe('Should include headers from iterable objects', scope => { test('Should include headers built with Headers global object', { skip: !globalThis.Headers }, async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.hello, 'world') @@ -309,7 +309,7 @@ describe('Should include headers from iterable objects', scope => { test('Should include headers built with Map', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.hello, 'world') @@ -340,7 +340,7 @@ describe('Should include headers from iterable objects', scope => { test('Should include headers built with custom iterable object', async t => { t = tspl(t, { plan: 3 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) t.strictEqual(req.headers.hello, 'world') @@ -374,7 +374,7 @@ describe('Should include headers from iterable objects', scope => { test('Should throw error if headers iterable object does not yield key-value pairs', async t => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end('hello') }) diff --git a/test/retry-agent.js b/test/retry-agent.js index 0e5e252d954..f4edaa5f4a0 100644 --- a/test/retry-agent.js +++ b/test/retry-agent.js @@ -10,7 +10,7 @@ test('Should retry status code', async t => { t = tspl(t, { plan: 2 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const opts = { maxRetries: 5, timeout: 1, diff --git a/test/retry-handler.js b/test/retry-handler.js index 85eea6b0597..3a42fce3a7a 100644 --- a/test/retry-handler.js +++ b/test/retry-handler.js @@ -14,7 +14,7 @@ test('Should retry status code', async t => { let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { retryOptions: { retry: (err, { state, opts }, done) => { @@ -109,7 +109,7 @@ test('Should account for network and response errors', async t => { let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { retryOptions: { retry: (err, { state, opts }, done) => { @@ -201,7 +201,7 @@ test('Should account for network and response errors', async t => { test('Issue #3288 - request with body (asynciterable)', async t => { t = tspl(t, { plan: 4 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { method: 'POST', path: '/', @@ -268,7 +268,7 @@ test('Should use retry-after header for retries', async t => { let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let checkpoint const dispatchOptions = { method: 'PUT', @@ -351,7 +351,7 @@ test('Should use retry-after header for retries (date)', async t => { let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let checkpoint const dispatchOptions = { method: 'PUT', @@ -436,7 +436,7 @@ test('Should retry with defaults', async t => { let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { method: 'GET', path: '/', @@ -521,7 +521,7 @@ test('Should handle 206 partial content', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.ok(true, 'pass') res.setHeader('etag', 'asd') @@ -617,7 +617,7 @@ test('Should handle 206 partial content - bad-etag', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.ok(true, 'pass') res.setHeader('etag', 'asd') @@ -699,7 +699,7 @@ test('Should handle 206 partial content - bad-etag', async t => { test('retrying a request with a body', async t => { let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { retryOptions: { retry: (err, { state, opts }, done) => { @@ -778,7 +778,7 @@ test('retrying a request with a body', async t => { test('retrying a request with a body (stream)', async t => { let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { retryOptions: { retry: (err, { state, opts }, done) => { @@ -845,7 +845,7 @@ test('retrying a request with a body (stream)', async t => { test('retrying a request with a body (buffer)', async t => { let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const dispatchOptions = { retryOptions: { retry: (err, { state, opts }, done) => { @@ -918,7 +918,7 @@ test('retrying a request with a body (buffer)', async t => { test('should not error if request is not meant to be retried', async t => { t = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { res.writeHead(400) res.end('Bad request') @@ -986,7 +986,7 @@ test('Should be able to properly pass the minTimeout to the RetryContext when co t = tspl(t, { plan: 2 }) let counter = 0 - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.on('request', (req, res) => { switch (counter) { case 0: @@ -1062,7 +1062,7 @@ test('Issue#2986 - Handle custom 206', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.deepStrictEqual(req.headers.range, 'bytes=0-3') res.setHeader('etag', 'asd') @@ -1160,7 +1160,7 @@ test('Issue#3128 - Support if-match', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.deepStrictEqual(req.headers.range, 'bytes=0-3') res.setHeader('etag', 'asd') @@ -1260,7 +1260,7 @@ test('Issue#3128 - Should ignore weak etags', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.deepStrictEqual(req.headers.range, 'bytes=0-3') res.setHeader('etag', 'W/asd') @@ -1360,7 +1360,7 @@ test('Weak etags are ignored on range-requests', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.deepStrictEqual(req.headers.range, 'bytes=0-3') res.setHeader('etag', 'W/asd') @@ -1459,7 +1459,7 @@ test('Should throw RequestRetryError when Content-Range mismatch', async t => { // Took from: https://github.com/nxtedition/nxt-lib/blob/4b001ebc2f22cf735a398f35ff800dd553fe5933/test/undici/retry.js#L47 let x = 0 - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { if (x === 0) { t.ok(true, 'pass') res.setHeader('etag', 'asd') @@ -1553,7 +1553,7 @@ test('Should use retry-after header for retries (date) but date format is wrong' let counter = 0 const chunks = [] - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let checkpoint const dispatchOptions = { method: 'PUT', diff --git a/test/socket-back-pressure.js b/test/socket-back-pressure.js index 043e815ed9a..e7150c0a9c5 100644 --- a/test/socket-back-pressure.js +++ b/test/socket-back-pressure.js @@ -10,7 +10,7 @@ const { test, after } = require('node:test') test('socket back-pressure', async (t) => { t = tspl(t, { plan: 3 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) let bytesWritten = 0 const buf = Buffer.allocUnsafe(16384) diff --git a/test/socket-timeout.js b/test/socket-timeout.js index 43ee1576615..5095da8f430 100644 --- a/test/socket-timeout.js +++ b/test/socket-timeout.js @@ -9,7 +9,7 @@ const FakeTimers = require('@sinonjs/fake-timers') test('timeout with pipelining 1', async (t) => { t = tspl(t, { plan: 9 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) server.once('request', (req, res) => { t.ok(true, 'first request received, we are letting this timeout on the client') @@ -63,7 +63,7 @@ test('timeout with pipelining 1', async (t) => { test('Disable socket timeout', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer() + const server = createServer({ joinDuplicateHeaders: true }) const clock = FakeTimers.install() after(clock.uninstall.bind(clock)) diff --git a/test/stream-compat.js b/test/stream-compat.js index 5f219fe42e3..15806a2447a 100644 --- a/test/stream-compat.js +++ b/test/stream-compat.js @@ -10,7 +10,7 @@ const EE = require('node:events') test('stream body without destroy', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -41,7 +41,7 @@ test('stream body without destroy', async (t) => { test('IncomingMessage', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.end() }) after(() => server.close()) @@ -50,7 +50,7 @@ test('IncomingMessage', async (t) => { const proxyClient = new Client(`http://localhost:${server.address().port}`) after(() => proxyClient.destroy()) - const proxy = createServer((req, res) => { + const proxy = createServer({ joinDuplicateHeaders: true }, (req, res) => { proxyClient.request({ path: '/', method: 'PUT', diff --git a/test/tls-cert-leak.js b/test/tls-cert-leak.js index 2a579e7a0a6..784b6980f75 100644 --- a/test/tls-cert-leak.js +++ b/test/tls-cert-leak.js @@ -23,7 +23,8 @@ test('no memory leak with TLS certificate errors', { timeout: 20000 }, async (t) // Create HTTPS server with self-signed certificate const serverOptions = { key: fs.readFileSync(path.join(__dirname, 'fixtures', 'key.pem')), - cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'cert.pem')) + cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'cert.pem')), + joinDuplicateHeaders: true } // Create a server that always responds with a simple message diff --git a/test/tls-session-reuse.js b/test/tls-session-reuse.js index c70578bed1f..2ebd25dbd2a 100644 --- a/test/tls-session-reuse.js +++ b/test/tls-session-reuse.js @@ -11,7 +11,8 @@ const { kSocket } = require('../lib/core/symbols') const options = { key: readFileSync(join(__dirname, 'fixtures', 'key.pem'), 'utf8'), - cert: readFileSync(join(__dirname, 'fixtures', 'cert.pem'), 'utf8') + cert: readFileSync(join(__dirname, 'fixtures', 'cert.pem'), 'utf8'), + joinDuplicateHeaders: true } const ca = readFileSync(join(__dirname, 'fixtures', 'ca.pem'), 'utf8') diff --git a/test/trailers.js b/test/trailers.js index 8f616e87eba..64a29da7b22 100644 --- a/test/trailers.js +++ b/test/trailers.js @@ -8,7 +8,7 @@ const { createServer } = require('node:http') test('response trailers missing is OK', async (t) => { t = tspl(t, { plan: 1 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Trailer: 'content-length' }) @@ -33,7 +33,7 @@ test('response trailers missing is OK', async (t) => { test('response trailers missing w trailers is OK', async (t) => { t = tspl(t, { plan: 2 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.writeHead(200, { Trailer: 'content-length' }) diff --git a/test/utils/esm-wrapper.mjs b/test/utils/esm-wrapper.mjs index 104190c1afe..76d8c2ae426 100644 --- a/test/utils/esm-wrapper.mjs +++ b/test/utils/esm-wrapper.mjs @@ -19,7 +19,7 @@ import { test('imported Client works with basic GET', async (t) => { t = tspl(t, { plan: 10 }) - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { t.strictEqual('/', req.url) t.strictEqual('GET', req.method) t.strictEqual(`localhost:${server.address().port}`, req.headers.host) diff --git a/test/utils/hello-world-server.js b/test/utils/hello-world-server.js index 520ed3a734d..50dd072dc4f 100644 --- a/test/utils/hello-world-server.js +++ b/test/utils/hello-world-server.js @@ -3,7 +3,7 @@ const { createServer } = require('node:http') const hostname = '127.0.0.1' -const server = createServer(async (req, res) => { +const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { res.statusCode = 200 res.setHeader('Content-Type', 'text/plain') diff --git a/test/utils/redirecting-servers.js b/test/utils/redirecting-servers.js index 011979c3e1e..ad9b6e7180c 100644 --- a/test/utils/redirecting-servers.js +++ b/test/utils/redirecting-servers.js @@ -18,7 +18,7 @@ function close (server) { function startServer (handler) { return new Promise(resolve => { - const server = createServer(handler) + const server = createServer({ joinDuplicateHeaders: true }, handler) server.listen(0, () => { resolve(`localhost:${server.address().port}`) diff --git a/test/websocket/opening-handshake.js b/test/websocket/opening-handshake.js index 110a827edc9..1eaeb9fecd4 100644 --- a/test/websocket/opening-handshake.js +++ b/test/websocket/opening-handshake.js @@ -8,7 +8,7 @@ const { WebSocket } = require('../..') test('WebSocket connecting to server that isn\'t a Websocket server', () => { return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { assert.equal(req.headers.connection, 'upgrade') assert.equal(req.headers.upgrade, 'websocket') assert.ok(req.headers['sec-websocket-key']) @@ -68,7 +68,7 @@ test('Multiple protocols are joined by a comma', () => { test('Server doesn\'t send Sec-WebSocket-Protocol header when protocols are used', () => { return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.statusCode = 101 req.socket.destroy() @@ -88,7 +88,7 @@ test('Server doesn\'t send Sec-WebSocket-Protocol header when protocols are used test('Server sends invalid Upgrade header', () => { return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Upgrade', 'NotWebSocket') res.statusCode = 101 @@ -109,7 +109,7 @@ test('Server sends invalid Upgrade header', () => { test('Server sends invalid Connection header', () => { return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Upgrade', 'websocket') res.setHeader('Connection', 'downgrade') res.statusCode = 101 @@ -131,7 +131,7 @@ test('Server sends invalid Connection header', () => { test('Server sends invalid Sec-WebSocket-Accept header', () => { return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { res.setHeader('Upgrade', 'websocket') res.setHeader('Connection', 'upgrade') res.setHeader('Sec-WebSocket-Accept', 'abc') @@ -157,7 +157,7 @@ test('Server sends invalid Sec-WebSocket-Extensions header', () => { const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' const { createHash } = require('node:crypto') - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const key = req.headers['sec-websocket-key'] assert.ok(key) @@ -189,7 +189,7 @@ test('Server sends invalid Sec-WebSocket-Extensions header', () => { const { createHash } = require('node:crypto') return new Promise((resolve, reject) => { - const server = createServer((req, res) => { + const server = createServer({ joinDuplicateHeaders: true }, (req, res) => { const key = req.headers['sec-websocket-key'] assert.ok(key) diff --git a/test/wpt/server/server.mjs b/test/wpt/server/server.mjs index 2ade5291c6e..a83651d38ac 100644 --- a/test/wpt/server/server.mjs +++ b/test/wpt/server/server.mjs @@ -30,7 +30,7 @@ class Stash extends Map { const stash = new Stash() -const server = createServer(async (req, res) => { +const server = createServer({ joinDuplicateHeaders: true }, async (req, res) => { const fullUrl = new URL(req.url, `http://localhost:${server.address().port}`) if (fullUrl.searchParams.has('pipe')) {