diff --git a/lib/api/api-connect.js b/lib/api/api-connect.js index b545a3eb5c1..69911703236 100644 --- a/lib/api/api-connect.js +++ b/lib/api/api-connect.js @@ -56,12 +56,10 @@ class ConnectHandler extends AsyncResource { this.callback = null let responseHeaders = headers - const rawHeaders = controller?.rawHeaders // Indicates is an HTTP2Session - if (responseHeaders != null) { - responseHeaders = this.responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) - : headers + if (responseHeaders != null && this.responseHeaders === 'raw') { + const rawHeaders = controller?.rawHeaders + responseHeaders = Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] } this.runInAsyncScope(callback, null, null, { diff --git a/lib/api/api-pipeline.js b/lib/api/api-pipeline.js index c8bd7414932..5d5caa0c56a 100644 --- a/lib/api/api-pipeline.js +++ b/lib/api/api-pipeline.js @@ -165,9 +165,11 @@ class PipelineHandler extends AsyncResource { if (statusCode < 200) { if (this.onInfo) { - const rawHeaders = controller?.rawHeaders const responseHeaders = this.responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + ? (() => { + const rawHeaders = controller?.rawHeaders + return Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] + })() : headers this.onInfo({ statusCode, headers: responseHeaders }) } @@ -179,9 +181,11 @@ class PipelineHandler extends AsyncResource { let body try { this.handler = null - const rawHeaders = controller?.rawHeaders const responseHeaders = this.responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + ? (() => { + const rawHeaders = controller?.rawHeaders + return Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] + })() : headers body = this.runInAsyncScope(handler, null, { statusCode, diff --git a/lib/api/api-request.js b/lib/api/api-request.js index 20487761a83..54686c2cbe0 100644 --- a/lib/api/api-request.js +++ b/lib/api/api-request.js @@ -90,9 +90,11 @@ class RequestHandler extends AsyncResource { onResponseStart (controller, statusCode, headers, statusText) { const { callback, opaque, context, responseHeaders, highWaterMark } = this - const rawHeaders = controller?.rawHeaders const responseHeaderData = responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + ? (() => { + const rawHeaders = controller?.rawHeaders + return Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] + })() : headers if (statusCode < 200) { diff --git a/lib/api/api-stream.js b/lib/api/api-stream.js index daee5681223..ec4cf8d5e5c 100644 --- a/lib/api/api-stream.js +++ b/lib/api/api-stream.js @@ -83,9 +83,11 @@ class StreamHandler extends AsyncResource { onResponseStart (controller, statusCode, headers, _statusMessage) { const { factory, opaque, context, responseHeaders } = this - const rawHeaders = controller?.rawHeaders const responseHeaderData = responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + ? (() => { + const rawHeaders = controller?.rawHeaders + return Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] + })() : headers if (statusCode < 200) { diff --git a/lib/api/api-upgrade.js b/lib/api/api-upgrade.js index 058fe31efd1..582171af1ea 100644 --- a/lib/api/api-upgrade.js +++ b/lib/api/api-upgrade.js @@ -65,9 +65,11 @@ class UpgradeHandler extends AsyncResource { this.callback = null - const rawHeaders = controller?.rawHeaders const responseHeaders = this.responseHeaders === 'raw' - ? (Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : []) + ? (() => { + const rawHeaders = controller?.rawHeaders + return Array.isArray(rawHeaders) ? util.parseRawHeaders(rawHeaders) : [] + })() : headers this.runInAsyncScope(callback, null, null, { diff --git a/lib/core/request.js b/lib/core/request.js index 2d2675a5065..2ebb2f866d3 100644 --- a/lib/core/request.js +++ b/lib/core/request.js @@ -46,6 +46,7 @@ function isValidContentLengthHeaderValue (val) { const kHandler = Symbol('handler') const kController = Symbol('controller') const kResume = Symbol('resume') +const kRawHeaders = Symbol('raw headers') class RequestController { #paused = false @@ -53,15 +54,29 @@ class RequestController { #aborted = false #abort - [kResume] = null + [kResume] = null; + [kRawHeaders] = null - rawHeaders = null rawTrailers = null constructor (abort) { this.#abort = abort } + get rawHeaders () { + let rawHeaders = this[kRawHeaders] + if (typeof rawHeaders === 'function') { + rawHeaders = rawHeaders() + this[kRawHeaders] = rawHeaders + } + + return rawHeaders + } + + set rawHeaders (rawHeaders) { + this[kRawHeaders] = rawHeaders + } + pause () { this.#paused = true } @@ -325,7 +340,7 @@ class Request { return this[kHandler].onResponseStarted?.() } - onResponseStart (statusCode, headers, resume, statusText) { + onResponseStart (statusCode, headers, resume, statusText, rawHeaders = headers) { assert(!this.aborted) assert(!this.completed) @@ -336,7 +351,7 @@ class Request { const controller = this[kController] if (controller) { controller[kResume] = resume - controller.rawHeaders = headers + controller.rawHeaders = rawHeaders } const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers @@ -368,13 +383,13 @@ class Request { } } - onRequestUpgrade (statusCode, headers, socket) { + onRequestUpgrade (statusCode, headers, socket, rawHeaders = headers) { assert(!this.aborted) assert(!this.completed) const controller = this[kController] if (controller) { - controller.rawHeaders = headers + controller.rawHeaders = rawHeaders } const parsedHeaders = Array.isArray(headers) ? parseHeaders(headers) : headers diff --git a/lib/dispatcher/client-h2.js b/lib/dispatcher/client-h2.js index 0709968a390..72b939429ce 100644 --- a/lib/dispatcher/client-h2.js +++ b/lib/dispatcher/client-h2.js @@ -108,6 +108,18 @@ function getH2HeaderNameBuffer (name) { return buffer } +function parseH2HeadersObject (headers) { + const result = Object.create(null) + + for (const name in headers) { + if (name[0] !== ':') { + result[name] = headers[name] + } + } + + return result +} + function parseH2Headers (headers) { const result = [] @@ -604,7 +616,7 @@ function writeH2 (client, request) { const statusCode = headers[HTTP2_HEADER_STATUS] - request.onRequestUpgrade(statusCode, parseH2Headers(headers), stream) + request.onRequestUpgrade(statusCode, parseH2HeadersObject(headers), stream, () => parseH2Headers(headers)) if (!request.aborted && !request.completed) { stream.off('error', onUpgradeStreamError) @@ -797,7 +809,7 @@ function writeH2 (client, request) { return } - if (request.onResponseStart(Number(statusCode), parseH2Headers(headers), stream.resume.bind(stream), '') === false) { + if (request.onResponseStart(Number(statusCode), parseH2HeadersObject(headers), stream.resume.bind(stream), '', () => parseH2Headers(headers)) === false) { stream.pause() }