@depup/mswjs__interceptors 0.43.0-depup.0 → 0.43.2-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/changes.json +1 -1
- package/lib/browser/interceptors/XMLHttpRequest/web.js +1 -1
- package/lib/browser/presets/browser.js +1 -1
- package/lib/browser/{web-BcKSQghf.js → web-EzmPOkVl.js} +12 -4
- package/lib/browser/{web-BcKSQghf.js.map → web-EzmPOkVl.js.map} +1 -1
- package/lib/node/interceptors/ClientRequest/index.js +1 -1
- package/lib/node/interceptors/XMLHttpRequest/node.js +1 -1
- package/lib/node/interceptors/fetch/node.js +1 -1
- package/lib/node/interceptors/http/index.js +1 -1
- package/lib/node/remote-http-interceptor.js +1 -1
- package/lib/node/{source-C_hSJzNQ.js → source-Bs0HXaSq.js} +11 -1
- package/lib/node/{source-C_hSJzNQ.js.map → source-Bs0HXaSq.js.map} +1 -1
- package/package.json +3 -3
- package/src/interceptors/XMLHttpRequest/xml-http-request-controller.ts +15 -3
- package/src/interceptors/http/source.ts +18 -0
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/mswjs__interceptors
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [@mswjs/interceptors](https://www.npmjs.com/package/@mswjs/interceptors) @ 0.43.
|
|
17
|
-
| Processed | 2026-09-
|
|
16
|
+
| Original | [@mswjs/interceptors](https://www.npmjs.com/package/@mswjs/interceptors) @ 0.43.2 |
|
|
17
|
+
| Processed | 2026-09-18 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 0 |
|
|
20
20
|
|
package/changes.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as XMLHttpRequestInterceptor } from "../../web-
|
|
1
|
+
import { t as XMLHttpRequestInterceptor } from "../../web-EzmPOkVl.js";
|
|
2
2
|
export { XMLHttpRequestInterceptor };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as FetchInterceptor } from "../web-DUlFZEtz.js";
|
|
2
|
-
import { t as XMLHttpRequestInterceptor } from "../web-
|
|
2
|
+
import { t as XMLHttpRequestInterceptor } from "../web-EzmPOkVl.js";
|
|
3
3
|
//#region src/presets/browser.ts
|
|
4
4
|
/**
|
|
5
5
|
* A browser preset for the request interception regardless
|
|
@@ -692,12 +692,20 @@ var XMLHttpRequestController = class {
|
|
|
692
692
|
credentials: this.request.withCredentials ? "include" : "same-origin",
|
|
693
693
|
body: resolvedBody
|
|
694
694
|
});
|
|
695
|
-
|
|
695
|
+
const headers = fetchRequest.headers;
|
|
696
|
+
define(fetchRequest, "headers", createProxy(headers, { methodCall: ([methodName, args], invoke) => {
|
|
697
|
+
const result = invoke();
|
|
696
698
|
switch (methodName) {
|
|
697
699
|
case "append":
|
|
698
700
|
case "set": {
|
|
699
701
|
const [headerName, headerValue] = args;
|
|
700
|
-
|
|
702
|
+
/**
|
|
703
|
+
* @note Forward only the headers the Fetch API Request accepted.
|
|
704
|
+
* Forbidden request headers (e.g. "Cookie") are dropped silently
|
|
705
|
+
* by the request's headers guard, and forwarding them makes
|
|
706
|
+
* the browser refuse them with an error in the console.
|
|
707
|
+
*/
|
|
708
|
+
if (headers.has(headerName)) this.request.setRequestHeader(headerName, headerValue);
|
|
701
709
|
break;
|
|
702
710
|
}
|
|
703
711
|
case "delete": {
|
|
@@ -706,7 +714,7 @@ var XMLHttpRequestController = class {
|
|
|
706
714
|
break;
|
|
707
715
|
}
|
|
708
716
|
}
|
|
709
|
-
return
|
|
717
|
+
return result;
|
|
710
718
|
} }));
|
|
711
719
|
this.logger.verbose("converted request to a Fetch API Request!", fetchRequest);
|
|
712
720
|
return fetchRequest;
|
|
@@ -815,4 +823,4 @@ var XMLHttpRequestInterceptor = class extends Interceptor {
|
|
|
815
823
|
//#endregion
|
|
816
824
|
export { XMLHttpRequestInterceptor as t };
|
|
817
825
|
|
|
818
|
-
//# sourceMappingURL=web-
|
|
826
|
+
//# sourceMappingURL=web-EzmPOkVl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-BcKSQghf.js","names":[],"sources":["../../src/interceptors/XMLHttpRequest/utils/concat-array-buffer.ts","../../src/interceptors/XMLHttpRequest/polyfills/event-polyfill.ts","../../src/interceptors/XMLHttpRequest/polyfills/progress-event-polyfill.ts","../../src/interceptors/XMLHttpRequest/utils/create-event.ts","../../src/utils/find-property-source.ts","../../src/utils/create-proxy.ts","../../src/interceptors/XMLHttpRequest/utils/is-dom-parser-supported-type.ts","../../src/utils/parse-json.ts","../../src/interceptors/XMLHttpRequest/utils/create-response.ts","../../src/interceptors/XMLHttpRequest/utils/get-body-byte-length.ts","../../src/interceptors/XMLHttpRequest/xml-http-request-controller.ts","../../src/interceptors/XMLHttpRequest/xml-http-request-proxy.ts","../../src/interceptors/XMLHttpRequest/web.ts"],"sourcesContent":["/**\n * Concatenate two `Uint8Array` buffers.\n */\nexport function concatArrayBuffer(\n left: Uint8Array,\n right: Uint8Array\n) {\n const result = new Uint8Array(left.byteLength + right.byteLength)\n result.set(left, 0)\n result.set(right, left.byteLength)\n return result\n}\n","export class EventPolyfill implements Event {\n readonly NONE = 0\n readonly CAPTURING_PHASE = 1\n readonly AT_TARGET = 2\n readonly BUBBLING_PHASE = 3\n\n public type: string = ''\n public srcElement: EventTarget | null = null\n public target: EventTarget | null\n public currentTarget: EventTarget | null = null\n public eventPhase: number = 0\n public timeStamp: number\n public isTrusted: boolean = true\n public composed: boolean = false\n public cancelable: boolean = true\n public defaultPrevented: boolean = false\n public bubbles: boolean = true\n public lengthComputable: boolean = true\n public loaded: number = 0\n public total: number = 0\n\n cancelBubble: boolean = false\n returnValue: boolean = true\n\n constructor(\n type: string,\n options?: { target: EventTarget; currentTarget: EventTarget }\n ) {\n this.type = type\n this.target = options?.target || null\n this.currentTarget = options?.currentTarget || null\n this.timeStamp = Date.now()\n }\n\n public composedPath(): EventTarget[] {\n return []\n }\n\n public initEvent(type: string, bubbles?: boolean, cancelable?: boolean) {\n this.type = type\n this.bubbles = !!bubbles\n this.cancelable = !!cancelable\n }\n\n public preventDefault() {\n this.defaultPrevented = true\n }\n\n public stopPropagation() {}\n public stopImmediatePropagation() {}\n}\n","import { EventPolyfill } from './event-polyfill'\n\nexport class ProgressEventPolyfill extends EventPolyfill {\n readonly lengthComputable: boolean\n readonly composed: boolean\n readonly loaded: number\n readonly total: number\n\n constructor(type: string, init?: ProgressEventInit) {\n super(type)\n\n this.lengthComputable = init?.lengthComputable || false\n this.composed = init?.composed || false\n this.loaded = init?.loaded || 0\n this.total = init?.total || 0\n }\n}\n","import { EventPolyfill } from '../polyfills/event-polyfill'\nimport { ProgressEventPolyfill } from '../polyfills/progress-event-polyfill'\n\nconst SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== 'undefined'\n\nexport function createEvent(\n target: XMLHttpRequest | XMLHttpRequestUpload,\n type: string,\n init?: ProgressEventInit\n): EventPolyfill | ProgressEvent {\n const progressEvents = [\n 'error',\n 'progress',\n 'loadstart',\n 'loadend',\n 'load',\n 'timeout',\n 'abort',\n ]\n\n /**\n * `ProgressEvent` is not supported in React Native.\n * @see https://github.com/mswjs/interceptors/issues/40\n */\n const ProgressEventClass = SUPPORTS_PROGRESS_EVENT\n ? ProgressEvent\n : ProgressEventPolyfill\n\n const event = progressEvents.includes(type)\n ? new ProgressEventClass(type, {\n lengthComputable: true,\n loaded: init?.loaded || 0,\n total: init?.total || 0,\n })\n : new EventPolyfill(type, {\n target,\n currentTarget: target,\n })\n\n return event\n}\n","/**\n * Returns the source object of the given property on the target object\n * (the target itself, any parent in its prototype, or null).\n */\nexport function findPropertySource(\n target: object,\n propertyName: string | symbol\n): object | null {\n if (!(propertyName in target)) {\n return null\n }\n\n const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName)\n if (hasProperty) {\n return target\n }\n\n const prototype = Reflect.getPrototypeOf(target)\n return prototype ? findPropertySource(prototype, propertyName) : null\n}\n","import { findPropertySource } from './find-property-source'\n\nexport interface ProxyOptions<Target extends Record<string, any>> {\n constructorCall?(args: Array<unknown>, next: NextFunction<Target>): Target\n\n methodCall?<F extends keyof Target>(\n this: Target,\n data: [methodName: F, args: Array<unknown>],\n next: NextFunction<void>\n ): void\n\n setProperty?(\n data: [propertyName: string | symbol, nextValue: unknown],\n next: NextFunction<boolean>\n ): boolean\n\n getProperty?(\n data: [propertyName: string | symbol, receiver: Target],\n next: NextFunction<void>\n ): void\n}\n\nexport type NextFunction<ReturnType> = () => ReturnType\n\nexport function createProxy<Target extends object>(\n target: Target,\n options: ProxyOptions<Target>\n): Target {\n const proxy = new Proxy(target, optionsToProxyHandler(options))\n\n return proxy\n}\n\nfunction optionsToProxyHandler<T extends Record<string, any>>(\n options: ProxyOptions<T>\n): ProxyHandler<T> {\n const { constructorCall, methodCall, getProperty, setProperty } = options\n const handler: ProxyHandler<T> = {}\n\n if (typeof constructorCall !== 'undefined') {\n handler.construct = function (target, args, newTarget) {\n const next = Reflect.construct.bind(null, target as any, args, newTarget)\n return constructorCall.call(newTarget, args, next)\n }\n }\n\n handler.set = function (target, propertyName, nextValue) {\n const next = () => {\n const propertySource = findPropertySource(target, propertyName) || target\n const ownDescriptors = Reflect.getOwnPropertyDescriptor(\n propertySource,\n propertyName\n )\n\n // Respect any custom setters present for this property.\n if (typeof ownDescriptors?.set !== 'undefined') {\n ownDescriptors.set.apply(target, [nextValue])\n return true\n }\n\n // Otherwise, set the property on the source.\n return Reflect.defineProperty(propertySource, propertyName, {\n writable: true,\n enumerable: true,\n configurable: true,\n value: nextValue,\n })\n }\n\n if (typeof setProperty !== 'undefined') {\n return setProperty.call(target, [propertyName, nextValue], next)\n }\n\n return next()\n }\n\n handler.get = function (target, propertyName, receiver) {\n /**\n * @note Using `Reflect.get()` here causes \"TypeError: Illegal invocation\".\n */\n const next = () => target[propertyName as any]\n\n const value =\n typeof getProperty !== 'undefined'\n ? getProperty.call(target, [propertyName, receiver], next)\n : next()\n\n if (typeof value === 'function') {\n return (...args: Array<any>) => {\n const next = value.bind(target, ...args)\n\n if (typeof methodCall !== 'undefined') {\n return methodCall.call(target, [propertyName as any, args], next)\n }\n\n return next()\n }\n }\n\n return value\n }\n\n return handler\n}\n","export function isDomParserSupportedType(\n type: string\n): type is DOMParserSupportedType {\n const supportedTypes: Array<DOMParserSupportedType> = [\n 'application/xhtml+xml',\n 'application/xml',\n 'image/svg+xml',\n 'text/html',\n 'text/xml',\n ]\n return supportedTypes.some((supportedType) => {\n return type.startsWith(supportedType)\n })\n}\n","/**\n * Parses a given string into JSON.\n * Gracefully handles invalid JSON by returning `null`.\n */\nexport function parseJson(data: string): Record<string, unknown> | null {\n try {\n const json = JSON.parse(data)\n return json\n } catch (_) {\n return null\n }\n}\n","import { FetchResponse } from '../../../utils/fetch-utils'\n\n/**\n * Creates a Fetch API `Response` instance from the given\n * `XMLHttpRequest` instance and a response body.\n */\nexport function createResponse(\n request: XMLHttpRequest,\n body: BodyInit | null\n): Response {\n /**\n * Handle XMLHttpRequest responses that must have null as the\n * response body when represented using Fetch API Response.\n * XMLHttpRequest response will always have an empty string\n * as the \"request.response\" in those cases, resulting in an error\n * when constructing a Response instance.\n * @see https://github.com/mswjs/interceptors/issues/379\n */\n const responseBodyOrNull = FetchResponse.isResponseWithBody(request.status)\n ? body\n : null\n\n return new FetchResponse(responseBodyOrNull, {\n url: request.responseURL,\n status: request.status,\n statusText: request.statusText,\n headers: createHeadersFromXMLHttpRequestHeaders(\n request.getAllResponseHeaders()\n ),\n })\n}\n\nfunction createHeadersFromXMLHttpRequestHeaders(headersString: string): Headers {\n const headers = new Headers()\n\n const lines = headersString.split(/[\\r\\n]+/)\n for (const line of lines) {\n if (line.trim() === '') {\n continue\n }\n\n const [name, ...parts] = line.split(': ')\n const value = parts.join(': ')\n\n headers.append(name, value)\n }\n\n return headers\n}\n","/**\n * Return a total byte length of the given request/response body.\n * If the `Content-Length` header is present, it will be used as the byte length.\n */\nexport async function getBodyByteLength(\n input: Request | Response\n): Promise<number> {\n const explicitContentLength = input.headers.get('content-length')\n\n if (explicitContentLength != null && explicitContentLength !== '') {\n return Number(explicitContentLength)\n }\n\n const buffer = await input.arrayBuffer()\n return buffer.byteLength\n}\n","import { until } from '@open-draft/until'\nimport { invariant } from 'outvariant'\nimport type { Logger } from '../../utils/logger'\nimport type { HttpResponseType } from '../../events/http'\nimport { concatArrayBuffer } from './utils/concat-array-buffer'\nimport { createEvent } from './utils/create-event'\nimport {\n decodeBuffer,\n encodeBuffer,\n toArrayBuffer,\n} from '../../utils/buffer-utils'\nimport { createProxy } from '../../utils/create-proxy'\nimport { isDomParserSupportedType } from './utils/is-dom-parser-supported-type'\nimport { parseJson } from '../../utils/parse-json'\nimport { createResponse } from './utils/create-response'\nimport { createRequestId } from '../../create-request-id'\nimport { getBodyByteLength } from './utils/get-body-byte-length'\nimport { FetchRequest, FetchResponse } from '../../utils/fetch-utils'\nimport { isResponseError } from '../../utils/response-utils'\n\nconst kIsRequestHandled = Symbol('kIsRequestHandled')\nconst kFetchRequest = Symbol('kFetchRequest')\nconst MAX_REDIRECTS = 20\n\n/**\n * An `XMLHttpRequest` instance controller that allows us\n * to handle any given request instance (e.g. responding to it).\n */\nexport class XMLHttpRequestController {\n public request: XMLHttpRequest\n public requestId: string\n public onRequest?: (\n this: XMLHttpRequestController,\n args: {\n request: Request\n requestId: string\n }\n ) => Promise<void>\n public onResponse?: (\n this: XMLHttpRequestController,\n args: {\n response: Response\n responseType: HttpResponseType\n request: Request\n requestId: string\n }\n ) => void;\n\n [kIsRequestHandled]: boolean;\n [kFetchRequest]?: Request\n\n private sync: boolean = false\n private method: string = 'GET'\n private url: URL = null as any\n private requestHeaders: Headers\n private responseBuffer: Uint8Array<ArrayBuffer>\n private redirectCount: number\n private events: Map<keyof XMLHttpRequestEventTargetEventMap, Array<Function>>\n private uploadEvents: Map<\n keyof XMLHttpRequestEventTargetEventMap,\n Array<Function>\n >\n\n constructor(\n readonly initialRequest: XMLHttpRequest,\n public logger: Logger\n ) {\n this[kIsRequestHandled] = false\n\n this.redirectCount = 0\n this.events = new Map()\n this.uploadEvents = new Map()\n this.requestId = createRequestId()\n this.requestHeaders = new Headers()\n this.responseBuffer = new Uint8Array()\n\n this.request = createProxy(initialRequest, {\n methodCall: ([methodName, args], invoke) => {\n switch (methodName) {\n case 'open': {\n const [method, url, async] = args as [\n string,\n string | undefined,\n boolean | undefined,\n ]\n\n this.sync = !(async ?? true)\n\n if (typeof url === 'undefined') {\n this.method = 'GET'\n this.url = toAbsoluteUrl(method)\n } else {\n this.method = method\n this.url = toAbsoluteUrl(url)\n }\n\n this.logger.verbose('open %s %s', this.method, this.url.href)\n\n return invoke()\n }\n\n case 'addEventListener': {\n const [eventName, listener] = args as [\n keyof XMLHttpRequestEventTargetEventMap,\n Function,\n ]\n\n this.registerEvent(eventName, listener)\n this.logger.verbose('addEventListener', eventName, listener)\n\n return invoke()\n }\n\n case 'setRequestHeader': {\n const [name, value] = args as [string, string]\n this.requestHeaders.set(name, value)\n\n this.logger.verbose('setRequestHeader', name, value)\n\n return invoke()\n }\n\n case 'send': {\n const [body] = args as [\n body?: XMLHttpRequestBodyInit | Document | null,\n ]\n\n if (this.sync) {\n console.warn(\n `Failed to intercept an XMLHttpRequest (${this.method} ${this.url}): synchronous requests are not supported. This request will be performed as-is.`\n )\n return invoke()\n }\n\n this.request.addEventListener('load', () => {\n if (typeof this.onResponse !== 'undefined') {\n // Create a Fetch API Response representation of whichever\n // response this XMLHttpRequest received. Note those may\n // be either a mocked and the original response.\n const fetchResponse = createResponse(\n this.request,\n /**\n * The `response` property is the right way to read\n * the ambiguous response body, as the request's \"responseType\" may differ.\n * @see https://xhr.spec.whatwg.org/#the-response-attribute\n */\n this.request.response\n )\n\n // Notify the consumer about the response.\n this.onResponse.call(this, {\n response: fetchResponse,\n responseType: this[kIsRequestHandled] ? 'mock' : 'original',\n request: fetchRequest,\n requestId: this.requestId!,\n })\n }\n })\n\n const requestBody =\n typeof body === 'string' ? encodeBuffer(body) : body\n\n // Delegate request handling to the consumer.\n const fetchRequest = this.toFetchApiRequest(requestBody)\n this[kFetchRequest] = fetchRequest.clone()\n\n /**\n * @note Start request handling on the next tick so that the user\n * could add event listeners for \"loadend\" before the interceptor fires it.\n */\n queueMicrotask(() => {\n const onceRequestSettled =\n this.onRequest?.call(this, {\n request: fetchRequest,\n requestId: this.requestId!,\n }) || Promise.resolve()\n\n onceRequestSettled.finally(() => {\n // If the consumer didn't handle the request (called `.respondWith()`) perform it as-is.\n if (!this[kIsRequestHandled]) {\n this.logger.verbose(\n 'request callback settled but request has not been handled (readystate %d), performing as-is...',\n this.request.readyState\n )\n\n return invoke()\n }\n })\n })\n\n break\n }\n\n default: {\n return invoke()\n }\n }\n },\n })\n\n /**\n * Proxy the `.upload` property to gather the event listeners/callbacks.\n */\n define(\n this.request,\n 'upload',\n createProxy(this.request.upload, {\n setProperty: ([propertyName, nextValue], invoke) => {\n switch (propertyName) {\n case 'onloadstart':\n case 'onprogress':\n case 'onaboart':\n case 'onerror':\n case 'onload':\n case 'ontimeout':\n case 'onloadend': {\n const eventName = propertyName.slice(\n 2\n ) as keyof XMLHttpRequestEventTargetEventMap\n\n this.registerUploadEvent(eventName, nextValue as Function)\n }\n }\n\n return invoke()\n },\n methodCall: ([methodName, args], invoke) => {\n switch (methodName) {\n case 'addEventListener': {\n const [eventName, listener] = args as [\n keyof XMLHttpRequestEventTargetEventMap,\n Function,\n ]\n this.registerUploadEvent(eventName, listener)\n this.logger.verbose('upload.addEventListener', eventName, listener)\n\n return invoke()\n }\n }\n },\n })\n )\n }\n\n private registerEvent(\n eventName: keyof XMLHttpRequestEventTargetEventMap,\n listener: Function\n ): void {\n const prevEvents = this.events.get(eventName) || []\n const nextEvents = prevEvents.concat(listener)\n this.events.set(eventName, nextEvents)\n\n this.logger.verbose('registered event \"%s\"', eventName, listener)\n }\n\n private registerUploadEvent(\n eventName: keyof XMLHttpRequestEventTargetEventMap,\n listener: Function\n ): void {\n const prevEvents = this.uploadEvents.get(eventName) || []\n const nextEvents = prevEvents.concat(listener)\n this.uploadEvents.set(eventName, nextEvents)\n\n this.logger.verbose('registered upload event \"%s\"', eventName, listener)\n }\n\n /**\n * Responds to the current request with the given\n * Fetch API `Response` instance.\n */\n public async respondWith(response: Response): Promise<void> {\n /**\n * @note Since `XMLHttpRequestController` delegates the handling of the responses\n * to the \"load\" event listener that doesn't distinguish between the mocked and original\n * responses, mark the request that had a mocked response with a corresponding symbol.\n *\n * Mark this request as having a mocked response immediately since\n * calculating request/response total body length is asynchronous.\n */\n this[kIsRequestHandled] = true\n\n this.logger.verbose(\n 'responding with a mocked response: %d %s',\n response.status,\n response.statusText\n )\n\n FetchResponse.setUrl(this.url.href, response)\n\n // Update the response getters to resolve against the mocked response.\n Object.defineProperties(this.request, {\n response: {\n enumerable: true,\n configurable: false,\n get: () => this.response,\n },\n responseText: {\n enumerable: true,\n configurable: false,\n get: () => this.responseText,\n },\n responseXML: {\n enumerable: true,\n configurable: false,\n get: () => this.responseXML,\n },\n })\n\n // 1. Fire a progress event named loadstart at this with 0 and 0.\n this.trigger('loadstart', this.request, { loaded: 0, total: 0 })\n\n // 2. Let requestBodyTransmitted be 0.\n let requestBodyTransmitted = 0\n let uploadComplete = false\n\n if (this[kFetchRequest]) {\n const requestBodyLength = await getBodyByteLength(\n this[kFetchRequest].clone()\n )\n\n // 5. If this’s upload complete flag is unset and this’s upload listener flag is set, then fire a progress event named loadstart at this’s upload object with requestBodyTransmitted and requestBodyLength.\n if (!uploadComplete) {\n this.trigger('loadstart', this.request.upload, {\n loaded: 0,\n total: requestBodyLength,\n })\n }\n\n const processRequestBodyChunkLength = (bytesLength: number) => {\n requestBodyTransmitted += bytesLength\n\n if (requestBodyTransmitted < requestBodyLength) {\n this.trigger('progress', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n }\n }\n\n const processRequestEndOfBody = () => {\n uploadComplete = true\n\n this.trigger('progress', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n this.trigger('load', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n this.trigger('loadend', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n }\n\n if (this[kFetchRequest]?.body != null) {\n const reader = this[kFetchRequest].body.getReader()\n\n while (true) {\n const { value, done } = await reader.read()\n\n if (done) {\n processRequestEndOfBody()\n break\n }\n\n processRequestBodyChunkLength(value.byteLength)\n }\n } else {\n processRequestEndOfBody()\n }\n }\n\n let timedOut = false\n const responseReadController = new AbortController()\n\n const requestErrorSteps = (\n event: keyof XMLHttpRequestEventTargetEventMap\n ) => {\n this.setReadyState(this.request.DONE)\n\n if (!uploadComplete) {\n this.trigger(event, this.request.upload, {\n loaded: 0,\n total: 0,\n })\n this.trigger('loadend', this.request.upload, {\n loaded: 0,\n total: 0,\n })\n }\n\n this.trigger(event, this.request, { loaded: 0, total: 0 })\n this.trigger('loadend', this.request, { loaded: 0, total: 0 })\n }\n\n const processResponse = async (response: Response) => {\n const handleErrors = () => {\n if (timedOut) {\n requestErrorSteps('timeout')\n } else if (responseReadController.signal.aborted) {\n requestErrorSteps('abort')\n } else if (isResponseError(response)) {\n requestErrorSteps('error')\n }\n }\n\n handleErrors()\n\n define(this.request, 'status', response.status)\n define(this.request, 'statusText', response.statusText)\n\n if (!this.request.responseURL) {\n define(this.request, 'responseURL', response.url)\n }\n\n if (isResponseError(response)) {\n return\n }\n\n /**\n * @note The response body length is derived ONLY from the \"content-length\" header.\n * If that response header is not set, the \"total\" in all progress events must be 0.\n */\n const responseBodyLength = Number(\n response.headers.get('content-length') ?? '0'\n )\n\n this.setReadyState(this.request.HEADERS_RECEIVED)\n\n let receivedBytes = 0\n let lastReceivedResponseBytesAt = performance.now()\n\n const processResponseBodyChunk = (bytesLength: number) => {\n receivedBytes += bytesLength\n\n const now = performance.now()\n const shouldBuffer =\n now - lastReceivedResponseBytesAt <= 60 &&\n receivedBytes < responseBodyLength\n lastReceivedResponseBytesAt = now\n\n if (shouldBuffer) {\n return\n }\n\n if (this.request.readyState === this.request.HEADERS_RECEIVED) {\n this.setReadyState(this.request.LOADING, false)\n }\n\n this.trigger('readystatechange', this.request)\n this.trigger('progress', this.request, {\n loaded: receivedBytes,\n total: responseBodyLength,\n })\n }\n\n const processResponseBodyError = () => {\n requestErrorSteps('error')\n }\n\n const processResponseEndOfBody = async () => {\n handleErrors()\n\n if (isResponseError(response)) {\n return\n }\n\n // 3. Let transmitted be xhr’s received bytes’s length.\n let transmitted = receivedBytes\n\n // 9. Fire an event named readystatechange at xhr.\n this.setReadyState(this.request.DONE)\n // 10. Fire a progress event named load at xhr with transmitted and length.\n this.trigger('load', this.request, {\n loaded: transmitted,\n total: responseBodyLength,\n })\n // 11. Fire a progress event named loadend at xhr with transmitted and length.\n this.trigger('loadend', this.request, {\n loaded: transmitted,\n total: responseBodyLength,\n })\n }\n\n // 7. If this’s response’s body is null, then run handle response end-of-body for this and return.\n if (response.body == null) {\n processResponseEndOfBody()\n } else {\n const reader = response.body.getReader()\n\n while (true) {\n if (responseReadController.signal.aborted) {\n break\n }\n\n try {\n const { value, done } = await reader.read()\n\n if (done) {\n processResponseEndOfBody()\n return\n }\n\n processResponseBodyChunk(value.byteLength)\n this.responseBuffer = concatArrayBuffer(this.responseBuffer, value)\n } catch {\n processResponseBodyError()\n }\n }\n }\n }\n\n // Redirects are followed as a part of the fetch controller. Since we don't have one,\n // retrieve the final response and then continue with processing it instead of the mocked one.\n const [redirectError, finalResponse] = await until(() => {\n return this.followRedirects(response)\n })\n\n if (redirectError) {\n return\n }\n\n processResponse(finalResponse)\n\n // 12.1, 12.2.\n if (this.request.timeout) {\n setTimeout(() => {\n if (this.request.readyState !== this.request.DONE) {\n timedOut = true\n responseReadController.abort()\n }\n }, this.request.timeout)\n }\n\n this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {\n apply: (_, __, args: [name: string]) => {\n this.logger.verbose('getResponseHeader', args[0])\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.verbose('headers not received yet, returning null')\n return null\n }\n\n const headerValue = finalResponse.headers.get(args[0])\n this.logger.verbose(\n 'resolved response header \"%s\" to',\n args[0],\n headerValue\n )\n\n return headerValue\n },\n })\n\n this.request.getAllResponseHeaders = new Proxy(\n this.request.getAllResponseHeaders,\n {\n apply: () => {\n this.logger.verbose('getAllResponseHeaders')\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.verbose('headers not received yet, returning empty string')\n return ''\n }\n\n const headersList = Array.from(finalResponse.headers)\n const allHeaders = headersList\n .map(([headerName, headerValue]) => {\n return `${headerName}: ${headerValue}`\n })\n .join('\\r\\n')\n\n this.logger.verbose('resolved all response headers to', allHeaders)\n\n return allHeaders\n },\n }\n )\n }\n\n private responseBufferToText(): string {\n return decodeBuffer(this.responseBuffer)\n }\n\n get response(): unknown {\n this.logger.verbose(\n 'getResponse (responseType: %s)',\n this.request.responseType\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n switch (this.request.responseType) {\n case 'json': {\n const responseJson = parseJson(this.responseBufferToText())\n this.logger.verbose('resolved response JSON', responseJson)\n\n return responseJson\n }\n\n case 'arraybuffer': {\n const arrayBuffer = toArrayBuffer(this.responseBuffer)\n this.logger.verbose('resolved response ArrayBuffer', arrayBuffer)\n\n return arrayBuffer\n }\n\n case 'blob': {\n const mimeType =\n this.request.getResponseHeader('Content-Type') || 'text/plain'\n const responseBlob = new Blob([this.responseBufferToText()], {\n type: mimeType,\n })\n\n this.logger.verbose(\n 'resolved response Blob (mime type: %s)',\n responseBlob,\n mimeType\n )\n\n return responseBlob\n }\n\n default: {\n const responseText = this.responseBufferToText()\n this.logger.verbose(\n 'resolving \"%s\" response type as text',\n this.request.responseType,\n responseText\n )\n\n return responseText\n }\n }\n }\n\n get responseText(): string {\n /**\n * Throw when trying to read the response body as text when the\n * \"responseType\" doesn't expect text. This just respects the spec better.\n * @see https://xhr.spec.whatwg.org/#the-responsetext-attribute\n */\n invariant(\n this.request.responseType === '' || this.request.responseType === 'text',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (\n this.request.readyState !== this.request.LOADING &&\n this.request.readyState !== this.request.DONE\n ) {\n return ''\n }\n\n const responseText = this.responseBufferToText()\n this.logger.verbose('getResponseText: \"%s\"', responseText)\n\n return responseText\n }\n\n get responseXML(): Document | null {\n invariant(\n this.request.responseType === '' ||\n this.request.responseType === 'document',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n const contentType = this.request.getResponseHeader('Content-Type') || ''\n\n if (typeof DOMParser === 'undefined') {\n console.warn(\n 'Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly.'\n )\n return null\n }\n\n if (isDomParserSupportedType(contentType)) {\n return new DOMParser().parseFromString(\n this.responseBufferToText(),\n contentType\n )\n }\n\n return null\n }\n\n private async followRedirects(response: Response): Promise<Response> {\n const redirectLocation = response.headers.get('location')\n\n if (\n !redirectLocation ||\n !FetchResponse.isRedirectResponse(response.status)\n ) {\n return response\n }\n\n this.redirectCount++\n\n if (this.redirectCount > MAX_REDIRECTS) {\n throw new Error('Too many redirects')\n }\n\n const redirectUrl = new URL(redirectLocation, location.href)\n const redirectMethod = FetchResponse.isResponseWithBody(response.status)\n ? this.method\n : 'GET'\n\n const redirectResponse = await new Promise<Response>((resolve, reject) => {\n const request = new XMLHttpRequest()\n request.responseType = this.request.responseType\n\n request.addEventListener('load', () => {\n this.url = new URL(request.responseURL)\n resolve(createResponse(request, request.response))\n })\n\n request.addEventListener('error', () => {\n this.errorWith()\n reject(new Error('Redirect request failed'))\n })\n\n request.open(redirectMethod, redirectUrl.href)\n request.send()\n })\n\n return this.followRedirects(redirectResponse)\n }\n\n public errorWith(error?: Error): void {\n /**\n * @note Mark this request as handled even if it received a mock error.\n * This prevents the controller from trying to perform this request as-is.\n */\n this[kIsRequestHandled] = true\n this.logger.verbose('responding with an error')\n\n this.setReadyState(this.request.DONE)\n this.trigger('error', this.request)\n this.trigger('loadend', this.request)\n }\n\n /**\n * Transitions this request's `readyState` to the given one.\n */\n private setReadyState(\n nextReadyState: number,\n triggerReadyStateChangeEvent = true\n ): void {\n this.logger.verbose(\n 'setReadyState: %d -> %d',\n this.request.readyState,\n nextReadyState\n )\n\n if (this.request.readyState === nextReadyState) {\n this.logger.verbose('ready state identical, skipping transition...')\n return\n }\n\n define(this.request, 'readyState', nextReadyState)\n\n this.logger.verbose('set readyState to: %d', nextReadyState)\n\n if (!triggerReadyStateChangeEvent) {\n return\n }\n\n if (nextReadyState !== this.request.UNSENT) {\n this.logger.verbose('triggering \"readystatechange\" event...')\n\n this.trigger('readystatechange', this.request)\n }\n }\n\n /**\n * Triggers given event on the `XMLHttpRequest` instance.\n */\n private trigger<\n EventName extends keyof (XMLHttpRequestEventTargetEventMap & {\n readystatechange: ProgressEvent<XMLHttpRequestEventTarget>\n }),\n >(\n eventName: EventName,\n target: XMLHttpRequest | XMLHttpRequestUpload,\n options?: ProgressEventInit\n ): void {\n const callback = (target as XMLHttpRequest)[`on${eventName}`]\n const event = createEvent(target, eventName, options)\n\n this.logger.verbose('trigger \"%s\"', eventName, options || '')\n\n // Invoke direct callbacks.\n if (typeof callback === 'function') {\n this.logger.verbose('found a direct \"%s\" callback, calling...', eventName)\n callback.call(target as XMLHttpRequest, event)\n }\n\n // Invoke event listeners.\n const events =\n target instanceof XMLHttpRequestUpload ? this.uploadEvents : this.events\n\n for (const [registeredEventName, listeners] of events) {\n if (registeredEventName === eventName) {\n this.logger.verbose(\n 'found %d listener(s) for \"%s\" event, calling...',\n listeners.length,\n eventName\n )\n\n listeners.forEach((listener) => listener.call(target, event))\n }\n }\n }\n\n /**\n * Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.\n */\n private toFetchApiRequest(\n body: XMLHttpRequestBodyInit | Document | null | undefined\n ): Request {\n this.logger.verbose('converting request to a Fetch API Request...')\n\n // If the `Document` is used as the body of this XMLHttpRequest,\n // set its inner text as the Fetch API Request body.\n const resolvedBody =\n body instanceof Document ? body.documentElement.innerText : body\n\n const fetchRequest = new FetchRequest(this.url.href, {\n method: this.method,\n headers: this.requestHeaders,\n /**\n * @see https://xhr.spec.whatwg.org/#cross-origin-credentials\n */\n credentials: this.request.withCredentials ? 'include' : 'same-origin',\n body: resolvedBody,\n })\n\n const proxyHeaders = createProxy(fetchRequest.headers, {\n methodCall: ([methodName, args], invoke) => {\n // Forward the latest state of the internal request headers\n // because the interceptor might have modified them\n // without responding to the request.\n switch (methodName) {\n case 'append':\n case 'set': {\n const [headerName, headerValue] = args as [string, string]\n this.request.setRequestHeader(headerName, headerValue)\n break\n }\n\n case 'delete': {\n const [headerName] = args as [string]\n console.warn(\n `XMLHttpRequest: Cannot remove a \"${headerName}\" header from the Fetch API representation of the \"${fetchRequest.method} ${fetchRequest.url}\" request. XMLHttpRequest headers cannot be removed.`\n )\n break\n }\n }\n\n return invoke()\n },\n })\n define(fetchRequest, 'headers', proxyHeaders)\n // setRawRequest(fetchRequest, this.request)\n\n this.logger.verbose('converted request to a Fetch API Request!', fetchRequest)\n\n return fetchRequest\n }\n}\n\nfunction toAbsoluteUrl(url: string | URL): URL {\n /**\n * @note XMLHttpRequest interceptor may run in environments\n * that implement XMLHttpRequest but don't implement \"location\"\n * (for example, React Native). If that's the case, return the\n * input URL as-is (nothing to be relative to).\n * @see https://github.com/mswjs/msw/issues/1777\n */\n if (typeof location === 'undefined') {\n return new URL(url)\n }\n\n return new URL(url.toString(), location.href)\n}\n\nfunction define(\n target: object,\n property: string | symbol,\n value: unknown\n): void {\n Reflect.defineProperty(target, property, {\n // Ensure writable properties to allow redefining readonly properties.\n writable: true,\n enumerable: true,\n value,\n })\n}\n","import type { Emitter } from 'rettime'\nimport { HttpResponseEvent, type HttpRequestEventMap } from '../../events/http'\nimport { RequestController } from '../../request-controller'\nimport { XMLHttpRequestController } from './xml-http-request-controller'\nimport { handleRequest } from '../../utils/handle-request'\nimport type { Logger } from '../../utils/logger'\n\nexport interface XMLHttpRequestProxyOptions {\n emitter: Emitter<HttpRequestEventMap>\n logger: Logger\n}\n\n/**\n * Create a proxied `XMLHttpRequest` class.\n * The proxied class establishes spies on certain methods,\n * allowing us to intercept requests and respond to them.\n */\nexport function createXMLHttpRequestProxy({\n emitter,\n logger,\n}: XMLHttpRequestProxyOptions) {\n const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {\n construct(target, args, newTarget) {\n logger.verbose('constructed new XMLHttpRequest')\n\n const originalRequest = Reflect.construct(\n target,\n args,\n newTarget\n ) as XMLHttpRequest\n\n /**\n * @note Forward prototype descriptors onto the proxied object.\n * XMLHttpRequest is implemented in JSDOM in a way that assigns\n * a bunch of descriptors, like \"set responseType()\" on the prototype.\n * With this propagation, we make sure that those descriptors trigger\n * when the user operates with the proxied request instance.\n */\n const prototypeDescriptors = Object.getOwnPropertyDescriptors(\n target.prototype\n )\n for (const propertyName in prototypeDescriptors) {\n Reflect.defineProperty(\n originalRequest,\n propertyName,\n prototypeDescriptors[propertyName]\n )\n }\n\n const xhrRequestController = new XMLHttpRequestController(\n originalRequest,\n logger\n )\n\n xhrRequestController.onRequest = async function ({ request, requestId }) {\n const controller = new RequestController(request, {\n passthrough: () => {\n this.logger.verbose(\n 'no mocked response received, performing request as-is...'\n )\n },\n respondWith: async (response) => {\n await this.respondWith(response)\n },\n errorWith: (reason) => {\n this.logger.verbose('request errored %o', { error: reason })\n\n if (reason instanceof Error) {\n this.errorWith(reason)\n }\n },\n }, {\n logger,\n requestId,\n })\n\n this.logger.verbose('awaiting mocked response')\n\n this.logger.verbose(\n 'emitting the \"request\" event for %s listener(s)...',\n emitter.listenerCount('request')\n )\n\n await handleRequest({\n initiator: this.request,\n request,\n requestId,\n controller,\n emitter,\n logger,\n })\n }\n\n xhrRequestController.onResponse = async function ({\n response,\n responseType,\n request,\n requestId,\n }) {\n this.logger.verbose(\n 'emitting the \"response\" event for %s listener(s)...',\n emitter.listenerCount('response')\n )\n\n await emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator: this.request,\n response,\n responseType,\n request,\n requestId,\n })\n )\n }\n\n // Return the proxied request from the controller\n // so that the controller can react to the consumer's interactions\n // with this request (opening/sending/etc).\n return xhrRequestController.request\n },\n })\n\n return XMLHttpRequestProxy\n}\n","import { HttpRequestEventMap } from '../../events/http'\nimport { Interceptor } from '../../interceptor'\nimport { createXMLHttpRequestProxy } from './xml-http-request-proxy'\nimport { hasConfigurableGlobal } from '../../utils/has-configurable-global'\nimport { patchesRegistry } from '../../utils/patches-registry'\nimport { createLogger } from '../../utils/logger'\n\nconst logger = createLogger('xhr')\n\nexport class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol.for('xhr-interceptor')\n\n protected predicate() {\n return hasConfigurableGlobal('XMLHttpRequest')\n }\n\n protected setup() {\n logger.verbose('patching \"XMLHttpRequest\"...')\n\n this.subscriptions.push(\n patchesRegistry.applyPatch(globalThis, 'XMLHttpRequest', () => {\n return createXMLHttpRequestProxy({\n emitter: this.emitter,\n logger,\n })\n })\n )\n\n logger.verbose(\n 'global \"XMLHttpRequest\" patched!',\n globalThis.XMLHttpRequest.name\n )\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"web-EzmPOkVl.js","names":[],"sources":["../../src/interceptors/XMLHttpRequest/utils/concat-array-buffer.ts","../../src/interceptors/XMLHttpRequest/polyfills/event-polyfill.ts","../../src/interceptors/XMLHttpRequest/polyfills/progress-event-polyfill.ts","../../src/interceptors/XMLHttpRequest/utils/create-event.ts","../../src/utils/find-property-source.ts","../../src/utils/create-proxy.ts","../../src/interceptors/XMLHttpRequest/utils/is-dom-parser-supported-type.ts","../../src/utils/parse-json.ts","../../src/interceptors/XMLHttpRequest/utils/create-response.ts","../../src/interceptors/XMLHttpRequest/utils/get-body-byte-length.ts","../../src/interceptors/XMLHttpRequest/xml-http-request-controller.ts","../../src/interceptors/XMLHttpRequest/xml-http-request-proxy.ts","../../src/interceptors/XMLHttpRequest/web.ts"],"sourcesContent":["/**\n * Concatenate two `Uint8Array` buffers.\n */\nexport function concatArrayBuffer(\n left: Uint8Array,\n right: Uint8Array\n) {\n const result = new Uint8Array(left.byteLength + right.byteLength)\n result.set(left, 0)\n result.set(right, left.byteLength)\n return result\n}\n","export class EventPolyfill implements Event {\n readonly NONE = 0\n readonly CAPTURING_PHASE = 1\n readonly AT_TARGET = 2\n readonly BUBBLING_PHASE = 3\n\n public type: string = ''\n public srcElement: EventTarget | null = null\n public target: EventTarget | null\n public currentTarget: EventTarget | null = null\n public eventPhase: number = 0\n public timeStamp: number\n public isTrusted: boolean = true\n public composed: boolean = false\n public cancelable: boolean = true\n public defaultPrevented: boolean = false\n public bubbles: boolean = true\n public lengthComputable: boolean = true\n public loaded: number = 0\n public total: number = 0\n\n cancelBubble: boolean = false\n returnValue: boolean = true\n\n constructor(\n type: string,\n options?: { target: EventTarget; currentTarget: EventTarget }\n ) {\n this.type = type\n this.target = options?.target || null\n this.currentTarget = options?.currentTarget || null\n this.timeStamp = Date.now()\n }\n\n public composedPath(): EventTarget[] {\n return []\n }\n\n public initEvent(type: string, bubbles?: boolean, cancelable?: boolean) {\n this.type = type\n this.bubbles = !!bubbles\n this.cancelable = !!cancelable\n }\n\n public preventDefault() {\n this.defaultPrevented = true\n }\n\n public stopPropagation() {}\n public stopImmediatePropagation() {}\n}\n","import { EventPolyfill } from './event-polyfill'\n\nexport class ProgressEventPolyfill extends EventPolyfill {\n readonly lengthComputable: boolean\n readonly composed: boolean\n readonly loaded: number\n readonly total: number\n\n constructor(type: string, init?: ProgressEventInit) {\n super(type)\n\n this.lengthComputable = init?.lengthComputable || false\n this.composed = init?.composed || false\n this.loaded = init?.loaded || 0\n this.total = init?.total || 0\n }\n}\n","import { EventPolyfill } from '../polyfills/event-polyfill'\nimport { ProgressEventPolyfill } from '../polyfills/progress-event-polyfill'\n\nconst SUPPORTS_PROGRESS_EVENT = typeof ProgressEvent !== 'undefined'\n\nexport function createEvent(\n target: XMLHttpRequest | XMLHttpRequestUpload,\n type: string,\n init?: ProgressEventInit\n): EventPolyfill | ProgressEvent {\n const progressEvents = [\n 'error',\n 'progress',\n 'loadstart',\n 'loadend',\n 'load',\n 'timeout',\n 'abort',\n ]\n\n /**\n * `ProgressEvent` is not supported in React Native.\n * @see https://github.com/mswjs/interceptors/issues/40\n */\n const ProgressEventClass = SUPPORTS_PROGRESS_EVENT\n ? ProgressEvent\n : ProgressEventPolyfill\n\n const event = progressEvents.includes(type)\n ? new ProgressEventClass(type, {\n lengthComputable: true,\n loaded: init?.loaded || 0,\n total: init?.total || 0,\n })\n : new EventPolyfill(type, {\n target,\n currentTarget: target,\n })\n\n return event\n}\n","/**\n * Returns the source object of the given property on the target object\n * (the target itself, any parent in its prototype, or null).\n */\nexport function findPropertySource(\n target: object,\n propertyName: string | symbol\n): object | null {\n if (!(propertyName in target)) {\n return null\n }\n\n const hasProperty = Object.prototype.hasOwnProperty.call(target, propertyName)\n if (hasProperty) {\n return target\n }\n\n const prototype = Reflect.getPrototypeOf(target)\n return prototype ? findPropertySource(prototype, propertyName) : null\n}\n","import { findPropertySource } from './find-property-source'\n\nexport interface ProxyOptions<Target extends Record<string, any>> {\n constructorCall?(args: Array<unknown>, next: NextFunction<Target>): Target\n\n methodCall?<F extends keyof Target>(\n this: Target,\n data: [methodName: F, args: Array<unknown>],\n next: NextFunction<void>\n ): void\n\n setProperty?(\n data: [propertyName: string | symbol, nextValue: unknown],\n next: NextFunction<boolean>\n ): boolean\n\n getProperty?(\n data: [propertyName: string | symbol, receiver: Target],\n next: NextFunction<void>\n ): void\n}\n\nexport type NextFunction<ReturnType> = () => ReturnType\n\nexport function createProxy<Target extends object>(\n target: Target,\n options: ProxyOptions<Target>\n): Target {\n const proxy = new Proxy(target, optionsToProxyHandler(options))\n\n return proxy\n}\n\nfunction optionsToProxyHandler<T extends Record<string, any>>(\n options: ProxyOptions<T>\n): ProxyHandler<T> {\n const { constructorCall, methodCall, getProperty, setProperty } = options\n const handler: ProxyHandler<T> = {}\n\n if (typeof constructorCall !== 'undefined') {\n handler.construct = function (target, args, newTarget) {\n const next = Reflect.construct.bind(null, target as any, args, newTarget)\n return constructorCall.call(newTarget, args, next)\n }\n }\n\n handler.set = function (target, propertyName, nextValue) {\n const next = () => {\n const propertySource = findPropertySource(target, propertyName) || target\n const ownDescriptors = Reflect.getOwnPropertyDescriptor(\n propertySource,\n propertyName\n )\n\n // Respect any custom setters present for this property.\n if (typeof ownDescriptors?.set !== 'undefined') {\n ownDescriptors.set.apply(target, [nextValue])\n return true\n }\n\n // Otherwise, set the property on the source.\n return Reflect.defineProperty(propertySource, propertyName, {\n writable: true,\n enumerable: true,\n configurable: true,\n value: nextValue,\n })\n }\n\n if (typeof setProperty !== 'undefined') {\n return setProperty.call(target, [propertyName, nextValue], next)\n }\n\n return next()\n }\n\n handler.get = function (target, propertyName, receiver) {\n /**\n * @note Using `Reflect.get()` here causes \"TypeError: Illegal invocation\".\n */\n const next = () => target[propertyName as any]\n\n const value =\n typeof getProperty !== 'undefined'\n ? getProperty.call(target, [propertyName, receiver], next)\n : next()\n\n if (typeof value === 'function') {\n return (...args: Array<any>) => {\n const next = value.bind(target, ...args)\n\n if (typeof methodCall !== 'undefined') {\n return methodCall.call(target, [propertyName as any, args], next)\n }\n\n return next()\n }\n }\n\n return value\n }\n\n return handler\n}\n","export function isDomParserSupportedType(\n type: string\n): type is DOMParserSupportedType {\n const supportedTypes: Array<DOMParserSupportedType> = [\n 'application/xhtml+xml',\n 'application/xml',\n 'image/svg+xml',\n 'text/html',\n 'text/xml',\n ]\n return supportedTypes.some((supportedType) => {\n return type.startsWith(supportedType)\n })\n}\n","/**\n * Parses a given string into JSON.\n * Gracefully handles invalid JSON by returning `null`.\n */\nexport function parseJson(data: string): Record<string, unknown> | null {\n try {\n const json = JSON.parse(data)\n return json\n } catch (_) {\n return null\n }\n}\n","import { FetchResponse } from '../../../utils/fetch-utils'\n\n/**\n * Creates a Fetch API `Response` instance from the given\n * `XMLHttpRequest` instance and a response body.\n */\nexport function createResponse(\n request: XMLHttpRequest,\n body: BodyInit | null\n): Response {\n /**\n * Handle XMLHttpRequest responses that must have null as the\n * response body when represented using Fetch API Response.\n * XMLHttpRequest response will always have an empty string\n * as the \"request.response\" in those cases, resulting in an error\n * when constructing a Response instance.\n * @see https://github.com/mswjs/interceptors/issues/379\n */\n const responseBodyOrNull = FetchResponse.isResponseWithBody(request.status)\n ? body\n : null\n\n return new FetchResponse(responseBodyOrNull, {\n url: request.responseURL,\n status: request.status,\n statusText: request.statusText,\n headers: createHeadersFromXMLHttpRequestHeaders(\n request.getAllResponseHeaders()\n ),\n })\n}\n\nfunction createHeadersFromXMLHttpRequestHeaders(headersString: string): Headers {\n const headers = new Headers()\n\n const lines = headersString.split(/[\\r\\n]+/)\n for (const line of lines) {\n if (line.trim() === '') {\n continue\n }\n\n const [name, ...parts] = line.split(': ')\n const value = parts.join(': ')\n\n headers.append(name, value)\n }\n\n return headers\n}\n","/**\n * Return a total byte length of the given request/response body.\n * If the `Content-Length` header is present, it will be used as the byte length.\n */\nexport async function getBodyByteLength(\n input: Request | Response\n): Promise<number> {\n const explicitContentLength = input.headers.get('content-length')\n\n if (explicitContentLength != null && explicitContentLength !== '') {\n return Number(explicitContentLength)\n }\n\n const buffer = await input.arrayBuffer()\n return buffer.byteLength\n}\n","import { until } from '@open-draft/until'\nimport { invariant } from 'outvariant'\nimport type { Logger } from '../../utils/logger'\nimport type { HttpResponseType } from '../../events/http'\nimport { concatArrayBuffer } from './utils/concat-array-buffer'\nimport { createEvent } from './utils/create-event'\nimport {\n decodeBuffer,\n encodeBuffer,\n toArrayBuffer,\n} from '../../utils/buffer-utils'\nimport { createProxy } from '../../utils/create-proxy'\nimport { isDomParserSupportedType } from './utils/is-dom-parser-supported-type'\nimport { parseJson } from '../../utils/parse-json'\nimport { createResponse } from './utils/create-response'\nimport { createRequestId } from '../../create-request-id'\nimport { getBodyByteLength } from './utils/get-body-byte-length'\nimport { FetchRequest, FetchResponse } from '../../utils/fetch-utils'\nimport { isResponseError } from '../../utils/response-utils'\n\nconst kIsRequestHandled = Symbol('kIsRequestHandled')\nconst kFetchRequest = Symbol('kFetchRequest')\nconst MAX_REDIRECTS = 20\n\n/**\n * An `XMLHttpRequest` instance controller that allows us\n * to handle any given request instance (e.g. responding to it).\n */\nexport class XMLHttpRequestController {\n public request: XMLHttpRequest\n public requestId: string\n public onRequest?: (\n this: XMLHttpRequestController,\n args: {\n request: Request\n requestId: string\n }\n ) => Promise<void>\n public onResponse?: (\n this: XMLHttpRequestController,\n args: {\n response: Response\n responseType: HttpResponseType\n request: Request\n requestId: string\n }\n ) => void;\n\n [kIsRequestHandled]: boolean;\n [kFetchRequest]?: Request\n\n private sync: boolean = false\n private method: string = 'GET'\n private url: URL = null as any\n private requestHeaders: Headers\n private responseBuffer: Uint8Array<ArrayBuffer>\n private redirectCount: number\n private events: Map<keyof XMLHttpRequestEventTargetEventMap, Array<Function>>\n private uploadEvents: Map<\n keyof XMLHttpRequestEventTargetEventMap,\n Array<Function>\n >\n\n constructor(\n readonly initialRequest: XMLHttpRequest,\n public logger: Logger\n ) {\n this[kIsRequestHandled] = false\n\n this.redirectCount = 0\n this.events = new Map()\n this.uploadEvents = new Map()\n this.requestId = createRequestId()\n this.requestHeaders = new Headers()\n this.responseBuffer = new Uint8Array()\n\n this.request = createProxy(initialRequest, {\n methodCall: ([methodName, args], invoke) => {\n switch (methodName) {\n case 'open': {\n const [method, url, async] = args as [\n string,\n string | undefined,\n boolean | undefined,\n ]\n\n this.sync = !(async ?? true)\n\n if (typeof url === 'undefined') {\n this.method = 'GET'\n this.url = toAbsoluteUrl(method)\n } else {\n this.method = method\n this.url = toAbsoluteUrl(url)\n }\n\n this.logger.verbose('open %s %s', this.method, this.url.href)\n\n return invoke()\n }\n\n case 'addEventListener': {\n const [eventName, listener] = args as [\n keyof XMLHttpRequestEventTargetEventMap,\n Function,\n ]\n\n this.registerEvent(eventName, listener)\n this.logger.verbose('addEventListener', eventName, listener)\n\n return invoke()\n }\n\n case 'setRequestHeader': {\n const [name, value] = args as [string, string]\n this.requestHeaders.set(name, value)\n\n this.logger.verbose('setRequestHeader', name, value)\n\n return invoke()\n }\n\n case 'send': {\n const [body] = args as [\n body?: XMLHttpRequestBodyInit | Document | null,\n ]\n\n if (this.sync) {\n console.warn(\n `Failed to intercept an XMLHttpRequest (${this.method} ${this.url}): synchronous requests are not supported. This request will be performed as-is.`\n )\n return invoke()\n }\n\n this.request.addEventListener('load', () => {\n if (typeof this.onResponse !== 'undefined') {\n // Create a Fetch API Response representation of whichever\n // response this XMLHttpRequest received. Note those may\n // be either a mocked and the original response.\n const fetchResponse = createResponse(\n this.request,\n /**\n * The `response` property is the right way to read\n * the ambiguous response body, as the request's \"responseType\" may differ.\n * @see https://xhr.spec.whatwg.org/#the-response-attribute\n */\n this.request.response\n )\n\n // Notify the consumer about the response.\n this.onResponse.call(this, {\n response: fetchResponse,\n responseType: this[kIsRequestHandled] ? 'mock' : 'original',\n request: fetchRequest,\n requestId: this.requestId!,\n })\n }\n })\n\n const requestBody =\n typeof body === 'string' ? encodeBuffer(body) : body\n\n // Delegate request handling to the consumer.\n const fetchRequest = this.toFetchApiRequest(requestBody)\n this[kFetchRequest] = fetchRequest.clone()\n\n /**\n * @note Start request handling on the next tick so that the user\n * could add event listeners for \"loadend\" before the interceptor fires it.\n */\n queueMicrotask(() => {\n const onceRequestSettled =\n this.onRequest?.call(this, {\n request: fetchRequest,\n requestId: this.requestId!,\n }) || Promise.resolve()\n\n onceRequestSettled.finally(() => {\n // If the consumer didn't handle the request (called `.respondWith()`) perform it as-is.\n if (!this[kIsRequestHandled]) {\n this.logger.verbose(\n 'request callback settled but request has not been handled (readystate %d), performing as-is...',\n this.request.readyState\n )\n\n return invoke()\n }\n })\n })\n\n break\n }\n\n default: {\n return invoke()\n }\n }\n },\n })\n\n /**\n * Proxy the `.upload` property to gather the event listeners/callbacks.\n */\n define(\n this.request,\n 'upload',\n createProxy(this.request.upload, {\n setProperty: ([propertyName, nextValue], invoke) => {\n switch (propertyName) {\n case 'onloadstart':\n case 'onprogress':\n case 'onaboart':\n case 'onerror':\n case 'onload':\n case 'ontimeout':\n case 'onloadend': {\n const eventName = propertyName.slice(\n 2\n ) as keyof XMLHttpRequestEventTargetEventMap\n\n this.registerUploadEvent(eventName, nextValue as Function)\n }\n }\n\n return invoke()\n },\n methodCall: ([methodName, args], invoke) => {\n switch (methodName) {\n case 'addEventListener': {\n const [eventName, listener] = args as [\n keyof XMLHttpRequestEventTargetEventMap,\n Function,\n ]\n this.registerUploadEvent(eventName, listener)\n this.logger.verbose('upload.addEventListener', eventName, listener)\n\n return invoke()\n }\n }\n },\n })\n )\n }\n\n private registerEvent(\n eventName: keyof XMLHttpRequestEventTargetEventMap,\n listener: Function\n ): void {\n const prevEvents = this.events.get(eventName) || []\n const nextEvents = prevEvents.concat(listener)\n this.events.set(eventName, nextEvents)\n\n this.logger.verbose('registered event \"%s\"', eventName, listener)\n }\n\n private registerUploadEvent(\n eventName: keyof XMLHttpRequestEventTargetEventMap,\n listener: Function\n ): void {\n const prevEvents = this.uploadEvents.get(eventName) || []\n const nextEvents = prevEvents.concat(listener)\n this.uploadEvents.set(eventName, nextEvents)\n\n this.logger.verbose('registered upload event \"%s\"', eventName, listener)\n }\n\n /**\n * Responds to the current request with the given\n * Fetch API `Response` instance.\n */\n public async respondWith(response: Response): Promise<void> {\n /**\n * @note Since `XMLHttpRequestController` delegates the handling of the responses\n * to the \"load\" event listener that doesn't distinguish between the mocked and original\n * responses, mark the request that had a mocked response with a corresponding symbol.\n *\n * Mark this request as having a mocked response immediately since\n * calculating request/response total body length is asynchronous.\n */\n this[kIsRequestHandled] = true\n\n this.logger.verbose(\n 'responding with a mocked response: %d %s',\n response.status,\n response.statusText\n )\n\n FetchResponse.setUrl(this.url.href, response)\n\n // Update the response getters to resolve against the mocked response.\n Object.defineProperties(this.request, {\n response: {\n enumerable: true,\n configurable: false,\n get: () => this.response,\n },\n responseText: {\n enumerable: true,\n configurable: false,\n get: () => this.responseText,\n },\n responseXML: {\n enumerable: true,\n configurable: false,\n get: () => this.responseXML,\n },\n })\n\n // 1. Fire a progress event named loadstart at this with 0 and 0.\n this.trigger('loadstart', this.request, { loaded: 0, total: 0 })\n\n // 2. Let requestBodyTransmitted be 0.\n let requestBodyTransmitted = 0\n let uploadComplete = false\n\n if (this[kFetchRequest]) {\n const requestBodyLength = await getBodyByteLength(\n this[kFetchRequest].clone()\n )\n\n // 5. If this’s upload complete flag is unset and this’s upload listener flag is set, then fire a progress event named loadstart at this’s upload object with requestBodyTransmitted and requestBodyLength.\n if (!uploadComplete) {\n this.trigger('loadstart', this.request.upload, {\n loaded: 0,\n total: requestBodyLength,\n })\n }\n\n const processRequestBodyChunkLength = (bytesLength: number) => {\n requestBodyTransmitted += bytesLength\n\n if (requestBodyTransmitted < requestBodyLength) {\n this.trigger('progress', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n }\n }\n\n const processRequestEndOfBody = () => {\n uploadComplete = true\n\n this.trigger('progress', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n this.trigger('load', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n this.trigger('loadend', this.request.upload, {\n loaded: requestBodyTransmitted,\n total: requestBodyLength,\n })\n }\n\n if (this[kFetchRequest]?.body != null) {\n const reader = this[kFetchRequest].body.getReader()\n\n while (true) {\n const { value, done } = await reader.read()\n\n if (done) {\n processRequestEndOfBody()\n break\n }\n\n processRequestBodyChunkLength(value.byteLength)\n }\n } else {\n processRequestEndOfBody()\n }\n }\n\n let timedOut = false\n const responseReadController = new AbortController()\n\n const requestErrorSteps = (\n event: keyof XMLHttpRequestEventTargetEventMap\n ) => {\n this.setReadyState(this.request.DONE)\n\n if (!uploadComplete) {\n this.trigger(event, this.request.upload, {\n loaded: 0,\n total: 0,\n })\n this.trigger('loadend', this.request.upload, {\n loaded: 0,\n total: 0,\n })\n }\n\n this.trigger(event, this.request, { loaded: 0, total: 0 })\n this.trigger('loadend', this.request, { loaded: 0, total: 0 })\n }\n\n const processResponse = async (response: Response) => {\n const handleErrors = () => {\n if (timedOut) {\n requestErrorSteps('timeout')\n } else if (responseReadController.signal.aborted) {\n requestErrorSteps('abort')\n } else if (isResponseError(response)) {\n requestErrorSteps('error')\n }\n }\n\n handleErrors()\n\n define(this.request, 'status', response.status)\n define(this.request, 'statusText', response.statusText)\n\n if (!this.request.responseURL) {\n define(this.request, 'responseURL', response.url)\n }\n\n if (isResponseError(response)) {\n return\n }\n\n /**\n * @note The response body length is derived ONLY from the \"content-length\" header.\n * If that response header is not set, the \"total\" in all progress events must be 0.\n */\n const responseBodyLength = Number(\n response.headers.get('content-length') ?? '0'\n )\n\n this.setReadyState(this.request.HEADERS_RECEIVED)\n\n let receivedBytes = 0\n let lastReceivedResponseBytesAt = performance.now()\n\n const processResponseBodyChunk = (bytesLength: number) => {\n receivedBytes += bytesLength\n\n const now = performance.now()\n const shouldBuffer =\n now - lastReceivedResponseBytesAt <= 60 &&\n receivedBytes < responseBodyLength\n lastReceivedResponseBytesAt = now\n\n if (shouldBuffer) {\n return\n }\n\n if (this.request.readyState === this.request.HEADERS_RECEIVED) {\n this.setReadyState(this.request.LOADING, false)\n }\n\n this.trigger('readystatechange', this.request)\n this.trigger('progress', this.request, {\n loaded: receivedBytes,\n total: responseBodyLength,\n })\n }\n\n const processResponseBodyError = () => {\n requestErrorSteps('error')\n }\n\n const processResponseEndOfBody = async () => {\n handleErrors()\n\n if (isResponseError(response)) {\n return\n }\n\n // 3. Let transmitted be xhr’s received bytes’s length.\n let transmitted = receivedBytes\n\n // 9. Fire an event named readystatechange at xhr.\n this.setReadyState(this.request.DONE)\n // 10. Fire a progress event named load at xhr with transmitted and length.\n this.trigger('load', this.request, {\n loaded: transmitted,\n total: responseBodyLength,\n })\n // 11. Fire a progress event named loadend at xhr with transmitted and length.\n this.trigger('loadend', this.request, {\n loaded: transmitted,\n total: responseBodyLength,\n })\n }\n\n // 7. If this’s response’s body is null, then run handle response end-of-body for this and return.\n if (response.body == null) {\n processResponseEndOfBody()\n } else {\n const reader = response.body.getReader()\n\n while (true) {\n if (responseReadController.signal.aborted) {\n break\n }\n\n try {\n const { value, done } = await reader.read()\n\n if (done) {\n processResponseEndOfBody()\n return\n }\n\n processResponseBodyChunk(value.byteLength)\n this.responseBuffer = concatArrayBuffer(this.responseBuffer, value)\n } catch {\n processResponseBodyError()\n }\n }\n }\n }\n\n // Redirects are followed as a part of the fetch controller. Since we don't have one,\n // retrieve the final response and then continue with processing it instead of the mocked one.\n const [redirectError, finalResponse] = await until(() => {\n return this.followRedirects(response)\n })\n\n if (redirectError) {\n return\n }\n\n processResponse(finalResponse)\n\n // 12.1, 12.2.\n if (this.request.timeout) {\n setTimeout(() => {\n if (this.request.readyState !== this.request.DONE) {\n timedOut = true\n responseReadController.abort()\n }\n }, this.request.timeout)\n }\n\n this.request.getResponseHeader = new Proxy(this.request.getResponseHeader, {\n apply: (_, __, args: [name: string]) => {\n this.logger.verbose('getResponseHeader', args[0])\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.verbose('headers not received yet, returning null')\n return null\n }\n\n const headerValue = finalResponse.headers.get(args[0])\n this.logger.verbose(\n 'resolved response header \"%s\" to',\n args[0],\n headerValue\n )\n\n return headerValue\n },\n })\n\n this.request.getAllResponseHeaders = new Proxy(\n this.request.getAllResponseHeaders,\n {\n apply: () => {\n this.logger.verbose('getAllResponseHeaders')\n\n if (this.request.readyState < this.request.HEADERS_RECEIVED) {\n this.logger.verbose('headers not received yet, returning empty string')\n return ''\n }\n\n const headersList = Array.from(finalResponse.headers)\n const allHeaders = headersList\n .map(([headerName, headerValue]) => {\n return `${headerName}: ${headerValue}`\n })\n .join('\\r\\n')\n\n this.logger.verbose('resolved all response headers to', allHeaders)\n\n return allHeaders\n },\n }\n )\n }\n\n private responseBufferToText(): string {\n return decodeBuffer(this.responseBuffer)\n }\n\n get response(): unknown {\n this.logger.verbose(\n 'getResponse (responseType: %s)',\n this.request.responseType\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n switch (this.request.responseType) {\n case 'json': {\n const responseJson = parseJson(this.responseBufferToText())\n this.logger.verbose('resolved response JSON', responseJson)\n\n return responseJson\n }\n\n case 'arraybuffer': {\n const arrayBuffer = toArrayBuffer(this.responseBuffer)\n this.logger.verbose('resolved response ArrayBuffer', arrayBuffer)\n\n return arrayBuffer\n }\n\n case 'blob': {\n const mimeType =\n this.request.getResponseHeader('Content-Type') || 'text/plain'\n const responseBlob = new Blob([this.responseBufferToText()], {\n type: mimeType,\n })\n\n this.logger.verbose(\n 'resolved response Blob (mime type: %s)',\n responseBlob,\n mimeType\n )\n\n return responseBlob\n }\n\n default: {\n const responseText = this.responseBufferToText()\n this.logger.verbose(\n 'resolving \"%s\" response type as text',\n this.request.responseType,\n responseText\n )\n\n return responseText\n }\n }\n }\n\n get responseText(): string {\n /**\n * Throw when trying to read the response body as text when the\n * \"responseType\" doesn't expect text. This just respects the spec better.\n * @see https://xhr.spec.whatwg.org/#the-responsetext-attribute\n */\n invariant(\n this.request.responseType === '' || this.request.responseType === 'text',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (\n this.request.readyState !== this.request.LOADING &&\n this.request.readyState !== this.request.DONE\n ) {\n return ''\n }\n\n const responseText = this.responseBufferToText()\n this.logger.verbose('getResponseText: \"%s\"', responseText)\n\n return responseText\n }\n\n get responseXML(): Document | null {\n invariant(\n this.request.responseType === '' ||\n this.request.responseType === 'document',\n 'InvalidStateError: The object is in invalid state.'\n )\n\n if (this.request.readyState !== this.request.DONE) {\n return null\n }\n\n const contentType = this.request.getResponseHeader('Content-Type') || ''\n\n if (typeof DOMParser === 'undefined') {\n console.warn(\n 'Cannot retrieve XMLHttpRequest response body as XML: DOMParser is not defined. You are likely using an environment that is not browser or does not polyfill browser globals correctly.'\n )\n return null\n }\n\n if (isDomParserSupportedType(contentType)) {\n return new DOMParser().parseFromString(\n this.responseBufferToText(),\n contentType\n )\n }\n\n return null\n }\n\n private async followRedirects(response: Response): Promise<Response> {\n const redirectLocation = response.headers.get('location')\n\n if (\n !redirectLocation ||\n !FetchResponse.isRedirectResponse(response.status)\n ) {\n return response\n }\n\n this.redirectCount++\n\n if (this.redirectCount > MAX_REDIRECTS) {\n throw new Error('Too many redirects')\n }\n\n const redirectUrl = new URL(redirectLocation, location.href)\n const redirectMethod = FetchResponse.isResponseWithBody(response.status)\n ? this.method\n : 'GET'\n\n const redirectResponse = await new Promise<Response>((resolve, reject) => {\n const request = new XMLHttpRequest()\n request.responseType = this.request.responseType\n\n request.addEventListener('load', () => {\n this.url = new URL(request.responseURL)\n resolve(createResponse(request, request.response))\n })\n\n request.addEventListener('error', () => {\n this.errorWith()\n reject(new Error('Redirect request failed'))\n })\n\n request.open(redirectMethod, redirectUrl.href)\n request.send()\n })\n\n return this.followRedirects(redirectResponse)\n }\n\n public errorWith(error?: Error): void {\n /**\n * @note Mark this request as handled even if it received a mock error.\n * This prevents the controller from trying to perform this request as-is.\n */\n this[kIsRequestHandled] = true\n this.logger.verbose('responding with an error')\n\n this.setReadyState(this.request.DONE)\n this.trigger('error', this.request)\n this.trigger('loadend', this.request)\n }\n\n /**\n * Transitions this request's `readyState` to the given one.\n */\n private setReadyState(\n nextReadyState: number,\n triggerReadyStateChangeEvent = true\n ): void {\n this.logger.verbose(\n 'setReadyState: %d -> %d',\n this.request.readyState,\n nextReadyState\n )\n\n if (this.request.readyState === nextReadyState) {\n this.logger.verbose('ready state identical, skipping transition...')\n return\n }\n\n define(this.request, 'readyState', nextReadyState)\n\n this.logger.verbose('set readyState to: %d', nextReadyState)\n\n if (!triggerReadyStateChangeEvent) {\n return\n }\n\n if (nextReadyState !== this.request.UNSENT) {\n this.logger.verbose('triggering \"readystatechange\" event...')\n\n this.trigger('readystatechange', this.request)\n }\n }\n\n /**\n * Triggers given event on the `XMLHttpRequest` instance.\n */\n private trigger<\n EventName extends keyof (XMLHttpRequestEventTargetEventMap & {\n readystatechange: ProgressEvent<XMLHttpRequestEventTarget>\n }),\n >(\n eventName: EventName,\n target: XMLHttpRequest | XMLHttpRequestUpload,\n options?: ProgressEventInit\n ): void {\n const callback = (target as XMLHttpRequest)[`on${eventName}`]\n const event = createEvent(target, eventName, options)\n\n this.logger.verbose('trigger \"%s\"', eventName, options || '')\n\n // Invoke direct callbacks.\n if (typeof callback === 'function') {\n this.logger.verbose('found a direct \"%s\" callback, calling...', eventName)\n callback.call(target as XMLHttpRequest, event)\n }\n\n // Invoke event listeners.\n const events =\n target instanceof XMLHttpRequestUpload ? this.uploadEvents : this.events\n\n for (const [registeredEventName, listeners] of events) {\n if (registeredEventName === eventName) {\n this.logger.verbose(\n 'found %d listener(s) for \"%s\" event, calling...',\n listeners.length,\n eventName\n )\n\n listeners.forEach((listener) => listener.call(target, event))\n }\n }\n }\n\n /**\n * Converts this `XMLHttpRequest` instance into a Fetch API `Request` instance.\n */\n private toFetchApiRequest(\n body: XMLHttpRequestBodyInit | Document | null | undefined\n ): Request {\n this.logger.verbose('converting request to a Fetch API Request...')\n\n // If the `Document` is used as the body of this XMLHttpRequest,\n // set its inner text as the Fetch API Request body.\n const resolvedBody =\n body instanceof Document ? body.documentElement.innerText : body\n\n const fetchRequest = new FetchRequest(this.url.href, {\n method: this.method,\n headers: this.requestHeaders,\n /**\n * @see https://xhr.spec.whatwg.org/#cross-origin-credentials\n */\n credentials: this.request.withCredentials ? 'include' : 'same-origin',\n body: resolvedBody,\n })\n\n const headers = fetchRequest.headers\n const proxyHeaders = createProxy(headers, {\n methodCall: ([methodName, args], invoke) => {\n const result = invoke()\n\n // Forward the latest state of the internal request headers\n // because the interceptor might have modified them\n // without responding to the request.\n switch (methodName) {\n case 'append':\n case 'set': {\n const [headerName, headerValue] = args as [string, string]\n\n /**\n * @note Forward only the headers the Fetch API Request accepted.\n * Forbidden request headers (e.g. \"Cookie\") are dropped silently\n * by the request's headers guard, and forwarding them makes\n * the browser refuse them with an error in the console.\n */\n if (headers.has(headerName)) {\n this.request.setRequestHeader(headerName, headerValue)\n }\n break\n }\n\n case 'delete': {\n const [headerName] = args as [string]\n console.warn(\n `XMLHttpRequest: Cannot remove a \"${headerName}\" header from the Fetch API representation of the \"${fetchRequest.method} ${fetchRequest.url}\" request. XMLHttpRequest headers cannot be removed.`\n )\n break\n }\n }\n\n return result\n },\n })\n define(fetchRequest, 'headers', proxyHeaders)\n // setRawRequest(fetchRequest, this.request)\n\n this.logger.verbose('converted request to a Fetch API Request!', fetchRequest)\n\n return fetchRequest\n }\n}\n\nfunction toAbsoluteUrl(url: string | URL): URL {\n /**\n * @note XMLHttpRequest interceptor may run in environments\n * that implement XMLHttpRequest but don't implement \"location\"\n * (for example, React Native). If that's the case, return the\n * input URL as-is (nothing to be relative to).\n * @see https://github.com/mswjs/msw/issues/1777\n */\n if (typeof location === 'undefined') {\n return new URL(url)\n }\n\n return new URL(url.toString(), location.href)\n}\n\nfunction define(\n target: object,\n property: string | symbol,\n value: unknown\n): void {\n Reflect.defineProperty(target, property, {\n // Ensure writable properties to allow redefining readonly properties.\n writable: true,\n enumerable: true,\n value,\n })\n}\n","import type { Emitter } from 'rettime'\nimport { HttpResponseEvent, type HttpRequestEventMap } from '../../events/http'\nimport { RequestController } from '../../request-controller'\nimport { XMLHttpRequestController } from './xml-http-request-controller'\nimport { handleRequest } from '../../utils/handle-request'\nimport type { Logger } from '../../utils/logger'\n\nexport interface XMLHttpRequestProxyOptions {\n emitter: Emitter<HttpRequestEventMap>\n logger: Logger\n}\n\n/**\n * Create a proxied `XMLHttpRequest` class.\n * The proxied class establishes spies on certain methods,\n * allowing us to intercept requests and respond to them.\n */\nexport function createXMLHttpRequestProxy({\n emitter,\n logger,\n}: XMLHttpRequestProxyOptions) {\n const XMLHttpRequestProxy = new Proxy(globalThis.XMLHttpRequest, {\n construct(target, args, newTarget) {\n logger.verbose('constructed new XMLHttpRequest')\n\n const originalRequest = Reflect.construct(\n target,\n args,\n newTarget\n ) as XMLHttpRequest\n\n /**\n * @note Forward prototype descriptors onto the proxied object.\n * XMLHttpRequest is implemented in JSDOM in a way that assigns\n * a bunch of descriptors, like \"set responseType()\" on the prototype.\n * With this propagation, we make sure that those descriptors trigger\n * when the user operates with the proxied request instance.\n */\n const prototypeDescriptors = Object.getOwnPropertyDescriptors(\n target.prototype\n )\n for (const propertyName in prototypeDescriptors) {\n Reflect.defineProperty(\n originalRequest,\n propertyName,\n prototypeDescriptors[propertyName]\n )\n }\n\n const xhrRequestController = new XMLHttpRequestController(\n originalRequest,\n logger\n )\n\n xhrRequestController.onRequest = async function ({ request, requestId }) {\n const controller = new RequestController(request, {\n passthrough: () => {\n this.logger.verbose(\n 'no mocked response received, performing request as-is...'\n )\n },\n respondWith: async (response) => {\n await this.respondWith(response)\n },\n errorWith: (reason) => {\n this.logger.verbose('request errored %o', { error: reason })\n\n if (reason instanceof Error) {\n this.errorWith(reason)\n }\n },\n }, {\n logger,\n requestId,\n })\n\n this.logger.verbose('awaiting mocked response')\n\n this.logger.verbose(\n 'emitting the \"request\" event for %s listener(s)...',\n emitter.listenerCount('request')\n )\n\n await handleRequest({\n initiator: this.request,\n request,\n requestId,\n controller,\n emitter,\n logger,\n })\n }\n\n xhrRequestController.onResponse = async function ({\n response,\n responseType,\n request,\n requestId,\n }) {\n this.logger.verbose(\n 'emitting the \"response\" event for %s listener(s)...',\n emitter.listenerCount('response')\n )\n\n await emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator: this.request,\n response,\n responseType,\n request,\n requestId,\n })\n )\n }\n\n // Return the proxied request from the controller\n // so that the controller can react to the consumer's interactions\n // with this request (opening/sending/etc).\n return xhrRequestController.request\n },\n })\n\n return XMLHttpRequestProxy\n}\n","import { HttpRequestEventMap } from '../../events/http'\nimport { Interceptor } from '../../interceptor'\nimport { createXMLHttpRequestProxy } from './xml-http-request-proxy'\nimport { hasConfigurableGlobal } from '../../utils/has-configurable-global'\nimport { patchesRegistry } from '../../utils/patches-registry'\nimport { createLogger } from '../../utils/logger'\n\nconst logger = createLogger('xhr')\n\nexport class XMLHttpRequestInterceptor extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol.for('xhr-interceptor')\n\n protected predicate() {\n return hasConfigurableGlobal('XMLHttpRequest')\n }\n\n protected setup() {\n logger.verbose('patching \"XMLHttpRequest\"...')\n\n this.subscriptions.push(\n patchesRegistry.applyPatch(globalThis, 'XMLHttpRequest', () => {\n return createXMLHttpRequestProxy({\n emitter: this.emitter,\n logger,\n })\n })\n )\n\n logger.verbose(\n 'global \"XMLHttpRequest\" patched!',\n globalThis.XMLHttpRequest.name\n )\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as forwardHttpEvents, o as runInRequestContext, t as NodeHttpRequestSource } from "../../source-
|
|
1
|
+
import { i as forwardHttpEvents, o as runInRequestContext, t as NodeHttpRequestSource } from "../../source-Bs0HXaSq.js";
|
|
2
2
|
import { t as Interceptor } from "../../interceptor-C8qRPjxG.js";
|
|
3
3
|
import { n as patchesRegistry } from "../../patches-registry-DxR5TEc-.js";
|
|
4
4
|
import http from "node:http";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as requestContext, i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-
|
|
1
|
+
import { a as requestContext, i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-Bs0HXaSq.js";
|
|
2
2
|
import { n as createLogger, t as Interceptor } from "../../interceptor-C8qRPjxG.js";
|
|
3
3
|
import { t as FetchRequest } from "../../fetch-utils-D-_xeRlK.js";
|
|
4
4
|
import { n as patchesRegistry } from "../../patches-registry-DxR5TEc-.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as requestContext, i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-
|
|
1
|
+
import { a as requestContext, i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-Bs0HXaSq.js";
|
|
2
2
|
import { t as Interceptor } from "../../interceptor-C8qRPjxG.js";
|
|
3
3
|
import { i as getErrorResponse } from "../../fetch-utils-D-_xeRlK.js";
|
|
4
4
|
import { n as patchesRegistry } from "../../patches-registry-DxR5TEc-.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-
|
|
1
|
+
import { i as forwardHttpEvents, t as NodeHttpRequestSource } from "../../source-Bs0HXaSq.js";
|
|
2
2
|
import { t as Interceptor } from "../../interceptor-C8qRPjxG.js";
|
|
3
3
|
//#region src/interceptors/http/index.ts
|
|
4
4
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as handleRequest, r as HttpResponseEvent } from "./source-
|
|
1
|
+
import { n as handleRequest, r as HttpResponseEvent } from "./source-Bs0HXaSq.js";
|
|
2
2
|
import { n as createLogger, t as Interceptor } from "./interceptor-C8qRPjxG.js";
|
|
3
3
|
import { t as BatchInterceptor } from "./batch-interceptor-DMOfd-9x.js";
|
|
4
4
|
import { a as isResponseError, f as RequestController, n as FetchResponse, t as FetchRequest } from "./fetch-utils-D-_xeRlK.js";
|
|
@@ -2121,6 +2121,16 @@ var NodeHttpRequestSource = class extends Interceptor {
|
|
|
2121
2121
|
httpMessageHeaders.set(headerName, headerValue);
|
|
2122
2122
|
}
|
|
2123
2123
|
visitedHeaders.clear();
|
|
2124
|
+
/**
|
|
2125
|
+
* @note Remove the headers deleted from the request (e.g. via
|
|
2126
|
+
* `request.headers.delete()`). The raw headers start as a copy of
|
|
2127
|
+
* the outgoing HTTP message headers and track every mutation, so a
|
|
2128
|
+
* header present in the message but absent from the raw headers has
|
|
2129
|
+
* been deleted. Forbidden headers stripped from `request.headers`
|
|
2130
|
+
* remain in the raw headers and are preserved as-is.
|
|
2131
|
+
*/
|
|
2132
|
+
const rawHeaderNames = new Set(requestRawHeaders.map(([headerName]) => headerName.toLowerCase()));
|
|
2133
|
+
for (const [headerName] of httpMessageRawHeaders) if (!rawHeaderNames.has(headerName.toLowerCase())) httpMessageHeaders.delete(headerName);
|
|
2124
2134
|
const httpMessageHeadersString = Array.from(httpMessageHeaders).map(([name, value]) => `${name}: ${value}`).join("\r\n");
|
|
2125
2135
|
parts.splice(1, headersEndIndex - 1, httpMessageHeadersString);
|
|
2126
2136
|
return parts.join("\r\n");
|
|
@@ -2135,4 +2145,4 @@ var NodeHttpRequestSource = class extends Interceptor {
|
|
|
2135
2145
|
//#endregion
|
|
2136
2146
|
export { requestContext as a, forwardHttpEvents as i, handleRequest as n, runInRequestContext as o, HttpResponseEvent as r, NodeHttpRequestSource as t };
|
|
2137
2147
|
|
|
2138
|
-
//# sourceMappingURL=source-
|
|
2148
|
+
//# sourceMappingURL=source-Bs0HXaSq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-C_hSJzNQ.js","names":["constants","#checkError","#upgrade","#requestBodyStream","#status","#responseBodyStream","#modifyHttpHeaders"],"sources":["../../src/request-context.ts","../../src/interceptors/http/forward-events.ts","../../src/events/http.ts","../../src/interceptors/net/utils/connection-options-to-url.ts","../../src/interceptors/http/http-parser/llhttp/constants.cjs","../../src/interceptors/http/http-parser/index.ts","../../src/interceptors/http/http-parser.ts","../../src/utils/is-node-like-error.ts","../../src/utils/handle-request.ts","../../src/utils/clone-response.ts","../../src/interceptors/http/source.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Logger } from './utils/logger'\n\ninterface RequestContext {\n initiator: unknown\n logger?: Logger\n transformRequest?: (request: Request) => Request\n}\n\nexport const requestContext = new AsyncLocalStorage<RequestContext>()\n\nexport function runInRequestContext<T>(callback: () => T, logger?: Logger): T {\n /**\n * @note Never shadow an existing request context. Nested calls\n * (e.g. a patched entry point re-entered synchronously, or a request\n * made within the fetch/XMLHttpRequest interceptor context) must run\n * within the parent context so the sockets they create capture it.\n */\n if (requestContext.getStore()) {\n return callback()\n }\n\n /**\n * @note The initiator is the callback's return value (e.g. the\n * \"ClientRequest\" instance), so it cannot be known before running\n * the callback. The context is mutated in place once the callback\n * returns; readers hold the context object by reference and sample\n * \"initiator\" only after the request has been written.\n */\n const context: RequestContext = {\n initiator: undefined,\n logger,\n }\n\n return requestContext.run(context, () => {\n const initiator = callback()\n context.initiator = initiator\n return initiator\n })\n}\n","import { type Emitter } from 'rettime'\nimport {\n type HttpRequestEventMap,\n type HttpResponseEvent,\n} from '#/src/events/http'\nimport { type Interceptor } from '#/src/interceptor'\nimport { type DisposableSubscription } from '#/src/disposable'\nimport { createLogger } from '#/src/utils/logger'\n\nconst logger = createLogger('http-request')\n\ninterface ForwardHttpEventsOptions {\n source: Interceptor<HttpRequestEventMap>\n emitter: Emitter<HttpRequestEventMap>\n predicate: (initiator: unknown) => boolean\n responsePredicate?: (event: HttpResponseEvent) => boolean\n}\n\nexport function forwardHttpEvents(\n options: ForwardHttpEventsOptions\n): DisposableSubscription {\n const controller = new AbortController()\n const { source, emitter, predicate, responsePredicate } = options\n\n source.on(\n 'request',\n async (event) => {\n if (predicate(event.initiator)) {\n logger.verbose('forwarding \"request\" event %o', {\n requestId: event.requestId,\n })\n await emitter.emitAsPromise(event)\n }\n },\n {\n signal: controller.signal,\n }\n )\n\n const responseListener: Emitter.Listener<\n Emitter<HttpRequestEventMap>,\n 'response'\n > = async (event) => {\n if (\n predicate(event.initiator) &&\n (responsePredicate == null || responsePredicate(event))\n ) {\n logger.verbose('forwarding \"response\" event %o', {\n requestId: event.requestId,\n responseType: event.responseType,\n })\n await emitter.emitAsPromise(event)\n }\n }\n\n const unhandledExceptionListener: Emitter.Listener<\n Emitter<HttpRequestEventMap>,\n 'unhandledException'\n > = async (event) => {\n if (predicate(event.initiator)) {\n logger.verbose('forwarding \"unhandledException\" event %o', {\n requestId: event.requestId,\n })\n await emitter.emitAsPromise(event)\n }\n }\n\n const addResponseListener = (): void => {\n if (!source.listeners('response').includes(responseListener)) {\n source.on('response', responseListener, {\n signal: controller.signal,\n })\n }\n }\n\n const addUnhandledExceptionListener = (): void => {\n if (\n !source\n .listeners('unhandledException')\n .includes(unhandledExceptionListener)\n ) {\n source.on('unhandledException', unhandledExceptionListener, {\n signal: controller.signal,\n })\n }\n }\n\n if (emitter.listenerCount('response') > 0) {\n addResponseListener()\n }\n\n if (emitter.listenerCount('unhandledException') > 0) {\n addUnhandledExceptionListener()\n }\n\n emitter.hooks.on(\n 'newListener',\n (type) => {\n if (type === 'response') {\n addResponseListener()\n }\n\n if (type === 'unhandledException') {\n addUnhandledExceptionListener()\n }\n },\n {\n signal: controller.signal,\n persist: true,\n }\n )\n\n emitter.hooks.on(\n 'removeListener',\n (type) => {\n if (type === 'response' && emitter.listenerCount('response') === 0) {\n source.removeListener('response', responseListener)\n }\n\n if (\n type === 'unhandledException' &&\n emitter.listenerCount('unhandledException') === 0\n ) {\n source.removeListener(\n 'unhandledException',\n unhandledExceptionListener\n )\n }\n },\n {\n signal: controller.signal,\n persist: true,\n }\n )\n\n return () => {\n controller.abort()\n }\n}\n","import { TypedEvent } from 'rettime'\nimport type { RequestController } from '../request-controller'\n\nexport interface HttpRequestEventData {\n request: Request\n requestId: string\n initiator: unknown\n controller: RequestController\n}\n\nexport class HttpRequestEvent<\n DataType extends HttpRequestEventData = HttpRequestEventData,\n> extends TypedEvent<DataType, void, 'request'> {\n public request: Request\n public requestId: string\n public initiator: unknown\n public controller: RequestController\n\n constructor(data: DataType) {\n super(...(['request', {}] as any))\n\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n this.controller = data.controller\n }\n}\n\nexport type HttpResponseType = 'mock' | 'original'\n\ninterface HttpResponseEventData {\n response: Response\n responseType: HttpResponseType\n request: Request\n requestId: string\n initiator: unknown\n}\n\nexport class HttpResponseEvent<\n DataType extends HttpResponseEventData = HttpResponseEventData,\n> extends TypedEvent<DataType, void, 'response'> {\n public response: Response\n public responseType: HttpResponseType\n public request: Request\n public requestId: string\n public initiator: unknown\n\n constructor(data: DataType) {\n super(...(['response', {}] as any))\n\n this.response = data.response\n this.responseType = data.responseType\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n }\n}\n\ninterface UnhandledHttpExceptionEventData {\n error: unknown\n request: Request\n requestId: string\n initiator: unknown\n controller: RequestController\n}\n\nexport class UnhandledHttpException<\n DataType extends UnhandledHttpExceptionEventData =\n UnhandledHttpExceptionEventData,\n> extends TypedEvent<DataType, void, 'unhandledException'> {\n public error: unknown\n public request: Request\n public requestId: string\n public initiator: unknown\n public controller: RequestController\n\n constructor(data: DataType) {\n super(...(['unhandledException', {}] as any))\n\n this.error = data.error\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n this.controller = data.controller\n }\n}\n\nexport type HttpRequestEventMap = {\n request: HttpRequestEvent\n response: HttpResponseEvent\n unhandledException: UnhandledHttpException\n}\n","import net from 'node:net'\nimport tls from 'node:tls'\nimport { NetworkConnectionOptions } from './normalize-net-connect-args'\n\n/**\n * Creates a `URL` instance out of the `net.connect()` options.\n * @note This implies that the passed connection is an HTTP connection.\n */\nexport function connectionOptionsToUrl(\n options: NetworkConnectionOptions,\n socket: net.Socket\n): URL {\n const isIPv6 = net.isIPv6(options.host || '')\n const protocol =\n socket instanceof tls.TLSSocket\n ? 'https:'\n : getProtocolByConnectionOptions(options)\n const host = options.host || 'localhost'\n\n const url = new URL(`${protocol}//${isIPv6 ? `[${host}]` : host}`)\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n /**\n * Authentication options are provided as plain values.\n * Encode them to form a valid URL.\n * @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/internal/url.js#L1452\n */\n url.username = encodeURIComponent(username)\n url.password = encodeURIComponent(password)\n }\n\n return url\n}\n\nfunction getProtocolByConnectionOptions(\n options: NetworkConnectionOptions\n): 'https:' | 'http:' | (string & {}) {\n if (options.protocol) {\n return options.protocol\n }\n\n if (options.port === 443) {\n return 'https:'\n }\n\n return 'http:'\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SPECIAL_HEADERS = exports.MINOR = exports.MAJOR = exports.QDTEXT = exports.CONNECTION_TOKEN_CHARS = exports.RELAXED_HEADER_CHARS = exports.HEADER_CHARS = exports.HTAB_SP_VCHAR_OBS_TEXT = exports.SP = exports.HTAB = exports.TOKEN = exports.HEX = exports.URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.DIGIT = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.METHODS = exports.METHODS_HTTP = exports.METHODS_HTTP2 = exports.METHODS_HTTP1 = exports.METHODS_RTSP = exports.METHODS_RAOP = exports.METHODS_AIRPLAY = exports.METHODS_ICECAST = exports.METHODS_NON_STANDARD = exports.METHODS_CALDAV = exports.METHODS_UPNP = exports.METHODS_SUBVERSION = exports.METHODS_WEBDAV = exports.METHODS_BASIC_HTTP = exports.METHODS_HTTP1_HEAD = exports.HEADER_STATE = exports.FINISH = exports.STATUSES = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0;\nexports.ERROR = {\n OK: 0,\n INTERNAL: 1,\n STRICT: 2,\n CR_EXPECTED: 25,\n LF_EXPECTED: 3,\n UNEXPECTED_CONTENT_LENGTH: 4,\n UNEXPECTED_SPACE: 30,\n CLOSED_CONNECTION: 5,\n INVALID_METHOD: 6,\n INVALID_URL: 7,\n INVALID_CONSTANT: 8,\n INVALID_VERSION: 9,\n INVALID_HEADER_TOKEN: 10,\n INVALID_CONTENT_LENGTH: 11,\n INVALID_CHUNK_SIZE: 12,\n INVALID_STATUS: 13,\n INVALID_EOF_STATE: 14,\n INVALID_TRANSFER_ENCODING: 15,\n CB_MESSAGE_BEGIN: 16,\n CB_HEADERS_COMPLETE: 17,\n CB_MESSAGE_COMPLETE: 18,\n CB_CHUNK_HEADER: 19,\n CB_CHUNK_COMPLETE: 20,\n PAUSED: 21,\n PAUSED_UPGRADE: 22,\n PAUSED_H2_UPGRADE: 23,\n USER: 24,\n CB_URL_COMPLETE: 26,\n CB_STATUS_COMPLETE: 27,\n CB_METHOD_COMPLETE: 32,\n CB_VERSION_COMPLETE: 33,\n CB_HEADER_FIELD_COMPLETE: 28,\n CB_HEADER_VALUE_COMPLETE: 29,\n CB_CHUNK_EXTENSION_NAME_COMPLETE: 34,\n CB_CHUNK_EXTENSION_VALUE_COMPLETE: 35,\n CB_RESET: 31,\n CB_PROTOCOL_COMPLETE: 38,\n};\nexports.TYPE = {\n BOTH: 0, // default\n REQUEST: 1,\n RESPONSE: 2,\n};\nexports.FLAGS = {\n CONNECTION_KEEP_ALIVE: 1 << 0,\n CONNECTION_CLOSE: 1 << 1,\n CONNECTION_UPGRADE: 1 << 2,\n CHUNKED: 1 << 3,\n UPGRADE: 1 << 4,\n CONTENT_LENGTH: 1 << 5,\n SKIPBODY: 1 << 6,\n TRAILING: 1 << 7,\n // 1 << 8 is unused\n TRANSFER_ENCODING: 1 << 9,\n};\nexports.LENIENT_FLAGS = {\n HEADERS: 1 << 0,\n CHUNKED_LENGTH: 1 << 1,\n KEEP_ALIVE: 1 << 2,\n TRANSFER_ENCODING: 1 << 3,\n VERSION: 1 << 4,\n DATA_AFTER_CLOSE: 1 << 5,\n OPTIONAL_LF_AFTER_CR: 1 << 6,\n OPTIONAL_CRLF_AFTER_CHUNK: 1 << 7,\n OPTIONAL_CR_BEFORE_LF: 1 << 8,\n SPACES_AFTER_CHUNK_SIZE: 1 << 9,\n HEADER_VALUE_RELAXED: 1 << 10,\n};\nexports.STATUSES = {\n CONTINUE: 100,\n SWITCHING_PROTOCOLS: 101,\n PROCESSING: 102,\n EARLY_HINTS: 103,\n RESPONSE_IS_STALE: 110, // Unofficial\n REVALIDATION_FAILED: 111, // Unofficial\n DISCONNECTED_OPERATION: 112, // Unofficial\n HEURISTIC_EXPIRATION: 113, // Unofficial\n MISCELLANEOUS_WARNING: 199, // Unofficial\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NON_AUTHORITATIVE_INFORMATION: 203,\n NO_CONTENT: 204,\n RESET_CONTENT: 205,\n PARTIAL_CONTENT: 206,\n MULTI_STATUS: 207,\n ALREADY_REPORTED: 208,\n TRANSFORMATION_APPLIED: 214, // Unofficial\n IM_USED: 226,\n MISCELLANEOUS_PERSISTENT_WARNING: 299, // Unofficial\n MULTIPLE_CHOICES: 300,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n USE_PROXY: 305,\n SWITCH_PROXY: 306, // No longer used\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n EXPECTATION_FAILED: 417,\n IM_A_TEAPOT: 418,\n PAGE_EXPIRED: 419, // Unofficial\n ENHANCE_YOUR_CALM: 420, // Unofficial\n MISDIRECTED_REQUEST: 421,\n UNPROCESSABLE_ENTITY: 422,\n LOCKED: 423,\n FAILED_DEPENDENCY: 424,\n TOO_EARLY: 425,\n UPGRADE_REQUIRED: 426,\n PRECONDITION_REQUIRED: 428,\n TOO_MANY_REQUESTS: 429,\n REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL: 430, // Unofficial\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n LOGIN_TIMEOUT: 440, // Unofficial\n NO_RESPONSE: 444, // Unofficial\n RETRY_WITH: 449, // Unofficial\n BLOCKED_BY_PARENTAL_CONTROL: 450, // Unofficial\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n CLIENT_CLOSED_LOAD_BALANCED_REQUEST: 460, // Unofficial\n INVALID_X_FORWARDED_FOR: 463, // Unofficial\n REQUEST_HEADER_TOO_LARGE: 494, // Unofficial\n SSL_CERTIFICATE_ERROR: 495, // Unofficial\n SSL_CERTIFICATE_REQUIRED: 496, // Unofficial\n HTTP_REQUEST_SENT_TO_HTTPS_PORT: 497, // Unofficial\n INVALID_TOKEN: 498, // Unofficial\n CLIENT_CLOSED_REQUEST: 499, // Unofficial\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n VARIANT_ALSO_NEGOTIATES: 506,\n INSUFFICIENT_STORAGE: 507,\n LOOP_DETECTED: 508,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n NOT_EXTENDED: 510,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n WEB_SERVER_UNKNOWN_ERROR: 520, // Unofficial\n WEB_SERVER_IS_DOWN: 521, // Unofficial\n CONNECTION_TIMEOUT: 522, // Unofficial\n ORIGIN_IS_UNREACHABLE: 523, // Unofficial\n TIMEOUT_OCCURED: 524, // Unofficial\n SSL_HANDSHAKE_FAILED: 525, // Unofficial\n INVALID_SSL_CERTIFICATE: 526, // Unofficial\n RAILGUN_ERROR: 527, // Unofficial\n SITE_IS_OVERLOADED: 529, // Unofficial\n SITE_IS_FROZEN: 530, // Unofficial\n IDENTITY_PROVIDER_AUTHENTICATION_ERROR: 561, // Unofficial\n NETWORK_READ_TIMEOUT: 598, // Unofficial\n NETWORK_CONNECT_TIMEOUT: 599, // Unofficial\n};\nexports.FINISH = {\n SAFE: 0,\n SAFE_WITH_CB: 1,\n UNSAFE: 2,\n};\nexports.HEADER_STATE = {\n GENERAL: 0,\n CONNECTION: 1,\n CONTENT_LENGTH: 2,\n TRANSFER_ENCODING: 3,\n UPGRADE: 4,\n CONNECTION_KEEP_ALIVE: 5,\n CONNECTION_CLOSE: 6,\n CONNECTION_UPGRADE: 7,\n TRANSFER_ENCODING_CHUNKED: 8,\n};\nexports.METHODS_HTTP1_HEAD = {\n HEAD: 2,\n};\n/**\n * HTTP methods as defined by RFC-9110 and other specifications.\n * @see https://httpwg.org/specs/rfc9110.html#method.definitions\n */\nexports.METHODS_BASIC_HTTP = {\n DELETE: 0,\n GET: 1,\n ...exports.METHODS_HTTP1_HEAD,\n POST: 3,\n PUT: 4,\n CONNECT: 5,\n OPTIONS: 6,\n TRACE: 7,\n /**\n * @see https://www.rfc-editor.org/rfc/rfc5789.html\n */\n PATCH: 28,\n /* RFC-2068, section 19.6.1.2 */\n LINK: 31,\n UNLINK: 32,\n};\nexports.METHODS_WEBDAV = {\n COPY: 8,\n LOCK: 9,\n MKCOL: 10,\n MOVE: 11,\n PROPFIND: 12,\n PROPPATCH: 13,\n SEARCH: 14,\n UNLOCK: 15,\n BIND: 16,\n REBIND: 17,\n UNBIND: 18,\n ACL: 19,\n};\nexports.METHODS_SUBVERSION = {\n REPORT: 20,\n MKACTIVITY: 21,\n CHECKOUT: 22,\n MERGE: 23,\n};\nexports.METHODS_UPNP = {\n 'M-SEARCH': 24,\n NOTIFY: 25,\n SUBSCRIBE: 26,\n UNSUBSCRIBE: 27,\n};\nexports.METHODS_CALDAV = {\n MKCALENDAR: 30,\n};\nexports.METHODS_NON_STANDARD = {\n /**\n * Not defined in any RFC but commonly used\n */\n PURGE: 29,\n /* DRAFT https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html */\n QUERY: 46,\n};\nexports.METHODS_ICECAST = {\n SOURCE: 33,\n};\nexports.METHODS_AIRPLAY = {\n GET: 1,\n POST: 3,\n};\nexports.METHODS_RAOP = {\n FLUSH: 45,\n};\n/* RFC-2326 RTSP */\nexports.METHODS_RTSP = {\n OPTIONS: exports.METHODS_BASIC_HTTP.OPTIONS,\n DESCRIBE: 35,\n ANNOUNCE: 36,\n SETUP: 37,\n PLAY: 38,\n PAUSE: 39,\n TEARDOWN: 40,\n GET_PARAMETER: 41,\n SET_PARAMETER: 42,\n REDIRECT: 43,\n RECORD: 44,\n ...exports.METHODS_AIRPLAY,\n ...exports.METHODS_RAOP,\n};\nexports.METHODS_HTTP1 = {\n ...exports.METHODS_BASIC_HTTP,\n ...exports.METHODS_WEBDAV,\n ...exports.METHODS_SUBVERSION,\n ...exports.METHODS_UPNP,\n ...exports.METHODS_CALDAV,\n ...exports.METHODS_NON_STANDARD,\n // TODO(indutny): should we allow it with HTTP?\n ...exports.METHODS_ICECAST,\n};\nexports.METHODS_HTTP2 = {\n /**\n * RFC-9113, section 11.6\n * @see https://www.rfc-editor.org/rfc/rfc9113.html#preface\n */\n PRI: 34,\n};\nexports.METHODS_HTTP = {\n ...exports.METHODS_HTTP1,\n ...exports.METHODS_HTTP2,\n};\nexports.METHODS = {\n ...exports.METHODS_HTTP1,\n ...exports.METHODS_HTTP2,\n ...exports.METHODS_RTSP,\n};\n// ALPHA: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.ALPHA = [\n \"A\", \"a\", \"B\", \"b\", \"C\", \"c\", \"D\", \"d\",\n \"E\", \"e\", \"F\", \"f\", \"G\", \"g\", \"H\", \"h\",\n \"I\", \"i\", \"J\", \"j\", \"K\", \"k\", \"L\", \"l\",\n \"M\", \"m\", \"N\", \"n\", \"O\", \"o\", \"P\", \"p\",\n \"Q\", \"q\", \"R\", \"r\", \"S\", \"s\", \"T\", \"t\",\n \"U\", \"u\", \"V\", \"v\", \"W\", \"w\", \"X\", \"x\",\n \"Y\", \"y\", \"Z\", \"z\",\n];\nexports.NUM_MAP = {\n 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,\n 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,\n};\nexports.HEX_MAP = {\n 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,\n 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,\n A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF,\n a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf,\n};\n// DIGIT: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.DIGIT = [\n '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n];\nexports.ALPHANUM = [...exports.ALPHA, ...exports.DIGIT];\nexports.MARK = ['-', '_', '.', '!', '~', '*', '\\'', '(', ')'];\nexports.USERINFO_CHARS = [...exports.ALPHANUM, ...exports.MARK, '%', ';', ':', '&', '=', '+', '$', ','];\n// TODO(indutny): use RFC\nexports.URL_CHAR = [\n '!', '\"', '$', '%', '&', '\\'',\n '(', ')', '*', '+', ',', '-', '.', '/',\n ':', ';', '<', '=', '>',\n '@', '[', '\\\\', ']', '^', '_',\n '`',\n '{', '|', '}', '~',\n ...exports.ALPHANUM\n];\nexports.HEX = [...exports.DIGIT, 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'];\n/* Tokens as defined by rfc 2616. Also lowercases them.\n * token = 1*<any CHAR except CTLs or separators>\n * separators = \"(\" | \")\" | \"<\" | \">\" | \"@\"\n * | \",\" | \";\" | \":\" | \"\\\" | <\">\n * | \"/\" | \"[\" | \"]\" | \"?\" | \"=\"\n * | \"{\" | \"}\" | SP | HT\n */\nexports.TOKEN = [\n '!', '#', '$', '%', '&', '\\'',\n '*', '+', '-', '.',\n '^', '_', '`',\n '|', '~',\n ...exports.ALPHANUM\n];\n// HTAB: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.HTAB = ['\\t'];\n// SP: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.SP = [' '];\n// VCHAR: https://tools.ietf.org/html/rfc5234#appendix-B.1\nconst VCHAR = [\n 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,\n 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,\n 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,\n 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,\n 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,\n 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,\n 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,\n 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,\n 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,\n 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,\n];\n// OBS_TEXT: https://datatracker.ietf.org/doc/html/rfc9110#name-collected-abnf\n// 0x80 - 0xff\nconst OBS_TEXT = [\n 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,\n 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,\n 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,\n 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,\n 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,\n 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,\n 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,\n 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,\n];\nexports.HTAB_SP_VCHAR_OBS_TEXT = [...exports.HTAB, ...exports.SP, ...VCHAR, ...OBS_TEXT];\nexports.HEADER_CHARS = exports.HTAB_SP_VCHAR_OBS_TEXT;\nconst RELAXED_CTRL_CHARS = [\n 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Before TAB\n 0x0b, 0x0c, // VT, FF (between TAB and CR)\n 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // After CR/LF, before space\n 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,\n 0x1e, 0x1f,\n 0x7f, // DEL\n];\n// Relaxed header chars includes control characters (above) that are not allowed\n// by default. This excludes only NULL (0x00), CR (0x0d), LF (0x0a).\nexports.RELAXED_HEADER_CHARS = [...RELAXED_CTRL_CHARS, ...exports.HEADER_CHARS];\n// ',' = \\x2c\nexports.CONNECTION_TOKEN_CHARS = [\n ...exports.HTAB, ...exports.SP,\n 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x2b, /* */ 0x2d, 0x2e, 0x2f, 0x30,\n 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,\n 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,\n 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,\n 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,\n 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,\n 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,\n 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,\n 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,\n 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,\n ...OBS_TEXT\n];\n// QDTEXT: https://datatracker.ietf.org/doc/html/rfc9110#section-5.6.4\nexports.QDTEXT = [\n ...exports.HTAB, ...exports.SP,\n 0x21,\n 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,\n 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,\n 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,\n 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42,\n 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,\n 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,\n 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,\n 0x5b,\n 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64,\n 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,\n 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,\n 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c,\n 0x7d, 0x7e,\n ...OBS_TEXT\n];\nexports.MAJOR = exports.NUM_MAP;\nexports.MINOR = exports.MAJOR;\nexports.SPECIAL_HEADERS = {\n 'connection': exports.HEADER_STATE.CONNECTION,\n 'content-length': exports.HEADER_STATE.CONTENT_LENGTH,\n 'proxy-connection': exports.HEADER_STATE.CONNECTION,\n 'transfer-encoding': exports.HEADER_STATE.TRANSFER_ENCODING,\n 'upgrade': exports.HEADER_STATE.UPGRADE,\n};\nexports.default = {\n ERROR: exports.ERROR,\n TYPE: exports.TYPE,\n FLAGS: exports.FLAGS,\n LENIENT_FLAGS: exports.LENIENT_FLAGS,\n STATUSES: exports.STATUSES,\n FINISH: exports.FINISH,\n HEADER_STATE: exports.HEADER_STATE,\n ALPHA: exports.ALPHA,\n NUM_MAP: exports.NUM_MAP,\n HEX_MAP: exports.HEX_MAP,\n DIGIT: exports.DIGIT,\n ALPHANUM: exports.ALPHANUM,\n MARK: exports.MARK,\n USERINFO_CHARS: exports.USERINFO_CHARS,\n URL_CHAR: exports.URL_CHAR,\n HEX: exports.HEX,\n TOKEN: exports.TOKEN,\n HEADER_CHARS: exports.HEADER_CHARS,\n RELAXED_HEADER_CHARS: exports.RELAXED_HEADER_CHARS,\n CONNECTION_TOKEN_CHARS: exports.CONNECTION_TOKEN_CHARS,\n QDTEXT: exports.QDTEXT,\n HTAB_SP_VCHAR_OBS_TEXT: exports.HTAB_SP_VCHAR_OBS_TEXT,\n MAJOR: exports.MAJOR,\n MINOR: exports.MINOR,\n SPECIAL_HEADERS: exports.SPECIAL_HEADERS,\n METHODS: exports.METHODS,\n METHODS_HTTP: exports.METHODS_HTTP,\n METHODS_HTTP1_HEAD: exports.METHODS_HTTP1_HEAD,\n METHODS_HTTP1: exports.METHODS_HTTP1,\n METHODS_HTTP2: exports.METHODS_HTTP2,\n METHODS_ICECAST: exports.METHODS_ICECAST,\n METHODS_RTSP: exports.METHODS_RTSP,\n};","import fs from 'node:fs'\nimport * as constants from './llhttp/constants.cjs'\n\nexport { constants }\n\nexport interface RequestHeadersComplete {\n versionMajor: number\n versionMinor: number\n rawHeaders: Array<string>\n method: string\n url: string\n upgrade: boolean\n shouldKeepAlive: boolean\n}\n\nexport interface ResponseHeadersComplete {\n versionMajor: number\n versionMinor: number\n rawHeaders: Array<string>\n statusCode: number\n statusMessage: string\n upgrade: boolean\n shouldKeepAlive: boolean\n}\n\nconst KIND_REQUEST = constants.TYPE.REQUEST\nconst KIND_RESPONSE = constants.TYPE.RESPONSE\n\ntype ParserKind = typeof KIND_REQUEST | typeof KIND_RESPONSE\n\nexport interface ParserCallbacks<K extends ParserKind> {\n onError?: (error: Error) => void\n onMessageBegin?: () => number | void\n onHeadersComplete?: (\n info: K extends typeof KIND_REQUEST\n ? RequestHeadersComplete\n : ResponseHeadersComplete\n ) => number | void\n onBody?: (body: Buffer) => number | void\n onMessageComplete?: () => number | void\n}\n\nexport type RequestParserCallbacks = ParserCallbacks<typeof KIND_REQUEST>\nexport type ResponseParserCallbacks = ParserCallbacks<typeof KIND_RESPONSE>\n\nconst kPointer = Symbol('kPtr')\nconst kUrl = Symbol('kUrl')\nconst kStatusMessage = Symbol('kStatusMessage')\nconst kHeadersFields = Symbol('kHeadersFields')\nconst kHeadersValues = Symbol('kHeadersValues')\nconst kLastHeaderCallback = Symbol('kLastHeaderCallback')\nconst kCallbacks = Symbol('kCallbacks')\nconst kType = Symbol('kType')\n\nconst HEADER_CB_NONE = 0\nconst HEADER_CB_FIELD = 1\nconst HEADER_CB_VALUE = 2\n\nconst parsersMap = new Map<number, HttpParser<any>>()\n\nconst methodNames = Object.fromEntries(\n Object.entries(constants.METHODS).map(([name, num]) => [num, name])\n) as Record<number, string>\n\nfunction readStringFrom(pointer: number, length: number): string {\n return Buffer.from(llhttp_memory.buffer, pointer, length).toString('latin1')\n}\n\n/**\n * @note Reference the base URL through a variable. Bundlers (e.g. Vite)\n * statically rewrite the `new URL('...', import.meta.url)` pattern into\n * an asset URL resolved against the served origin, which breaks reading\n * the WASM binary from the file system in DOM-like test environments.\n */\nconst wasmBaseUrl = import.meta.url\n\nconst llhttpModule = new WebAssembly.Module(\n fs.readFileSync(new URL('./llhttp/llhttp.wasm', wasmBaseUrl))\n)\n\nconst llhttpInstance = new WebAssembly.Instance(llhttpModule, {\n env: {\n wasm_on_message_begin(parserPointer: number) {\n const parser = parsersMap.get(parserPointer)!\n parser[kUrl] = ''\n parser[kStatusMessage] = ''\n parser[kHeadersFields] = []\n parser[kHeadersValues] = []\n parser[kLastHeaderCallback] = HEADER_CB_NONE\n return parser[kCallbacks].onMessageBegin?.() ?? 0\n },\n // Request only\n wasm_on_url(parserPointer: number, at: number, length: number) {\n parsersMap.get(parserPointer)![kUrl] = readStringFrom(at, length)\n return 0\n },\n // Response only\n wasm_on_status(parserPointer: number, at: number, length: number) {\n parsersMap.get(parserPointer)![kStatusMessage] = readStringFrom(\n at,\n length\n )\n return 0\n },\n wasm_on_header_field(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n const chunk = readStringFrom(at, length)\n const fields = parser[kHeadersFields]\n\n // llhttp emits header field/value across multiple callbacks when the\n // bytes span buffer boundaries. Concatenate consecutive same-type\n // callbacks into a single entry; switch entries on field<->value transitions.\n if (parser[kLastHeaderCallback] === HEADER_CB_FIELD) {\n fields[fields.length - 1] += chunk\n } else {\n fields.push(chunk)\n parser[kLastHeaderCallback] = HEADER_CB_FIELD\n }\n return 0\n },\n wasm_on_header_value(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n const chunk = readStringFrom(at, length)\n const values = parser[kHeadersValues]\n\n if (parser[kLastHeaderCallback] === HEADER_CB_VALUE) {\n values[values.length - 1] += chunk\n } else {\n values.push(chunk)\n parser[kLastHeaderCallback] = HEADER_CB_VALUE\n }\n return 0\n },\n wasm_on_headers_complete(\n parserPointer: number,\n statusCode: number,\n rawUpgrade: number,\n rawShouldKeepAlive: number\n ) {\n const parser = parsersMap.get(parserPointer)!\n const versionMajor = llhttp_get_version_major(parserPointer)\n const versionMinor = llhttp_get_version_minor(parserPointer)\n const rawHeaders: Array<string> = []\n const upgrade = rawUpgrade === 1\n const shouldKeepAlive = rawShouldKeepAlive === 1\n\n for (let c = 0; c < parser[kHeadersFields].length; c++) {\n rawHeaders.push(parser[kHeadersFields][c]!, parser[kHeadersValues][c]!)\n }\n\n if (parser[kType] === KIND_REQUEST) {\n const method = methodNames[llhttp_get_method(parserPointer)]\n const url = parser[kUrl]\n const callback = parser[kCallbacks] as ParserCallbacks<\n typeof KIND_REQUEST\n >\n\n return (\n callback.onHeadersComplete?.({\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n upgrade,\n shouldKeepAlive,\n }) ?? 0\n )\n } else {\n const statusCode = llhttp_get_status_code(parserPointer) as number\n const statusMessage = parser[kStatusMessage]\n const callback = parser[kCallbacks] as ParserCallbacks<\n typeof KIND_RESPONSE\n >\n\n return (\n callback.onHeadersComplete?.({\n versionMajor,\n versionMinor,\n rawHeaders,\n statusCode,\n statusMessage,\n upgrade,\n shouldKeepAlive,\n }) ?? 0\n )\n }\n },\n wasm_on_body(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n // Create a copy of the body chunk, as the underlying memory buffer is reused by llhttp and can be overwritten on the next callback call.\n // Maybe not the most efficient way, but it is simple and safe.\n const body = Buffer.from(new Uint8Array(llhttp_memory.buffer, at, length))\n return parser[kCallbacks].onBody?.(body) ?? 0\n },\n wasm_on_message_complete(parserPointer: number) {\n return (\n parsersMap.get(parserPointer)![kCallbacks].onMessageComplete?.() ?? 0\n )\n },\n },\n})\n\nconst llhttp_memory = llhttpInstance.exports.memory as WebAssembly.Memory\nconst llhttp_alloc = llhttpInstance.exports.llhttp_alloc as CallableFunction\nconst llhttp_malloc = llhttpInstance.exports.malloc as CallableFunction\nconst llhttp_execute = llhttpInstance.exports.llhttp_execute as CallableFunction\nconst llhttp_get_type = llhttpInstance.exports\n .llhttp_get_type as CallableFunction\nconst llhttp_get_upgrade = llhttpInstance.exports\n .llhttp_get_upgrade as CallableFunction\nconst llhttp_should_keep_alive = llhttpInstance.exports\n .llhttp_should_keep_alive as CallableFunction\nconst llhttp_get_method = llhttpInstance.exports\n .llhttp_get_method as CallableFunction\nconst llhttp_get_status_code = llhttpInstance.exports\n .llhttp_get_status_code as CallableFunction\nconst llhttp_get_version_minor = llhttpInstance.exports\n .llhttp_get_http_minor as CallableFunction\nconst llhttp_get_version_major = llhttpInstance.exports\n .llhttp_get_http_major as CallableFunction\nconst llhttp_get_error_reason = llhttpInstance.exports\n .llhttp_get_error_reason as CallableFunction\nconst llhttp_get_error_pos = llhttpInstance.exports\n .llhttp_get_error_pos as CallableFunction\nconst llhttp_free = llhttpInstance.exports.free as CallableFunction\n\nconst initialize = llhttpInstance.exports._initialize as CallableFunction\ninitialize() // wasi reactor\n\nexport class HttpParser<K extends ParserKind> {\n [kPointer]: number;\n [kUrl]: string = '';\n [kStatusMessage]: string = '';\n [kHeadersFields]: Array<string> = [];\n [kHeadersValues]: Array<string> = [];\n [kLastHeaderCallback]: number = HEADER_CB_NONE;\n [kCallbacks]: ParserCallbacks<K>;\n [kType]: ParserKind\n\n constructor(type: K, callbacks: ParserCallbacks<K>) {\n this[kType] = type\n this[kCallbacks] = callbacks\n\n const parserPointer = llhttp_alloc(type)\n\n if (parserPointer === 0) {\n throw new Error('Failed to allocate llhttp parser')\n }\n\n this[kPointer] = parserPointer\n parsersMap.set(this[kPointer], this)\n }\n\n destroy() {\n // Guard against multiple calls to free/destroy.\n if (this[kPointer] === 0) {\n return\n }\n\n parsersMap.delete(this[kPointer])\n llhttp_free(this[kPointer])\n this[kPointer] = 0\n }\n\n execute(data: Buffer) {\n const pointer = llhttp_malloc(data.byteLength)\n\n if (pointer === 0) {\n throw new Error('Failed to allocate llhttp input buffer')\n }\n\n let ret: number\n try {\n const buffer = new Uint8Array(llhttp_memory.buffer)\n buffer.set(data, pointer)\n ret = llhttp_execute(this[kPointer], pointer, data.byteLength)\n } catch (error) {\n // Free the input buffer if a user callback threw synchronously,\n // otherwise the wasm heap leaks the chunk on every execute() call.\n llhttp_free(pointer)\n throw error\n }\n\n if (ret === constants.ERROR.PAUSED_UPGRADE) {\n // Find how many bytes llhttp consumed\n const errorPos = llhttp_get_error_pos(this[kPointer])\n const consumed = errorPos - pointer\n llhttp_free(pointer)\n // Return the unconsumed trailing bytes (tunnel/protocol data)\n return data.subarray(consumed)\n }\n\n llhttp_free(pointer)\n this.#checkError(ret)\n\n return null // fully consumed\n }\n\n #checkError(errorCode: number) {\n if (errorCode === constants.ERROR.OK) {\n return\n }\n\n const errorPointer = llhttp_get_error_reason(this[kPointer])\n const buffer = new Uint8Array(llhttp_memory.buffer)\n const length = buffer.indexOf(0, errorPointer) - errorPointer\n\n const error = new Error(readStringFrom(errorPointer, length))\n\n if (this[kCallbacks].onError) {\n this[kCallbacks].onError(error)\n return\n }\n\n throw error\n }\n}\n","import { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { FetchRequest, FetchResponse } from '../../utils/fetch-utils'\nimport { HttpParser } from './http-parser/index'\n\ninterface HttpRequestParserOptions {\n onError: (error: Error) => void\n connectionOptions: {\n method?: string\n url: URL\n }\n onRequest: (request: Request, abortController: AbortController) => void\n onMessageComplete?: () => void\n}\n\nexport class HttpRequestParser extends HttpParser<1> {\n #requestBodyStream?: Readable\n #upgrade = false\n\n constructor(options: HttpRequestParserOptions) {\n super(1, {\n onError: options.onError,\n onHeadersComplete: ({ rawHeaders, method, url: path, upgrade }) => {\n this.#upgrade = upgrade\n /**\n * @note When the socket is reused, \"connectionOptions\" will point\n * to the \"net.connect()\" call options that established the connection,\n * which may differ from the description of the current request (e.g. method).\n * Rely on the HTTPParser supplying us with the correct \"rawMethod\" number.\n */\n const finalMethod = (\n method ||\n options.connectionOptions.method ||\n 'GET'\n ).toUpperCase()\n\n const url = new URL(path || '', options.connectionOptions.url)\n const headers = FetchResponse.parseRawHeaders([...rawHeaders])\n\n // Translate the basic authorization to request headers.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n const credentials = Buffer.from(\n `${url.username}:${url.password}`\n ).toString('base64')\n headers.set('authorization', `Basic ${credentials}`)\n }\n url.username = ''\n url.password = ''\n }\n\n this.#requestBodyStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n */\n read: () => {},\n })\n\n /**\n * @note Expose an abort controller for the parsed request so the\n * consumer can abort it (e.g. when the client destroys the\n * connection before the request is handled).\n */\n const abortController = new AbortController()\n\n const request = new FetchRequest(url, {\n method: finalMethod,\n headers,\n credentials: 'same-origin',\n body: Readable.toWeb(this.#requestBodyStream) as any,\n signal: abortController.signal,\n })\n options.onRequest(request, abortController)\n },\n onBody: (chunk) => {\n invariant(\n this.#requestBodyStream,\n 'Failed to write to a request stream: stream does not exist. This is likely an issue with the library. Please report it on GitHub.'\n )\n\n this.#requestBodyStream.push(chunk)\n },\n onMessageComplete: () => {\n this.#requestBodyStream?.push(null)\n this.#requestBodyStream = undefined\n\n /**\n * @note An upgraded exchange (e.g. \"CONNECT\", WebSocket) has\n * no message boundary: it takes the connection over, and the\n * bytes that follow belong to it, not to a next exchange.\n */\n if (!this.#upgrade) {\n options.onMessageComplete?.()\n }\n },\n })\n }\n\n public free(error?: Error): void {\n this.destroy()\n this.#requestBodyStream?.destroy(error)\n this.#requestBodyStream = undefined\n }\n}\n\nexport class HttpResponseParser extends HttpParser<2> {\n #responseBodyStream?: Readable | null\n #status = 0\n\n constructor(options: {\n onResponse: (response: Response) => void\n onError: (error: Error) => void\n onMessageComplete?: (status: number) => void\n }) {\n super(2, {\n onError: options.onError,\n onHeadersComplete: ({\n rawHeaders,\n statusCode: status,\n statusMessage: statusText,\n }) => {\n this.#status = status\n const headers = FetchResponse.parseRawHeaders([...rawHeaders])\n\n const response = new FetchResponse(\n FetchResponse.isResponseWithBody(status)\n ? (Readable.toWeb(\n (this.#responseBodyStream = new Readable({ read() {} }))\n ) as any)\n : null,\n {\n status,\n statusText,\n headers,\n }\n )\n\n options.onResponse(response)\n },\n onBody: (chunk) => {\n invariant(\n this.#responseBodyStream,\n 'Failed to read from a response stream: stream does not exist. This is likely an issue with the library. Please report it on GitHub.'\n )\n\n this.#responseBodyStream.push(chunk)\n },\n onMessageComplete: () => {\n this.#responseBodyStream?.push(null)\n this.#responseBodyStream = null\n options.onMessageComplete?.(this.#status)\n },\n })\n }\n\n public free(error?: Error): void {\n this.destroy()\n\n if (error) {\n this.#responseBodyStream?.destroy(error)\n }\n\n this.#responseBodyStream = null\n }\n}\n","export function isNodeLikeError(\n error: unknown\n): error is NodeJS.ErrnoException {\n if (error == null) {\n return false\n }\n\n if (!(error instanceof Error)) {\n return false\n }\n\n return 'code' in error && 'errno' in error\n}\n","import type { Emitter } from 'rettime'\nimport { until } from '@open-draft/until'\nimport {\n HttpRequestEvent,\n HttpRequestEventData,\n UnhandledHttpException,\n type HttpRequestEventMap,\n} from '../events/http'\nimport { RequestController } from '../request-controller'\nimport {\n createServerErrorResponse,\n isResponseError,\n isResponseLike,\n} from './response-utils'\nimport { InterceptorError } from '../interceptor-error'\nimport { isNodeLikeError } from './is-node-like-error'\nimport { isObject } from './is-object'\nimport { formatRequest, type Logger } from './logger'\n\nexport interface HandleRequestOptions {\n initiator: unknown\n requestId: string\n request: Request\n emitter: Emitter<HttpRequestEventMap>\n controller: RequestController\n logger?: Logger\n}\n\nexport async function handleRequest(\n options: HandleRequestOptions\n): Promise<void> {\n if (options.logger?.isEnabled('default')) {\n void formatRequest(options.request).then((message) => {\n options.logger?.info('[%s] %s', options.requestId, message)\n })\n }\n\n const handleResponse = async (\n response: Response | Error | Record<string, any>\n ) => {\n if (response instanceof Error) {\n await options.controller.errorWith(response)\n return true\n }\n\n // Handle \"Response.error()\" instances.\n if (isResponseError(response)) {\n await options.controller.respondWith(response)\n return true\n }\n\n /**\n * Handle normal responses or response-like objects.\n * @note This must come before the arbitrary object check\n * since Response instances are, in fact, objects.\n */\n if (isResponseLike(response)) {\n await options.controller.respondWith(response)\n return true\n }\n\n // Handle arbitrary objects provided to `.errorWith(reason)`.\n if (isObject(response)) {\n await options.controller.errorWith(response)\n return true\n }\n\n return false\n }\n\n const handleResponseError = async (error: unknown): Promise<boolean> => {\n // Forward the special interceptor error instances\n // to the developer. These must not be handled in any way.\n if (error instanceof InterceptorError) {\n throw resultError\n }\n\n // Support mocking Node.js-like errors.\n if (isNodeLikeError(error)) {\n await options.controller.errorWith(error)\n return true\n }\n\n // Handle thrown responses.\n if (error instanceof Response) {\n return await handleResponse(error)\n }\n\n return false\n }\n\n const requestAbortPromise = Promise.withResolvers<void>()\n let requestAbortReason: unknown\n let isRequestAborted = false\n const onAbort = () => {\n isRequestAborted = true\n requestAbortReason = options.request.signal?.reason\n requestAbortPromise.reject(requestAbortReason)\n }\n\n /**\n * @note `signal` is not always defined in React Native.\n */\n if (options.request.signal) {\n if (options.request.signal.aborted) {\n await options.controller.errorWith(options.request.signal.reason)\n return\n }\n\n options.request.signal.addEventListener('abort', onAbort, { once: true })\n }\n\n const [resultError] = await until(async () => {\n // Emit the \"request\" event and wait until all the listeners\n // for that event are finished (e.g. async listeners awaited).\n // By the end of this promise, the developer cannot affect the\n // request anymore.\n const requestEventData: HttpRequestEventData = {\n initiator: options.initiator,\n requestId: options.requestId,\n request: options.request,\n controller: options.controller,\n }\n const requestEvent = new HttpRequestEvent(requestEventData)\n const requestListenersPromise = options.emitter.emitAsPromise(requestEvent)\n\n await Promise.race([\n // Short-circuit the request handling promise if the request gets aborted.\n requestAbortPromise.promise,\n requestListenersPromise,\n options.controller.handled,\n ])\n\n /**\n * @note If the \"request\" listener has replaced the request instance,\n * propagate that mutation back to the underlying insterceptor.\n * This happens with XMLHttpRequest that replaces request instances\n * to correctly reflect the \"withCredentials\" option on the Fetch API request.\n */\n if (requestEvent.request !== options.request) {\n options.request = requestEvent.request\n }\n })\n\n options.request.signal?.removeEventListener('abort', onAbort)\n\n // Handle the request being aborted while waiting for the request listeners.\n if (isRequestAborted) {\n await options.controller.errorWith(requestAbortReason)\n return\n }\n\n if (resultError) {\n // Handle the error during the request listener execution.\n // These can be thrown responses or request errors.\n if (await handleResponseError(resultError)) {\n return\n }\n\n // If the developer has added \"unhandledException\" listeners,\n // allow them to handle the error. They can translate it to a\n // mocked response, network error, or forward it as-is.\n if (options.emitter.listenerCount('unhandledException') > 0) {\n // Create a new request controller just for the unhandled exception case.\n // This is needed because the original controller might have been already\n // interacted with (e.g. \"respondWith\" or \"errorWith\" called on it).\n const unhandledExceptionController = new RequestController(\n options.request,\n {\n /**\n * @note Intentionally empty passthrough handle.\n * This controller is created within another controller and we only need\n * to know if `unhandledException` listeners handled the request.\n */\n passthrough() {},\n async respondWith(response) {\n await handleResponse(response)\n },\n async errorWith(reason) {\n /**\n * @note Handle the result of the unhandled controller\n * in the same way as the original request controller.\n * The exception here is that thrown errors within the\n * \"unhandledException\" event do NOT result in another\n * emit of the same event. They are forwarded as-is.\n */\n await options.controller.errorWith(reason)\n },\n }\n )\n\n await options.emitter.emitAsPromise(\n new UnhandledHttpException({\n initiator: options.initiator,\n error: resultError,\n request: options.request,\n requestId: options.requestId,\n controller: unhandledExceptionController,\n })\n )\n\n // If all the \"unhandledException\" listeners have finished\n // but have not handled the request in any way, passthrough.\n if (\n unhandledExceptionController.readyState !== RequestController.PENDING\n ) {\n return\n }\n }\n\n // Otherwise, coerce unhandled exceptions to a 500 Internal Server Error response.\n await options.controller.respondWith(\n createServerErrorResponse(resultError)\n )\n return\n }\n\n // If the request hasn't been handled by this point, passthrough.\n if (options.controller.readyState === RequestController.PENDING) {\n return await options.controller.passthrough()\n }\n\n return options.controller.handled\n}\n","import { FetchResponse } from './fetch-utils'\nimport { copyRawHeaders } from '../interceptors/ClientRequest/utils/record-raw-headers'\n\n/** Clone for observers without letting their unread body block caller cancellation. */\nexport function cloneResponse(response: Response): [Response, Response] {\n const clone = FetchResponse.clone(response)\n\n if (!response.body || !clone.body) {\n return [response, clone]\n }\n\n const observer = wrapResponse(clone)\n const caller = wrapResponse(response, observer.cancel)\n\n return [caller.response, observer.response]\n}\n\nfunction wrapResponse(\n response: Response,\n onCancel?: (reason: unknown) => Promise<void>\n) {\n const body = response.body!\n const reader = body.getReader()\n const cancel = (reason: unknown) => {\n return body.locked ? reader.cancel(reason) : body.cancel(reason)\n }\n const stream = new ReadableStream<Uint8Array>(\n {\n async pull(controller) {\n try {\n const { done, value } = await reader.read()\n\n if (done) {\n controller.close()\n reader.releaseLock()\n return\n }\n\n controller.enqueue(value)\n } catch (error) {\n controller.error(error)\n reader.releaseLock()\n }\n },\n async cancel(reason) {\n try {\n const cancellation = cancel(reason)\n\n if (onCancel) {\n // Caller cancellation owns both branches.\n await Promise.all([cancellation, onCancel(reason)])\n } else {\n // An observer must not wait for the caller to consume its branch:\n // Response delivery is still waiting for this listener to finish.\n void cancellation.catch(() => {})\n }\n } finally {\n reader.releaseLock()\n }\n },\n },\n { highWaterMark: 0 }\n )\n const wrappedResponse = new FetchResponse(stream, response)\n copyRawHeaders(response.headers, wrappedResponse.headers)\n Object.defineProperties(wrappedResponse, {\n type: { value: response.type },\n redirected: { value: response.redirected },\n })\n\n return { response: wrappedResponse, cancel }\n}\n","import net from 'node:net'\nimport {\n METHODS,\n STATUS_CODES,\n ServerResponse,\n IncomingMessage,\n} from 'node:http'\nimport { invariant } from 'outvariant'\nimport { HttpResponseEvent, type HttpRequestEventMap } from '../../events/http'\nimport { RequestController } from '../../request-controller'\nimport {\n getRawFetchHeaders,\n recordRawFetchHeaders,\n} from '../ClientRequest/utils/record-raw-headers'\nimport { SocketInterceptor } from '../net'\nimport { connectionOptionsToUrl } from '../net/utils/connection-options-to-url'\nimport { toBuffer } from '../../utils/buffer-utils'\nimport { createRequestId } from '../../create-request-id'\nimport { HttpRequestParser, HttpResponseParser } from './http-parser'\nimport { handleRequest, HandleRequestOptions } from '../../utils/handle-request'\nimport { isResponseError, kErrorResponse } from '../../utils/response-utils'\nimport { createLogger } from '../../utils/logger'\nimport {\n kRawSocket,\n SocketController,\n type FlushPendingDataFunction,\n} from '../net/socket-controller'\nimport { unwrapPendingData } from '../net/utils/flush-writes'\nimport { FetchResponse } from '../../utils/fetch-utils'\nimport { cloneResponse } from '../../utils/clone-response'\nimport { requestContext } from '../../request-context'\nimport { Interceptor } from '#/src/interceptor'\n\nconst httpLogger = createLogger('http-request')\n\n/**\n * Interceptor for HTTP requests in Node.js.\n * Routes socket connections through an HTTP parser.\n */\nexport class NodeHttpRequestSource extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol.for('node-http-request-source')\n\n protected predicate(): boolean {\n return true\n }\n\n protected setup(): void {\n const socketInterceptor = Interceptor.singleton(SocketInterceptor)\n socketInterceptor.apply(this)\n this.subscriptions.push(() => {\n socketInterceptor.dispose(this)\n })\n\n /**\n * @note Record the raw values provided to Headers set/append\n * in order to support \"IncomingMessage.prototype.rawHeaders\".\n * This is meant for the headers in mocked responses.\n */\n this.subscriptions.push(recordRawFetchHeaders())\n\n const controller = new AbortController()\n this.subscriptions.push(() => controller.abort())\n\n socketInterceptor.on(\n 'connection',\n ({ connectionOptions, socket, controller: socketController }) => {\n let isHttpConnection: boolean | undefined\n let requestParser: HttpRequestParser | undefined\n let tunnelUrl: URL | undefined\n let abortPendingRequest: (() => void) | undefined\n let pendingRequestController: RequestController | undefined\n\n // Protocol detection runs inside a client write. Let the write finish,\n // other data observers run, and the remaining \"connection\" listeners\n // get their chance to claim before flushing it to the real socket.\n const passthroughNonHttp = () => {\n setImmediate(() => {\n if (\n socketController.readyState === SocketController.PENDING &&\n !socket.destroyed\n ) {\n socketController.passthrough()\n }\n })\n }\n\n // A malformed request loses the boundary for subsequent requests.\n // Preserve the original bytes for the client and server to handle.\n const stopParsingRequests = (error: Error) => {\n httpLogger.verbose('stopping HTTP request parsing: %o', error)\n isHttpConnection = false\n\n if (\n pendingRequestController?.readyState === RequestController.PENDING\n ) {\n void pendingRequestController.passthrough()\n } else {\n passthroughNonHttp()\n }\n\n requestParser?.free(error)\n }\n\n /**\n * @note Capture the request context of the connection itself.\n * The socket is created synchronously within the request async\n * context (e.g. inside the patched `http.request()`), but the\n * first data may reach the socket from a foreign context (e.g.\n * a form-data stream piped into the request), where sampling\n * the request context yields nothing.\n */\n const connectionRequestContext = requestContext.getStore()\n\n /**\n * @note The client destroys the socket synchronously (e.g. Undici\n * on request abort) but the socket teardown events (\"error\",\n * \"close\") are emitted asynchronously, after the consumer has\n * already observed the rejected request promise. Hook into the\n * destroy itself so the pending request is aborted before any\n * of its listeners can resume.\n */\n const rawSocket = socketController[kRawSocket]\n const realSocketDestroy = rawSocket._destroy.bind(rawSocket)\n rawSocket._destroy = (error, callback) => {\n abortPendingRequest?.()\n realSocketDestroy(error, callback)\n }\n\n const executeRequestParser = (\n parser: HttpRequestParser,\n chunk: Buffer\n ) => {\n // llhttp pauses permanently at an upgrade boundary. Release the\n // parser after execute returns, outside its native callbacks.\n if (parser.execute(chunk) !== null) {\n socket.removeListener('data', onRequestData)\n parser.free()\n requestParser = undefined\n }\n }\n\n /**\n * @note Inspect the first sent packet to determine the protocol,\n * including when entering a mocked \"CONNECT\" tunnel.\n */\n const onRequestData = (chunk: Buffer) => {\n if (isHttpConnection === false) {\n passthroughNonHttp()\n return\n }\n\n /**\n * @note A mocked \"CONNECT\" request has established a tunnel.\n * The data that follows belongs to a new exchange addressed to\n * the tunnel target. The previous parser was freed at the upgrade\n * boundary, so detect the tunneled protocol anew.\n */\n if (tunnelUrl && !requestParser) {\n isHttpConnection = undefined\n\n /**\n * @note Retarget the connection to the tunnel authority.\n * The exchanges that follow belong to the tunnel target,\n * so an unclaimed exchange (HTTP or not) must pass through\n * to that target — not to the proxy, which never actually\n * established this tunnel — like a real established tunnel\n * relays its traffic.\n */\n socketController.reset({\n host: tunnelUrl.hostname,\n port: Number(tunnelUrl.port) || 80,\n path: null,\n })\n }\n\n if (requestParser) {\n executeRequestParser(requestParser, toBuffer(chunk))\n return\n }\n\n const httpMessage = chunk.toString()\n const httpMethod = httpMessage.split(' ')[0] || ''\n\n // Stop parsing connections that do not carry HTTP traffic.\n if (!METHODS.includes(httpMethod.toUpperCase())) {\n isHttpConnection = false\n passthroughNonHttp()\n return\n }\n\n isHttpConnection = true\n\n const baseUrl =\n tunnelUrl ?? connectionOptionsToUrl(connectionOptions, socket)\n\n httpLogger.verbose('handling http message %o', {\n httpMessage,\n httpMethod,\n baseUrl,\n })\n\n // Get the request initiator from the async context, falling\n // back to the context captured at the connection time, then\n // to the underlying socket.\n const requestContextValue =\n requestContext.getStore() ?? connectionRequestContext\n const initiator = requestContextValue?.initiator || socket\n\n requestParser = new HttpRequestParser({\n onError: stopParsingRequests,\n connectionOptions: {\n method: httpMethod,\n url: baseUrl,\n },\n /**\n * @note The message boundary ends the current exchange.\n * Schedule the controller reset so the next write on this\n * (kept-alive) socket opens a new exchange and buffers for\n * its own verdict instead of following the settled one\n * (e.g. leaking a mocked request to the server of a\n * previously passed-through exchange).\n */\n onMessageComplete: () => {\n socketController.scheduleReset()\n },\n onRequest: async (parsedRequest, requestAbortController) => {\n const request =\n requestContextValue?.transformRequest?.(parsedRequest) ??\n parsedRequest\n\n /**\n * @note A subsequent request arriving on a kept-alive socket\n * that has already been handled (passed through or mocked).\n * Clients like Undici reuse sockets without emitting the\n * \"free\" event, so reset the controller here, at the HTTP\n * message boundary, to handle the new request from the\n * pending state again.\n */\n if (socketController['readyState'] !== SocketController.PENDING) {\n socketController.reset()\n }\n\n const requestId = createRequestId()\n const requestLogger = requestContextValue?.logger ?? httpLogger\n\n httpLogger.verbose('received a parsed HTTP request %o', {\n method: request.method,\n url: request.url,\n })\n\n const requestController = new RequestController(\n request,\n {\n respondWith: async (rawResponse) => {\n httpLogger.verbose('respondWith() %o', {\n status: rawResponse.status,\n statusText: rawResponse.statusText,\n hasBody: rawResponse.body != null,\n })\n\n /**\n * @note The client may destroy the socket (e.g. on request\n * abort) moments before a response arrives. A destroyed\n * socket cannot be claimed and has no one reading it.\n */\n if (socket.destroyed) {\n return\n }\n\n socketController.claim()\n\n const originalResponse = FetchResponse.from(rawResponse, {\n url: request.url,\n })\n const [response, responseClone] =\n !isResponseError(originalResponse) &&\n this.emitter.listenerCount('response') > 0\n ? cloneResponse(originalResponse)\n : [originalResponse, null]\n\n /**\n * @note A successful mocked response to a \"CONNECT\"\n * request establishes a tunnel to the requested authority\n * (e.g. \"127.0.0.1:80\"). The exchange that follows on this\n * socket is addressed to that authority, not to the proxy.\n */\n if (request.method === 'CONNECT' && response.ok) {\n tunnelUrl = new URL(`http://${request.url}`)\n socket.on('data', onRequestData)\n }\n\n const respond = () => {\n return this.respondWith({\n socket: socketController[kRawSocket],\n request: context.request,\n response,\n })\n }\n\n if (responseClone) {\n await this.emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator,\n requestId,\n request: context.request,\n response: responseClone,\n responseType: 'mock',\n })\n )\n }\n\n if (socket.connecting) {\n // Send a mocked response once the socket connects, just like the real server would.\n // This preserves the correct order of events (e.g. connect, then data).\n socket.once('connect', respond)\n } else {\n /**\n * @note Reused sockets stay connected between requests and will not\n * emit \"connect\" anymore. If that's the case, respond immediately.\n */\n await respond()\n }\n },\n errorWith: (reason) => {\n if (reason instanceof Error) {\n socket.destroy(reason)\n }\n },\n passthrough: () => {\n const realSocket = socketController.passthrough(\n isHttpConnection === false\n ? undefined\n : this.#modifyHttpHeaders(context.request)\n )\n\n if (isHttpConnection === false) {\n return\n }\n\n if (this.emitter.listenerCount('response') > 0) {\n httpLogger.verbose(\n 'found \"response\" listener, corking socket reads'\n )\n\n /**\n * Suspend the delivery of the original response to the client\n * until the \"response\" event listeners settle. This guarantees\n * that the request promise (e.g. `await fetch()`) does not\n * resolve before the listeners are done. The real socket keeps\n * emitting data for the response parser meanwhile.\n */\n socketController.corkReads()\n\n let responseParserDisposed = false\n let responseComplete = false\n let hasFinalResponse = false\n const responseParser = new HttpResponseParser({\n onError: (error) => {\n disposeResponseParser(error)\n socketController.uncorkReads()\n },\n onMessageComplete: (status) => {\n responseComplete = status >= 200 || status === 101\n },\n onResponse: async (response) => {\n hasFinalResponse =\n response.status >= 200 || response.status === 101\n httpLogger.verbose(\n 'HTTP response parser parsed: %d %s',\n response.status,\n response.statusText\n )\n\n if (isResponseError(response)) {\n httpLogger.verbose(\n 'response is an error response, uncorking socket reads...'\n )\n\n socketController.uncorkReads()\n return\n }\n\n FetchResponse.setUrl(request.url, response)\n\n try {\n httpLogger.verbose('emitting \"response\" event')\n await this.emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator,\n requestId,\n request: context.request,\n response,\n responseType: 'original',\n })\n )\n } finally {\n httpLogger.verbose('uncorking socket reads')\n socketController.uncorkReads()\n\n /**\n * @note Informational responses other than\n * \"101 Switching Protocols\" are followed by a final\n * response on the same connection. Keep gating that\n * final response on the \"response\" event listeners.\n */\n if (\n !responseParserDisposed &&\n response.status < 200 &&\n response.status !== 101\n ) {\n socketController.corkReads()\n }\n }\n },\n })\n\n const onResponseData = (chunk: Buffer) => {\n responseParser.execute(chunk)\n\n // Free only after llhttp returns from its callbacks.\n if (responseComplete) {\n disposeResponseParser()\n }\n }\n\n const onResponseEnd = () => {\n disposeResponseParser()\n\n // Without a final response, release EOF now. A half-open\n // socket cannot close until the client consumes it.\n if (!hasFinalResponse) {\n socketController.uncorkReads()\n }\n }\n\n const disposeResponseParser = (error?: Error) => {\n responseParserDisposed = true\n realSocket.removeListener('data', onResponseData)\n realSocket.removeListener('end', onResponseEnd)\n realSocket.removeListener('close', onResponseEnd)\n responseParser.free(error)\n }\n\n realSocket\n .on('data', onResponseData)\n .once('end', onResponseEnd)\n .once('close', onResponseEnd)\n }\n },\n },\n {\n logger: requestLogger,\n requestId,\n }\n )\n\n invariant(\n socketController['readyState'] === SocketController.PENDING,\n 'CANNOT HANDLE ALREADY HANDLED REQUEST',\n request.method,\n request.url,\n socketController['readyState']\n )\n\n /**\n * @note Create a request resolution context.\n * This is so modifications to the \"request\" in upstream interceptors\n * are correctly picked up by the underlying HTTP interceptor.\n */\n const context: HandleRequestOptions = {\n initiator,\n requestId,\n request,\n controller: requestController,\n emitter: this.emitter,\n logger: requestLogger,\n }\n\n /**\n * @note The client destroying the socket while the request\n * is still pending means the request was aborted (e.g. via\n * `AbortController`). Abort the parsed request so its\n * handling settles and late interactions with the request\n * controller become controlled errors.\n */\n abortPendingRequest = () => {\n if (\n requestController.readyState === RequestController.PENDING\n ) {\n requestAbortController.abort()\n }\n }\n\n pendingRequestController = requestController\n\n try {\n await handleRequest(context)\n } finally {\n pendingRequestController = undefined\n abortPendingRequest = undefined\n }\n },\n })\n\n // Forward the first frame to the parser.\n executeRequestParser(requestParser, toBuffer(chunk))\n }\n\n socket.on('data', onRequestData)\n socket.on('close', () => requestParser?.free())\n },\n {\n signal: controller.signal,\n }\n )\n }\n\n private async respondWith(args: {\n socket: net.Socket\n request: Request\n response: Response\n }): Promise<void> {\n const { socket, request, response } = args\n\n if (socket.destroyed) {\n return\n }\n\n if (isResponseError(response)) {\n /**\n * @note Reference the error response on the socket error so the\n * client-side interceptors (e.g. fetch) can surface it to the\n * consumer as the reason behind the failed request. Keep the\n * reference non-enumerable so the error remains observably\n * identical for the clients that expose it as-is.\n */\n socket.destroy(\n Object.defineProperty(new TypeError('Network error'), kErrorResponse, {\n value: response,\n enumerable: false,\n })\n )\n return\n }\n\n invariant(\n !socket.connecting,\n 'Failed to mock a response for \"%s %s\": socket has not connected',\n request.method,\n request.url\n )\n\n /**\n * Use native server response handling in Node.js.\n * @see https://github.com/nodejs/node/blob/13eb80f3b718452213e0fc449702aefbbfe4110f/lib/_http_server.js#L202\n */\n const incomingMessage = new IncomingMessage(socket)\n\n /**\n * @note Describe the request method so the response body is\n * handled appropriately (e.g. \"HEAD\" responses must not write\n * a body). The HTTP version is deliberately left unset: with it,\n * `ServerResponse` frames bodies of unknown length as chunked,\n * polluting the mocked response headers with \"Transfer-Encoding\"\n * the mock never specified.\n */\n incomingMessage.method = request.method\n\n const serverResponse = new ServerResponse(incomingMessage)\n\n const responseSocket = new net.Socket()\n\n responseSocket._writeGeneric = (writev, data, encoding, callback) => {\n unwrapPendingData(data, (chunk, encoding) => {\n socket.push(toBuffer(chunk), encoding)\n })\n callback?.()\n }\n\n responseSocket._destroy = (\n error: Error | null,\n callback: (error: Error | null) => void\n ) => {\n /**\n * Only destroy the socket on stream errors.\n * On a clean end, the socket is already signaled via `socket.push(null)`\n * in the main response flow. Destroying it here prematurely would prevent\n * the client from processing the response (e.g. calling `response.destroy()`).\n * @see https://github.com/mswjs/interceptors/issues/738\n */\n if (error) {\n socket.destroy()\n }\n\n callback(null)\n }\n\n responseSocket.on('drain', () => serverResponse.emit('drain'))\n serverResponse.assignSocket(responseSocket)\n\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n const rawResponseHeaders = getRawFetchHeaders(response.headers)\n serverResponse.writeHead(\n response.status,\n response.statusText || STATUS_CODES[response.status],\n rawResponseHeaders\n )\n\n /**\n * @note Override the socket's `_destroy` before writing the response body.\n * The underlying TCP handle (from `socket.connect()`) makes `_destroy` async\n * (`_handle.close()` callback), which delays the 'error' event. Since the real\n * TCP connection is irrelevant for mocked responses, take the synchronous path\n * so that user-initiated `response.destroy(error)` emits the error promptly.\n * This must happen before `serverResponse.end()` because the HTTP parser may\n * fire the 'response' event synchronously during `socket.push()`.\n */\n socket._destroy = function (\n error: Error | null,\n callback: (error: Error | null) => void\n ) {\n if (error) {\n /**\n * Emit the error event as a microtask instead of relying on the default\n * `process.nextTick(emitErrorNT)` from `callback(error)`. This is necessary\n * because `respondWith` runs inside a microtask (from `await reader.read()`).\n * A resolved promise continuation (from toWebResponse) is queued as\n * another microtask during the same phase. Since microtasks are drained before\n * nextTick, the test's `await` would resolve before the error event fires.\n * Using `queueMicrotask` ensures the error event is emitted within the current\n * microtask phase, before other queued microtasks.\n */\n queueMicrotask(() => this.emit('error', error))\n }\n\n callback(null)\n\n /**\n * @note `net.Socket` is constructed with `emitClose: false`, so Node's\n * stream destroy machinery does not emit `'close'` automatically; the\n * stock `net.Socket._destroy` only emits it via `_handle.close()`.\n * Since this override replaces `_destroy`, emit `'close'` here so the\n * mocked socket completes its lifecycle (otherwise consumers waiting\n * on `'close'`, like `http.ClientRequest`, hang).\n */\n process.nextTick(() => this.emit('close', error != null))\n }\n\n if (response.body) {\n const reader = response.body.getReader()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n if (!serverResponse.write(value)) {\n await new Promise<void>((resolve) => {\n serverResponse.once('drain', resolve)\n })\n }\n }\n } catch {\n /**\n * @note Delay the socket destruction to allow the event loop\n * to flush already-pushed response data (headers + body chunks)\n * through the HTTP parser. Without this, the socket is destroyed\n * on the same tick as `socket.push(data)` and the client never\n * reads the response.\n */\n await new Promise<void>((resolve) => process.nextTick(resolve))\n socket.destroy()\n return\n }\n } else {\n serverResponse.end()\n }\n\n /**\n * @note Self-delimiting responses (chunked, explicit \"Content-Length\",\n * or bodiless by definition) must NOT signal the end-of-stream.\n * The client parser completes them from their framing alone, and\n * ending the socket would kill the kept-alive connection that\n * agents pool and reuse for subsequent requests.\n */\n const isSelfDelimitingResponse =\n request.method === 'HEAD' ||\n response.headers.has('content-length') ||\n response.headers.has('transfer-encoding') ||\n !FetchResponse.isResponseWithBody(response.status)\n\n if (\n /**\n * @note A non-2xx response to a \"CONNECT\" request means the proxy\n * refused the tunnel. Real proxies terminate the connection after\n * sending such a response, regardless of its framing.\n */\n (request.method === 'CONNECT' && !response.ok) ||\n (request.method !== 'CONNECT' && !isSelfDelimitingResponse)\n ) {\n /**\n * @note Defer the end-of-stream signal so the HTTP parser has a chance\n * to process already-pushed response data and fire the 'response' event\n * before the socket is ended. Without this, the parser marks the response\n * as \"complete\" before the client can interact with it (e.g. `response.destroy()`).\n */\n await new Promise<void>((resolve) => process.nextTick(resolve))\n socket.push(null)\n }\n }\n\n #modifyHttpHeaders(request: Request): FlushPendingDataFunction {\n const transformRequestMessage = (\n httpMessage: string | Buffer,\n encoding?: BufferEncoding | 'buffer'\n ): string | Buffer => {\n /**\n * @note Socket can write a buffer (e.g. uploaded file) even before\n * it writes the HTTP message. Bypass those cases.\n */\n if (encoding === 'buffer') {\n return httpMessage\n }\n\n const parts = httpMessage.toString(encoding).split('\\r\\n')\n const headersEndIndex = parts.findIndex((field) => field === '')\n const httpMessageHeaderPairs = parts.slice(1, headersEndIndex)\n\n // Extract raw [name, value] tuples from the wire format so they\n // can be compared against the request's raw fetch headers.\n const httpMessageRawHeaders = httpMessageHeaderPairs.map(\n (line): [string, string] => {\n const separatorIndex = line.indexOf(': ')\n return [line.slice(0, separatorIndex), line.slice(separatorIndex + 2)]\n }\n )\n\n const requestRawHeaders = getRawFetchHeaders(request.headers)\n\n // If the raw headers from the outgoing HTTP message and the request\n // headers are identical, send the message as-is to avoid the cost\n // (and side effects) of reserializing the headers block.\n const headersUnchanged =\n httpMessageRawHeaders.length === requestRawHeaders.length &&\n httpMessageRawHeaders.every((tuple, index) => {\n const requestTuple = requestRawHeaders[index]\n return tuple[0] === requestTuple[0] && tuple[1] === requestTuple[1]\n })\n\n if (headersUnchanged) {\n return httpMessage\n }\n\n const httpMessageHeaders = FetchResponse.parseRawHeaders(\n httpMessageHeaderPairs.flatMap((header) => header.split(': '))\n )\n\n const visitedHeaders = new Set<string>()\n\n for (const [headerName] of requestRawHeaders) {\n const normalizedHeaderName = headerName.toLowerCase()\n\n if (visitedHeaders.has(normalizedHeaderName)) {\n continue\n }\n\n visitedHeaders.add(normalizedHeaderName)\n\n /**\n * @note Forbidden Fetch headers (e.g. Host, Origin, Connection)\n * are stripped from `request.headers` but remain in the raw\n * headers list. Skip them so the original values from the\n * outgoing HTTP message are preserved.\n */\n const headerValue = request.headers.get(headerName)\n if (headerValue === null) {\n continue\n }\n\n // Use the merged value from Headers to correctly handle\n // appended headers (e.g. \"1, 2\" instead of just \"2\").\n httpMessageHeaders.set(headerName, headerValue)\n }\n\n visitedHeaders.clear()\n\n const httpMessageHeadersString = Array.from(httpMessageHeaders)\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n parts.splice(1, headersEndIndex - 1, httpMessageHeadersString)\n\n return parts.join('\\r\\n')\n }\n\n return (pendingData, encoding, callback) => {\n if (Array.isArray(pendingData)) {\n pendingData[0].chunk = transformRequestMessage(\n pendingData[0].chunk,\n pendingData[0].encoding\n )\n } else {\n pendingData = transformRequestMessage(pendingData, encoding)\n }\n\n callback(pendingData)\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"source-Bs0HXaSq.js","names":["constants","#checkError","#upgrade","#requestBodyStream","#status","#responseBodyStream","#modifyHttpHeaders"],"sources":["../../src/request-context.ts","../../src/interceptors/http/forward-events.ts","../../src/events/http.ts","../../src/interceptors/net/utils/connection-options-to-url.ts","../../src/interceptors/http/http-parser/llhttp/constants.cjs","../../src/interceptors/http/http-parser/index.ts","../../src/interceptors/http/http-parser.ts","../../src/utils/is-node-like-error.ts","../../src/utils/handle-request.ts","../../src/utils/clone-response.ts","../../src/interceptors/http/source.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Logger } from './utils/logger'\n\ninterface RequestContext {\n initiator: unknown\n logger?: Logger\n transformRequest?: (request: Request) => Request\n}\n\nexport const requestContext = new AsyncLocalStorage<RequestContext>()\n\nexport function runInRequestContext<T>(callback: () => T, logger?: Logger): T {\n /**\n * @note Never shadow an existing request context. Nested calls\n * (e.g. a patched entry point re-entered synchronously, or a request\n * made within the fetch/XMLHttpRequest interceptor context) must run\n * within the parent context so the sockets they create capture it.\n */\n if (requestContext.getStore()) {\n return callback()\n }\n\n /**\n * @note The initiator is the callback's return value (e.g. the\n * \"ClientRequest\" instance), so it cannot be known before running\n * the callback. The context is mutated in place once the callback\n * returns; readers hold the context object by reference and sample\n * \"initiator\" only after the request has been written.\n */\n const context: RequestContext = {\n initiator: undefined,\n logger,\n }\n\n return requestContext.run(context, () => {\n const initiator = callback()\n context.initiator = initiator\n return initiator\n })\n}\n","import { type Emitter } from 'rettime'\nimport {\n type HttpRequestEventMap,\n type HttpResponseEvent,\n} from '#/src/events/http'\nimport { type Interceptor } from '#/src/interceptor'\nimport { type DisposableSubscription } from '#/src/disposable'\nimport { createLogger } from '#/src/utils/logger'\n\nconst logger = createLogger('http-request')\n\ninterface ForwardHttpEventsOptions {\n source: Interceptor<HttpRequestEventMap>\n emitter: Emitter<HttpRequestEventMap>\n predicate: (initiator: unknown) => boolean\n responsePredicate?: (event: HttpResponseEvent) => boolean\n}\n\nexport function forwardHttpEvents(\n options: ForwardHttpEventsOptions\n): DisposableSubscription {\n const controller = new AbortController()\n const { source, emitter, predicate, responsePredicate } = options\n\n source.on(\n 'request',\n async (event) => {\n if (predicate(event.initiator)) {\n logger.verbose('forwarding \"request\" event %o', {\n requestId: event.requestId,\n })\n await emitter.emitAsPromise(event)\n }\n },\n {\n signal: controller.signal,\n }\n )\n\n const responseListener: Emitter.Listener<\n Emitter<HttpRequestEventMap>,\n 'response'\n > = async (event) => {\n if (\n predicate(event.initiator) &&\n (responsePredicate == null || responsePredicate(event))\n ) {\n logger.verbose('forwarding \"response\" event %o', {\n requestId: event.requestId,\n responseType: event.responseType,\n })\n await emitter.emitAsPromise(event)\n }\n }\n\n const unhandledExceptionListener: Emitter.Listener<\n Emitter<HttpRequestEventMap>,\n 'unhandledException'\n > = async (event) => {\n if (predicate(event.initiator)) {\n logger.verbose('forwarding \"unhandledException\" event %o', {\n requestId: event.requestId,\n })\n await emitter.emitAsPromise(event)\n }\n }\n\n const addResponseListener = (): void => {\n if (!source.listeners('response').includes(responseListener)) {\n source.on('response', responseListener, {\n signal: controller.signal,\n })\n }\n }\n\n const addUnhandledExceptionListener = (): void => {\n if (\n !source\n .listeners('unhandledException')\n .includes(unhandledExceptionListener)\n ) {\n source.on('unhandledException', unhandledExceptionListener, {\n signal: controller.signal,\n })\n }\n }\n\n if (emitter.listenerCount('response') > 0) {\n addResponseListener()\n }\n\n if (emitter.listenerCount('unhandledException') > 0) {\n addUnhandledExceptionListener()\n }\n\n emitter.hooks.on(\n 'newListener',\n (type) => {\n if (type === 'response') {\n addResponseListener()\n }\n\n if (type === 'unhandledException') {\n addUnhandledExceptionListener()\n }\n },\n {\n signal: controller.signal,\n persist: true,\n }\n )\n\n emitter.hooks.on(\n 'removeListener',\n (type) => {\n if (type === 'response' && emitter.listenerCount('response') === 0) {\n source.removeListener('response', responseListener)\n }\n\n if (\n type === 'unhandledException' &&\n emitter.listenerCount('unhandledException') === 0\n ) {\n source.removeListener(\n 'unhandledException',\n unhandledExceptionListener\n )\n }\n },\n {\n signal: controller.signal,\n persist: true,\n }\n )\n\n return () => {\n controller.abort()\n }\n}\n","import { TypedEvent } from 'rettime'\nimport type { RequestController } from '../request-controller'\n\nexport interface HttpRequestEventData {\n request: Request\n requestId: string\n initiator: unknown\n controller: RequestController\n}\n\nexport class HttpRequestEvent<\n DataType extends HttpRequestEventData = HttpRequestEventData,\n> extends TypedEvent<DataType, void, 'request'> {\n public request: Request\n public requestId: string\n public initiator: unknown\n public controller: RequestController\n\n constructor(data: DataType) {\n super(...(['request', {}] as any))\n\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n this.controller = data.controller\n }\n}\n\nexport type HttpResponseType = 'mock' | 'original'\n\ninterface HttpResponseEventData {\n response: Response\n responseType: HttpResponseType\n request: Request\n requestId: string\n initiator: unknown\n}\n\nexport class HttpResponseEvent<\n DataType extends HttpResponseEventData = HttpResponseEventData,\n> extends TypedEvent<DataType, void, 'response'> {\n public response: Response\n public responseType: HttpResponseType\n public request: Request\n public requestId: string\n public initiator: unknown\n\n constructor(data: DataType) {\n super(...(['response', {}] as any))\n\n this.response = data.response\n this.responseType = data.responseType\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n }\n}\n\ninterface UnhandledHttpExceptionEventData {\n error: unknown\n request: Request\n requestId: string\n initiator: unknown\n controller: RequestController\n}\n\nexport class UnhandledHttpException<\n DataType extends UnhandledHttpExceptionEventData =\n UnhandledHttpExceptionEventData,\n> extends TypedEvent<DataType, void, 'unhandledException'> {\n public error: unknown\n public request: Request\n public requestId: string\n public initiator: unknown\n public controller: RequestController\n\n constructor(data: DataType) {\n super(...(['unhandledException', {}] as any))\n\n this.error = data.error\n this.request = data.request\n this.requestId = data.requestId\n this.initiator = data.initiator\n this.controller = data.controller\n }\n}\n\nexport type HttpRequestEventMap = {\n request: HttpRequestEvent\n response: HttpResponseEvent\n unhandledException: UnhandledHttpException\n}\n","import net from 'node:net'\nimport tls from 'node:tls'\nimport { NetworkConnectionOptions } from './normalize-net-connect-args'\n\n/**\n * Creates a `URL` instance out of the `net.connect()` options.\n * @note This implies that the passed connection is an HTTP connection.\n */\nexport function connectionOptionsToUrl(\n options: NetworkConnectionOptions,\n socket: net.Socket\n): URL {\n const isIPv6 = net.isIPv6(options.host || '')\n const protocol =\n socket instanceof tls.TLSSocket\n ? 'https:'\n : getProtocolByConnectionOptions(options)\n const host = options.host || 'localhost'\n\n const url = new URL(`${protocol}//${isIPv6 ? `[${host}]` : host}`)\n\n if (options.path) {\n url.pathname = options.path\n }\n\n if (options.port) {\n url.port = options.port.toString()\n }\n\n if (options.auth) {\n const [username, password] = options.auth.split(':')\n /**\n * Authentication options are provided as plain values.\n * Encode them to form a valid URL.\n * @see https://github.com/nodejs/node/blob/f3adc11e37b8bfaaa026ea85c1cf22e3a0e29ae9/lib/internal/url.js#L1452\n */\n url.username = encodeURIComponent(username)\n url.password = encodeURIComponent(password)\n }\n\n return url\n}\n\nfunction getProtocolByConnectionOptions(\n options: NetworkConnectionOptions\n): 'https:' | 'http:' | (string & {}) {\n if (options.protocol) {\n return options.protocol\n }\n\n if (options.port === 443) {\n return 'https:'\n }\n\n return 'http:'\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SPECIAL_HEADERS = exports.MINOR = exports.MAJOR = exports.QDTEXT = exports.CONNECTION_TOKEN_CHARS = exports.RELAXED_HEADER_CHARS = exports.HEADER_CHARS = exports.HTAB_SP_VCHAR_OBS_TEXT = exports.SP = exports.HTAB = exports.TOKEN = exports.HEX = exports.URL_CHAR = exports.USERINFO_CHARS = exports.MARK = exports.ALPHANUM = exports.DIGIT = exports.HEX_MAP = exports.NUM_MAP = exports.ALPHA = exports.METHODS = exports.METHODS_HTTP = exports.METHODS_HTTP2 = exports.METHODS_HTTP1 = exports.METHODS_RTSP = exports.METHODS_RAOP = exports.METHODS_AIRPLAY = exports.METHODS_ICECAST = exports.METHODS_NON_STANDARD = exports.METHODS_CALDAV = exports.METHODS_UPNP = exports.METHODS_SUBVERSION = exports.METHODS_WEBDAV = exports.METHODS_BASIC_HTTP = exports.METHODS_HTTP1_HEAD = exports.HEADER_STATE = exports.FINISH = exports.STATUSES = exports.LENIENT_FLAGS = exports.FLAGS = exports.TYPE = exports.ERROR = void 0;\nexports.ERROR = {\n OK: 0,\n INTERNAL: 1,\n STRICT: 2,\n CR_EXPECTED: 25,\n LF_EXPECTED: 3,\n UNEXPECTED_CONTENT_LENGTH: 4,\n UNEXPECTED_SPACE: 30,\n CLOSED_CONNECTION: 5,\n INVALID_METHOD: 6,\n INVALID_URL: 7,\n INVALID_CONSTANT: 8,\n INVALID_VERSION: 9,\n INVALID_HEADER_TOKEN: 10,\n INVALID_CONTENT_LENGTH: 11,\n INVALID_CHUNK_SIZE: 12,\n INVALID_STATUS: 13,\n INVALID_EOF_STATE: 14,\n INVALID_TRANSFER_ENCODING: 15,\n CB_MESSAGE_BEGIN: 16,\n CB_HEADERS_COMPLETE: 17,\n CB_MESSAGE_COMPLETE: 18,\n CB_CHUNK_HEADER: 19,\n CB_CHUNK_COMPLETE: 20,\n PAUSED: 21,\n PAUSED_UPGRADE: 22,\n PAUSED_H2_UPGRADE: 23,\n USER: 24,\n CB_URL_COMPLETE: 26,\n CB_STATUS_COMPLETE: 27,\n CB_METHOD_COMPLETE: 32,\n CB_VERSION_COMPLETE: 33,\n CB_HEADER_FIELD_COMPLETE: 28,\n CB_HEADER_VALUE_COMPLETE: 29,\n CB_CHUNK_EXTENSION_NAME_COMPLETE: 34,\n CB_CHUNK_EXTENSION_VALUE_COMPLETE: 35,\n CB_RESET: 31,\n CB_PROTOCOL_COMPLETE: 38,\n};\nexports.TYPE = {\n BOTH: 0, // default\n REQUEST: 1,\n RESPONSE: 2,\n};\nexports.FLAGS = {\n CONNECTION_KEEP_ALIVE: 1 << 0,\n CONNECTION_CLOSE: 1 << 1,\n CONNECTION_UPGRADE: 1 << 2,\n CHUNKED: 1 << 3,\n UPGRADE: 1 << 4,\n CONTENT_LENGTH: 1 << 5,\n SKIPBODY: 1 << 6,\n TRAILING: 1 << 7,\n // 1 << 8 is unused\n TRANSFER_ENCODING: 1 << 9,\n};\nexports.LENIENT_FLAGS = {\n HEADERS: 1 << 0,\n CHUNKED_LENGTH: 1 << 1,\n KEEP_ALIVE: 1 << 2,\n TRANSFER_ENCODING: 1 << 3,\n VERSION: 1 << 4,\n DATA_AFTER_CLOSE: 1 << 5,\n OPTIONAL_LF_AFTER_CR: 1 << 6,\n OPTIONAL_CRLF_AFTER_CHUNK: 1 << 7,\n OPTIONAL_CR_BEFORE_LF: 1 << 8,\n SPACES_AFTER_CHUNK_SIZE: 1 << 9,\n HEADER_VALUE_RELAXED: 1 << 10,\n};\nexports.STATUSES = {\n CONTINUE: 100,\n SWITCHING_PROTOCOLS: 101,\n PROCESSING: 102,\n EARLY_HINTS: 103,\n RESPONSE_IS_STALE: 110, // Unofficial\n REVALIDATION_FAILED: 111, // Unofficial\n DISCONNECTED_OPERATION: 112, // Unofficial\n HEURISTIC_EXPIRATION: 113, // Unofficial\n MISCELLANEOUS_WARNING: 199, // Unofficial\n OK: 200,\n CREATED: 201,\n ACCEPTED: 202,\n NON_AUTHORITATIVE_INFORMATION: 203,\n NO_CONTENT: 204,\n RESET_CONTENT: 205,\n PARTIAL_CONTENT: 206,\n MULTI_STATUS: 207,\n ALREADY_REPORTED: 208,\n TRANSFORMATION_APPLIED: 214, // Unofficial\n IM_USED: 226,\n MISCELLANEOUS_PERSISTENT_WARNING: 299, // Unofficial\n MULTIPLE_CHOICES: 300,\n MOVED_PERMANENTLY: 301,\n FOUND: 302,\n SEE_OTHER: 303,\n NOT_MODIFIED: 304,\n USE_PROXY: 305,\n SWITCH_PROXY: 306, // No longer used\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n BAD_REQUEST: 400,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n METHOD_NOT_ALLOWED: 405,\n NOT_ACCEPTABLE: 406,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n REQUEST_TIMEOUT: 408,\n CONFLICT: 409,\n GONE: 410,\n LENGTH_REQUIRED: 411,\n PRECONDITION_FAILED: 412,\n PAYLOAD_TOO_LARGE: 413,\n URI_TOO_LONG: 414,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n EXPECTATION_FAILED: 417,\n IM_A_TEAPOT: 418,\n PAGE_EXPIRED: 419, // Unofficial\n ENHANCE_YOUR_CALM: 420, // Unofficial\n MISDIRECTED_REQUEST: 421,\n UNPROCESSABLE_ENTITY: 422,\n LOCKED: 423,\n FAILED_DEPENDENCY: 424,\n TOO_EARLY: 425,\n UPGRADE_REQUIRED: 426,\n PRECONDITION_REQUIRED: 428,\n TOO_MANY_REQUESTS: 429,\n REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL: 430, // Unofficial\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n LOGIN_TIMEOUT: 440, // Unofficial\n NO_RESPONSE: 444, // Unofficial\n RETRY_WITH: 449, // Unofficial\n BLOCKED_BY_PARENTAL_CONTROL: 450, // Unofficial\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n CLIENT_CLOSED_LOAD_BALANCED_REQUEST: 460, // Unofficial\n INVALID_X_FORWARDED_FOR: 463, // Unofficial\n REQUEST_HEADER_TOO_LARGE: 494, // Unofficial\n SSL_CERTIFICATE_ERROR: 495, // Unofficial\n SSL_CERTIFICATE_REQUIRED: 496, // Unofficial\n HTTP_REQUEST_SENT_TO_HTTPS_PORT: 497, // Unofficial\n INVALID_TOKEN: 498, // Unofficial\n CLIENT_CLOSED_REQUEST: 499, // Unofficial\n INTERNAL_SERVER_ERROR: 500,\n NOT_IMPLEMENTED: 501,\n BAD_GATEWAY: 502,\n SERVICE_UNAVAILABLE: 503,\n GATEWAY_TIMEOUT: 504,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n VARIANT_ALSO_NEGOTIATES: 506,\n INSUFFICIENT_STORAGE: 507,\n LOOP_DETECTED: 508,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n NOT_EXTENDED: 510,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n WEB_SERVER_UNKNOWN_ERROR: 520, // Unofficial\n WEB_SERVER_IS_DOWN: 521, // Unofficial\n CONNECTION_TIMEOUT: 522, // Unofficial\n ORIGIN_IS_UNREACHABLE: 523, // Unofficial\n TIMEOUT_OCCURED: 524, // Unofficial\n SSL_HANDSHAKE_FAILED: 525, // Unofficial\n INVALID_SSL_CERTIFICATE: 526, // Unofficial\n RAILGUN_ERROR: 527, // Unofficial\n SITE_IS_OVERLOADED: 529, // Unofficial\n SITE_IS_FROZEN: 530, // Unofficial\n IDENTITY_PROVIDER_AUTHENTICATION_ERROR: 561, // Unofficial\n NETWORK_READ_TIMEOUT: 598, // Unofficial\n NETWORK_CONNECT_TIMEOUT: 599, // Unofficial\n};\nexports.FINISH = {\n SAFE: 0,\n SAFE_WITH_CB: 1,\n UNSAFE: 2,\n};\nexports.HEADER_STATE = {\n GENERAL: 0,\n CONNECTION: 1,\n CONTENT_LENGTH: 2,\n TRANSFER_ENCODING: 3,\n UPGRADE: 4,\n CONNECTION_KEEP_ALIVE: 5,\n CONNECTION_CLOSE: 6,\n CONNECTION_UPGRADE: 7,\n TRANSFER_ENCODING_CHUNKED: 8,\n};\nexports.METHODS_HTTP1_HEAD = {\n HEAD: 2,\n};\n/**\n * HTTP methods as defined by RFC-9110 and other specifications.\n * @see https://httpwg.org/specs/rfc9110.html#method.definitions\n */\nexports.METHODS_BASIC_HTTP = {\n DELETE: 0,\n GET: 1,\n ...exports.METHODS_HTTP1_HEAD,\n POST: 3,\n PUT: 4,\n CONNECT: 5,\n OPTIONS: 6,\n TRACE: 7,\n /**\n * @see https://www.rfc-editor.org/rfc/rfc5789.html\n */\n PATCH: 28,\n /* RFC-2068, section 19.6.1.2 */\n LINK: 31,\n UNLINK: 32,\n};\nexports.METHODS_WEBDAV = {\n COPY: 8,\n LOCK: 9,\n MKCOL: 10,\n MOVE: 11,\n PROPFIND: 12,\n PROPPATCH: 13,\n SEARCH: 14,\n UNLOCK: 15,\n BIND: 16,\n REBIND: 17,\n UNBIND: 18,\n ACL: 19,\n};\nexports.METHODS_SUBVERSION = {\n REPORT: 20,\n MKACTIVITY: 21,\n CHECKOUT: 22,\n MERGE: 23,\n};\nexports.METHODS_UPNP = {\n 'M-SEARCH': 24,\n NOTIFY: 25,\n SUBSCRIBE: 26,\n UNSUBSCRIBE: 27,\n};\nexports.METHODS_CALDAV = {\n MKCALENDAR: 30,\n};\nexports.METHODS_NON_STANDARD = {\n /**\n * Not defined in any RFC but commonly used\n */\n PURGE: 29,\n /* DRAFT https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html */\n QUERY: 46,\n};\nexports.METHODS_ICECAST = {\n SOURCE: 33,\n};\nexports.METHODS_AIRPLAY = {\n GET: 1,\n POST: 3,\n};\nexports.METHODS_RAOP = {\n FLUSH: 45,\n};\n/* RFC-2326 RTSP */\nexports.METHODS_RTSP = {\n OPTIONS: exports.METHODS_BASIC_HTTP.OPTIONS,\n DESCRIBE: 35,\n ANNOUNCE: 36,\n SETUP: 37,\n PLAY: 38,\n PAUSE: 39,\n TEARDOWN: 40,\n GET_PARAMETER: 41,\n SET_PARAMETER: 42,\n REDIRECT: 43,\n RECORD: 44,\n ...exports.METHODS_AIRPLAY,\n ...exports.METHODS_RAOP,\n};\nexports.METHODS_HTTP1 = {\n ...exports.METHODS_BASIC_HTTP,\n ...exports.METHODS_WEBDAV,\n ...exports.METHODS_SUBVERSION,\n ...exports.METHODS_UPNP,\n ...exports.METHODS_CALDAV,\n ...exports.METHODS_NON_STANDARD,\n // TODO(indutny): should we allow it with HTTP?\n ...exports.METHODS_ICECAST,\n};\nexports.METHODS_HTTP2 = {\n /**\n * RFC-9113, section 11.6\n * @see https://www.rfc-editor.org/rfc/rfc9113.html#preface\n */\n PRI: 34,\n};\nexports.METHODS_HTTP = {\n ...exports.METHODS_HTTP1,\n ...exports.METHODS_HTTP2,\n};\nexports.METHODS = {\n ...exports.METHODS_HTTP1,\n ...exports.METHODS_HTTP2,\n ...exports.METHODS_RTSP,\n};\n// ALPHA: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.ALPHA = [\n \"A\", \"a\", \"B\", \"b\", \"C\", \"c\", \"D\", \"d\",\n \"E\", \"e\", \"F\", \"f\", \"G\", \"g\", \"H\", \"h\",\n \"I\", \"i\", \"J\", \"j\", \"K\", \"k\", \"L\", \"l\",\n \"M\", \"m\", \"N\", \"n\", \"O\", \"o\", \"P\", \"p\",\n \"Q\", \"q\", \"R\", \"r\", \"S\", \"s\", \"T\", \"t\",\n \"U\", \"u\", \"V\", \"v\", \"W\", \"w\", \"X\", \"x\",\n \"Y\", \"y\", \"Z\", \"z\",\n];\nexports.NUM_MAP = {\n 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,\n 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,\n};\nexports.HEX_MAP = {\n 0: 0, 1: 1, 2: 2, 3: 3, 4: 4,\n 5: 5, 6: 6, 7: 7, 8: 8, 9: 9,\n A: 0XA, B: 0XB, C: 0XC, D: 0XD, E: 0XE, F: 0XF,\n a: 0xa, b: 0xb, c: 0xc, d: 0xd, e: 0xe, f: 0xf,\n};\n// DIGIT: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.DIGIT = [\n '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n];\nexports.ALPHANUM = [...exports.ALPHA, ...exports.DIGIT];\nexports.MARK = ['-', '_', '.', '!', '~', '*', '\\'', '(', ')'];\nexports.USERINFO_CHARS = [...exports.ALPHANUM, ...exports.MARK, '%', ';', ':', '&', '=', '+', '$', ','];\n// TODO(indutny): use RFC\nexports.URL_CHAR = [\n '!', '\"', '$', '%', '&', '\\'',\n '(', ')', '*', '+', ',', '-', '.', '/',\n ':', ';', '<', '=', '>',\n '@', '[', '\\\\', ']', '^', '_',\n '`',\n '{', '|', '}', '~',\n ...exports.ALPHANUM\n];\nexports.HEX = [...exports.DIGIT, 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F'];\n/* Tokens as defined by rfc 2616. Also lowercases them.\n * token = 1*<any CHAR except CTLs or separators>\n * separators = \"(\" | \")\" | \"<\" | \">\" | \"@\"\n * | \",\" | \";\" | \":\" | \"\\\" | <\">\n * | \"/\" | \"[\" | \"]\" | \"?\" | \"=\"\n * | \"{\" | \"}\" | SP | HT\n */\nexports.TOKEN = [\n '!', '#', '$', '%', '&', '\\'',\n '*', '+', '-', '.',\n '^', '_', '`',\n '|', '~',\n ...exports.ALPHANUM\n];\n// HTAB: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.HTAB = ['\\t'];\n// SP: https://tools.ietf.org/html/rfc5234#appendix-B.1\nexports.SP = [' '];\n// VCHAR: https://tools.ietf.org/html/rfc5234#appendix-B.1\nconst VCHAR = [\n 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,\n 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,\n 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,\n 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,\n 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,\n 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,\n 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,\n 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,\n 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,\n 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,\n];\n// OBS_TEXT: https://datatracker.ietf.org/doc/html/rfc9110#name-collected-abnf\n// 0x80 - 0xff\nconst OBS_TEXT = [\n 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,\n 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,\n 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,\n 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,\n 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,\n 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,\n 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,\n 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,\n 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,\n];\nexports.HTAB_SP_VCHAR_OBS_TEXT = [...exports.HTAB, ...exports.SP, ...VCHAR, ...OBS_TEXT];\nexports.HEADER_CHARS = exports.HTAB_SP_VCHAR_OBS_TEXT;\nconst RELAXED_CTRL_CHARS = [\n 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Before TAB\n 0x0b, 0x0c, // VT, FF (between TAB and CR)\n 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, // After CR/LF, before space\n 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,\n 0x1e, 0x1f,\n 0x7f, // DEL\n];\n// Relaxed header chars includes control characters (above) that are not allowed\n// by default. This excludes only NULL (0x00), CR (0x0d), LF (0x0a).\nexports.RELAXED_HEADER_CHARS = [...RELAXED_CTRL_CHARS, ...exports.HEADER_CHARS];\n// ',' = \\x2c\nexports.CONNECTION_TOKEN_CHARS = [\n ...exports.HTAB, ...exports.SP,\n 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\n 0x29, 0x2a, 0x2b, /* */ 0x2d, 0x2e, 0x2f, 0x30,\n 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,\n 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,\n 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,\n 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,\n 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,\n 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,\n 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,\n 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,\n 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,\n 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,\n ...OBS_TEXT\n];\n// QDTEXT: https://datatracker.ietf.org/doc/html/rfc9110#section-5.6.4\nexports.QDTEXT = [\n ...exports.HTAB, ...exports.SP,\n 0x21,\n 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,\n 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,\n 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,\n 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42,\n 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,\n 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,\n 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,\n 0x5b,\n 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64,\n 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,\n 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,\n 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c,\n 0x7d, 0x7e,\n ...OBS_TEXT\n];\nexports.MAJOR = exports.NUM_MAP;\nexports.MINOR = exports.MAJOR;\nexports.SPECIAL_HEADERS = {\n 'connection': exports.HEADER_STATE.CONNECTION,\n 'content-length': exports.HEADER_STATE.CONTENT_LENGTH,\n 'proxy-connection': exports.HEADER_STATE.CONNECTION,\n 'transfer-encoding': exports.HEADER_STATE.TRANSFER_ENCODING,\n 'upgrade': exports.HEADER_STATE.UPGRADE,\n};\nexports.default = {\n ERROR: exports.ERROR,\n TYPE: exports.TYPE,\n FLAGS: exports.FLAGS,\n LENIENT_FLAGS: exports.LENIENT_FLAGS,\n STATUSES: exports.STATUSES,\n FINISH: exports.FINISH,\n HEADER_STATE: exports.HEADER_STATE,\n ALPHA: exports.ALPHA,\n NUM_MAP: exports.NUM_MAP,\n HEX_MAP: exports.HEX_MAP,\n DIGIT: exports.DIGIT,\n ALPHANUM: exports.ALPHANUM,\n MARK: exports.MARK,\n USERINFO_CHARS: exports.USERINFO_CHARS,\n URL_CHAR: exports.URL_CHAR,\n HEX: exports.HEX,\n TOKEN: exports.TOKEN,\n HEADER_CHARS: exports.HEADER_CHARS,\n RELAXED_HEADER_CHARS: exports.RELAXED_HEADER_CHARS,\n CONNECTION_TOKEN_CHARS: exports.CONNECTION_TOKEN_CHARS,\n QDTEXT: exports.QDTEXT,\n HTAB_SP_VCHAR_OBS_TEXT: exports.HTAB_SP_VCHAR_OBS_TEXT,\n MAJOR: exports.MAJOR,\n MINOR: exports.MINOR,\n SPECIAL_HEADERS: exports.SPECIAL_HEADERS,\n METHODS: exports.METHODS,\n METHODS_HTTP: exports.METHODS_HTTP,\n METHODS_HTTP1_HEAD: exports.METHODS_HTTP1_HEAD,\n METHODS_HTTP1: exports.METHODS_HTTP1,\n METHODS_HTTP2: exports.METHODS_HTTP2,\n METHODS_ICECAST: exports.METHODS_ICECAST,\n METHODS_RTSP: exports.METHODS_RTSP,\n};","import fs from 'node:fs'\nimport * as constants from './llhttp/constants.cjs'\n\nexport { constants }\n\nexport interface RequestHeadersComplete {\n versionMajor: number\n versionMinor: number\n rawHeaders: Array<string>\n method: string\n url: string\n upgrade: boolean\n shouldKeepAlive: boolean\n}\n\nexport interface ResponseHeadersComplete {\n versionMajor: number\n versionMinor: number\n rawHeaders: Array<string>\n statusCode: number\n statusMessage: string\n upgrade: boolean\n shouldKeepAlive: boolean\n}\n\nconst KIND_REQUEST = constants.TYPE.REQUEST\nconst KIND_RESPONSE = constants.TYPE.RESPONSE\n\ntype ParserKind = typeof KIND_REQUEST | typeof KIND_RESPONSE\n\nexport interface ParserCallbacks<K extends ParserKind> {\n onError?: (error: Error) => void\n onMessageBegin?: () => number | void\n onHeadersComplete?: (\n info: K extends typeof KIND_REQUEST\n ? RequestHeadersComplete\n : ResponseHeadersComplete\n ) => number | void\n onBody?: (body: Buffer) => number | void\n onMessageComplete?: () => number | void\n}\n\nexport type RequestParserCallbacks = ParserCallbacks<typeof KIND_REQUEST>\nexport type ResponseParserCallbacks = ParserCallbacks<typeof KIND_RESPONSE>\n\nconst kPointer = Symbol('kPtr')\nconst kUrl = Symbol('kUrl')\nconst kStatusMessage = Symbol('kStatusMessage')\nconst kHeadersFields = Symbol('kHeadersFields')\nconst kHeadersValues = Symbol('kHeadersValues')\nconst kLastHeaderCallback = Symbol('kLastHeaderCallback')\nconst kCallbacks = Symbol('kCallbacks')\nconst kType = Symbol('kType')\n\nconst HEADER_CB_NONE = 0\nconst HEADER_CB_FIELD = 1\nconst HEADER_CB_VALUE = 2\n\nconst parsersMap = new Map<number, HttpParser<any>>()\n\nconst methodNames = Object.fromEntries(\n Object.entries(constants.METHODS).map(([name, num]) => [num, name])\n) as Record<number, string>\n\nfunction readStringFrom(pointer: number, length: number): string {\n return Buffer.from(llhttp_memory.buffer, pointer, length).toString('latin1')\n}\n\n/**\n * @note Reference the base URL through a variable. Bundlers (e.g. Vite)\n * statically rewrite the `new URL('...', import.meta.url)` pattern into\n * an asset URL resolved against the served origin, which breaks reading\n * the WASM binary from the file system in DOM-like test environments.\n */\nconst wasmBaseUrl = import.meta.url\n\nconst llhttpModule = new WebAssembly.Module(\n fs.readFileSync(new URL('./llhttp/llhttp.wasm', wasmBaseUrl))\n)\n\nconst llhttpInstance = new WebAssembly.Instance(llhttpModule, {\n env: {\n wasm_on_message_begin(parserPointer: number) {\n const parser = parsersMap.get(parserPointer)!\n parser[kUrl] = ''\n parser[kStatusMessage] = ''\n parser[kHeadersFields] = []\n parser[kHeadersValues] = []\n parser[kLastHeaderCallback] = HEADER_CB_NONE\n return parser[kCallbacks].onMessageBegin?.() ?? 0\n },\n // Request only\n wasm_on_url(parserPointer: number, at: number, length: number) {\n parsersMap.get(parserPointer)![kUrl] = readStringFrom(at, length)\n return 0\n },\n // Response only\n wasm_on_status(parserPointer: number, at: number, length: number) {\n parsersMap.get(parserPointer)![kStatusMessage] = readStringFrom(\n at,\n length\n )\n return 0\n },\n wasm_on_header_field(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n const chunk = readStringFrom(at, length)\n const fields = parser[kHeadersFields]\n\n // llhttp emits header field/value across multiple callbacks when the\n // bytes span buffer boundaries. Concatenate consecutive same-type\n // callbacks into a single entry; switch entries on field<->value transitions.\n if (parser[kLastHeaderCallback] === HEADER_CB_FIELD) {\n fields[fields.length - 1] += chunk\n } else {\n fields.push(chunk)\n parser[kLastHeaderCallback] = HEADER_CB_FIELD\n }\n return 0\n },\n wasm_on_header_value(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n const chunk = readStringFrom(at, length)\n const values = parser[kHeadersValues]\n\n if (parser[kLastHeaderCallback] === HEADER_CB_VALUE) {\n values[values.length - 1] += chunk\n } else {\n values.push(chunk)\n parser[kLastHeaderCallback] = HEADER_CB_VALUE\n }\n return 0\n },\n wasm_on_headers_complete(\n parserPointer: number,\n statusCode: number,\n rawUpgrade: number,\n rawShouldKeepAlive: number\n ) {\n const parser = parsersMap.get(parserPointer)!\n const versionMajor = llhttp_get_version_major(parserPointer)\n const versionMinor = llhttp_get_version_minor(parserPointer)\n const rawHeaders: Array<string> = []\n const upgrade = rawUpgrade === 1\n const shouldKeepAlive = rawShouldKeepAlive === 1\n\n for (let c = 0; c < parser[kHeadersFields].length; c++) {\n rawHeaders.push(parser[kHeadersFields][c]!, parser[kHeadersValues][c]!)\n }\n\n if (parser[kType] === KIND_REQUEST) {\n const method = methodNames[llhttp_get_method(parserPointer)]\n const url = parser[kUrl]\n const callback = parser[kCallbacks] as ParserCallbacks<\n typeof KIND_REQUEST\n >\n\n return (\n callback.onHeadersComplete?.({\n versionMajor,\n versionMinor,\n rawHeaders,\n method,\n url,\n upgrade,\n shouldKeepAlive,\n }) ?? 0\n )\n } else {\n const statusCode = llhttp_get_status_code(parserPointer) as number\n const statusMessage = parser[kStatusMessage]\n const callback = parser[kCallbacks] as ParserCallbacks<\n typeof KIND_RESPONSE\n >\n\n return (\n callback.onHeadersComplete?.({\n versionMajor,\n versionMinor,\n rawHeaders,\n statusCode,\n statusMessage,\n upgrade,\n shouldKeepAlive,\n }) ?? 0\n )\n }\n },\n wasm_on_body(parserPointer: number, at: number, length: number) {\n const parser = parsersMap.get(parserPointer)!\n // Create a copy of the body chunk, as the underlying memory buffer is reused by llhttp and can be overwritten on the next callback call.\n // Maybe not the most efficient way, but it is simple and safe.\n const body = Buffer.from(new Uint8Array(llhttp_memory.buffer, at, length))\n return parser[kCallbacks].onBody?.(body) ?? 0\n },\n wasm_on_message_complete(parserPointer: number) {\n return (\n parsersMap.get(parserPointer)![kCallbacks].onMessageComplete?.() ?? 0\n )\n },\n },\n})\n\nconst llhttp_memory = llhttpInstance.exports.memory as WebAssembly.Memory\nconst llhttp_alloc = llhttpInstance.exports.llhttp_alloc as CallableFunction\nconst llhttp_malloc = llhttpInstance.exports.malloc as CallableFunction\nconst llhttp_execute = llhttpInstance.exports.llhttp_execute as CallableFunction\nconst llhttp_get_type = llhttpInstance.exports\n .llhttp_get_type as CallableFunction\nconst llhttp_get_upgrade = llhttpInstance.exports\n .llhttp_get_upgrade as CallableFunction\nconst llhttp_should_keep_alive = llhttpInstance.exports\n .llhttp_should_keep_alive as CallableFunction\nconst llhttp_get_method = llhttpInstance.exports\n .llhttp_get_method as CallableFunction\nconst llhttp_get_status_code = llhttpInstance.exports\n .llhttp_get_status_code as CallableFunction\nconst llhttp_get_version_minor = llhttpInstance.exports\n .llhttp_get_http_minor as CallableFunction\nconst llhttp_get_version_major = llhttpInstance.exports\n .llhttp_get_http_major as CallableFunction\nconst llhttp_get_error_reason = llhttpInstance.exports\n .llhttp_get_error_reason as CallableFunction\nconst llhttp_get_error_pos = llhttpInstance.exports\n .llhttp_get_error_pos as CallableFunction\nconst llhttp_free = llhttpInstance.exports.free as CallableFunction\n\nconst initialize = llhttpInstance.exports._initialize as CallableFunction\ninitialize() // wasi reactor\n\nexport class HttpParser<K extends ParserKind> {\n [kPointer]: number;\n [kUrl]: string = '';\n [kStatusMessage]: string = '';\n [kHeadersFields]: Array<string> = [];\n [kHeadersValues]: Array<string> = [];\n [kLastHeaderCallback]: number = HEADER_CB_NONE;\n [kCallbacks]: ParserCallbacks<K>;\n [kType]: ParserKind\n\n constructor(type: K, callbacks: ParserCallbacks<K>) {\n this[kType] = type\n this[kCallbacks] = callbacks\n\n const parserPointer = llhttp_alloc(type)\n\n if (parserPointer === 0) {\n throw new Error('Failed to allocate llhttp parser')\n }\n\n this[kPointer] = parserPointer\n parsersMap.set(this[kPointer], this)\n }\n\n destroy() {\n // Guard against multiple calls to free/destroy.\n if (this[kPointer] === 0) {\n return\n }\n\n parsersMap.delete(this[kPointer])\n llhttp_free(this[kPointer])\n this[kPointer] = 0\n }\n\n execute(data: Buffer) {\n const pointer = llhttp_malloc(data.byteLength)\n\n if (pointer === 0) {\n throw new Error('Failed to allocate llhttp input buffer')\n }\n\n let ret: number\n try {\n const buffer = new Uint8Array(llhttp_memory.buffer)\n buffer.set(data, pointer)\n ret = llhttp_execute(this[kPointer], pointer, data.byteLength)\n } catch (error) {\n // Free the input buffer if a user callback threw synchronously,\n // otherwise the wasm heap leaks the chunk on every execute() call.\n llhttp_free(pointer)\n throw error\n }\n\n if (ret === constants.ERROR.PAUSED_UPGRADE) {\n // Find how many bytes llhttp consumed\n const errorPos = llhttp_get_error_pos(this[kPointer])\n const consumed = errorPos - pointer\n llhttp_free(pointer)\n // Return the unconsumed trailing bytes (tunnel/protocol data)\n return data.subarray(consumed)\n }\n\n llhttp_free(pointer)\n this.#checkError(ret)\n\n return null // fully consumed\n }\n\n #checkError(errorCode: number) {\n if (errorCode === constants.ERROR.OK) {\n return\n }\n\n const errorPointer = llhttp_get_error_reason(this[kPointer])\n const buffer = new Uint8Array(llhttp_memory.buffer)\n const length = buffer.indexOf(0, errorPointer) - errorPointer\n\n const error = new Error(readStringFrom(errorPointer, length))\n\n if (this[kCallbacks].onError) {\n this[kCallbacks].onError(error)\n return\n }\n\n throw error\n }\n}\n","import { Readable } from 'node:stream'\nimport { invariant } from 'outvariant'\nimport { FetchRequest, FetchResponse } from '../../utils/fetch-utils'\nimport { HttpParser } from './http-parser/index'\n\ninterface HttpRequestParserOptions {\n onError: (error: Error) => void\n connectionOptions: {\n method?: string\n url: URL\n }\n onRequest: (request: Request, abortController: AbortController) => void\n onMessageComplete?: () => void\n}\n\nexport class HttpRequestParser extends HttpParser<1> {\n #requestBodyStream?: Readable\n #upgrade = false\n\n constructor(options: HttpRequestParserOptions) {\n super(1, {\n onError: options.onError,\n onHeadersComplete: ({ rawHeaders, method, url: path, upgrade }) => {\n this.#upgrade = upgrade\n /**\n * @note When the socket is reused, \"connectionOptions\" will point\n * to the \"net.connect()\" call options that established the connection,\n * which may differ from the description of the current request (e.g. method).\n * Rely on the HTTPParser supplying us with the correct \"rawMethod\" number.\n */\n const finalMethod = (\n method ||\n options.connectionOptions.method ||\n 'GET'\n ).toUpperCase()\n\n const url = new URL(path || '', options.connectionOptions.url)\n const headers = FetchResponse.parseRawHeaders([...rawHeaders])\n\n // Translate the basic authorization to request headers.\n // Constructing a Request instance with a URL containing auth is no-op.\n if (url.username || url.password) {\n if (!headers.has('authorization')) {\n const credentials = Buffer.from(\n `${url.username}:${url.password}`\n ).toString('base64')\n headers.set('authorization', `Basic ${credentials}`)\n }\n url.username = ''\n url.password = ''\n }\n\n this.#requestBodyStream = new Readable({\n /**\n * @note Provide the `read()` method so a `Readable` could be\n * used as the actual request body (the stream calls \"read()\").\n */\n read: () => {},\n })\n\n /**\n * @note Expose an abort controller for the parsed request so the\n * consumer can abort it (e.g. when the client destroys the\n * connection before the request is handled).\n */\n const abortController = new AbortController()\n\n const request = new FetchRequest(url, {\n method: finalMethod,\n headers,\n credentials: 'same-origin',\n body: Readable.toWeb(this.#requestBodyStream) as any,\n signal: abortController.signal,\n })\n options.onRequest(request, abortController)\n },\n onBody: (chunk) => {\n invariant(\n this.#requestBodyStream,\n 'Failed to write to a request stream: stream does not exist. This is likely an issue with the library. Please report it on GitHub.'\n )\n\n this.#requestBodyStream.push(chunk)\n },\n onMessageComplete: () => {\n this.#requestBodyStream?.push(null)\n this.#requestBodyStream = undefined\n\n /**\n * @note An upgraded exchange (e.g. \"CONNECT\", WebSocket) has\n * no message boundary: it takes the connection over, and the\n * bytes that follow belong to it, not to a next exchange.\n */\n if (!this.#upgrade) {\n options.onMessageComplete?.()\n }\n },\n })\n }\n\n public free(error?: Error): void {\n this.destroy()\n this.#requestBodyStream?.destroy(error)\n this.#requestBodyStream = undefined\n }\n}\n\nexport class HttpResponseParser extends HttpParser<2> {\n #responseBodyStream?: Readable | null\n #status = 0\n\n constructor(options: {\n onResponse: (response: Response) => void\n onError: (error: Error) => void\n onMessageComplete?: (status: number) => void\n }) {\n super(2, {\n onError: options.onError,\n onHeadersComplete: ({\n rawHeaders,\n statusCode: status,\n statusMessage: statusText,\n }) => {\n this.#status = status\n const headers = FetchResponse.parseRawHeaders([...rawHeaders])\n\n const response = new FetchResponse(\n FetchResponse.isResponseWithBody(status)\n ? (Readable.toWeb(\n (this.#responseBodyStream = new Readable({ read() {} }))\n ) as any)\n : null,\n {\n status,\n statusText,\n headers,\n }\n )\n\n options.onResponse(response)\n },\n onBody: (chunk) => {\n invariant(\n this.#responseBodyStream,\n 'Failed to read from a response stream: stream does not exist. This is likely an issue with the library. Please report it on GitHub.'\n )\n\n this.#responseBodyStream.push(chunk)\n },\n onMessageComplete: () => {\n this.#responseBodyStream?.push(null)\n this.#responseBodyStream = null\n options.onMessageComplete?.(this.#status)\n },\n })\n }\n\n public free(error?: Error): void {\n this.destroy()\n\n if (error) {\n this.#responseBodyStream?.destroy(error)\n }\n\n this.#responseBodyStream = null\n }\n}\n","export function isNodeLikeError(\n error: unknown\n): error is NodeJS.ErrnoException {\n if (error == null) {\n return false\n }\n\n if (!(error instanceof Error)) {\n return false\n }\n\n return 'code' in error && 'errno' in error\n}\n","import type { Emitter } from 'rettime'\nimport { until } from '@open-draft/until'\nimport {\n HttpRequestEvent,\n HttpRequestEventData,\n UnhandledHttpException,\n type HttpRequestEventMap,\n} from '../events/http'\nimport { RequestController } from '../request-controller'\nimport {\n createServerErrorResponse,\n isResponseError,\n isResponseLike,\n} from './response-utils'\nimport { InterceptorError } from '../interceptor-error'\nimport { isNodeLikeError } from './is-node-like-error'\nimport { isObject } from './is-object'\nimport { formatRequest, type Logger } from './logger'\n\nexport interface HandleRequestOptions {\n initiator: unknown\n requestId: string\n request: Request\n emitter: Emitter<HttpRequestEventMap>\n controller: RequestController\n logger?: Logger\n}\n\nexport async function handleRequest(\n options: HandleRequestOptions\n): Promise<void> {\n if (options.logger?.isEnabled('default')) {\n void formatRequest(options.request).then((message) => {\n options.logger?.info('[%s] %s', options.requestId, message)\n })\n }\n\n const handleResponse = async (\n response: Response | Error | Record<string, any>\n ) => {\n if (response instanceof Error) {\n await options.controller.errorWith(response)\n return true\n }\n\n // Handle \"Response.error()\" instances.\n if (isResponseError(response)) {\n await options.controller.respondWith(response)\n return true\n }\n\n /**\n * Handle normal responses or response-like objects.\n * @note This must come before the arbitrary object check\n * since Response instances are, in fact, objects.\n */\n if (isResponseLike(response)) {\n await options.controller.respondWith(response)\n return true\n }\n\n // Handle arbitrary objects provided to `.errorWith(reason)`.\n if (isObject(response)) {\n await options.controller.errorWith(response)\n return true\n }\n\n return false\n }\n\n const handleResponseError = async (error: unknown): Promise<boolean> => {\n // Forward the special interceptor error instances\n // to the developer. These must not be handled in any way.\n if (error instanceof InterceptorError) {\n throw resultError\n }\n\n // Support mocking Node.js-like errors.\n if (isNodeLikeError(error)) {\n await options.controller.errorWith(error)\n return true\n }\n\n // Handle thrown responses.\n if (error instanceof Response) {\n return await handleResponse(error)\n }\n\n return false\n }\n\n const requestAbortPromise = Promise.withResolvers<void>()\n let requestAbortReason: unknown\n let isRequestAborted = false\n const onAbort = () => {\n isRequestAborted = true\n requestAbortReason = options.request.signal?.reason\n requestAbortPromise.reject(requestAbortReason)\n }\n\n /**\n * @note `signal` is not always defined in React Native.\n */\n if (options.request.signal) {\n if (options.request.signal.aborted) {\n await options.controller.errorWith(options.request.signal.reason)\n return\n }\n\n options.request.signal.addEventListener('abort', onAbort, { once: true })\n }\n\n const [resultError] = await until(async () => {\n // Emit the \"request\" event and wait until all the listeners\n // for that event are finished (e.g. async listeners awaited).\n // By the end of this promise, the developer cannot affect the\n // request anymore.\n const requestEventData: HttpRequestEventData = {\n initiator: options.initiator,\n requestId: options.requestId,\n request: options.request,\n controller: options.controller,\n }\n const requestEvent = new HttpRequestEvent(requestEventData)\n const requestListenersPromise = options.emitter.emitAsPromise(requestEvent)\n\n await Promise.race([\n // Short-circuit the request handling promise if the request gets aborted.\n requestAbortPromise.promise,\n requestListenersPromise,\n options.controller.handled,\n ])\n\n /**\n * @note If the \"request\" listener has replaced the request instance,\n * propagate that mutation back to the underlying insterceptor.\n * This happens with XMLHttpRequest that replaces request instances\n * to correctly reflect the \"withCredentials\" option on the Fetch API request.\n */\n if (requestEvent.request !== options.request) {\n options.request = requestEvent.request\n }\n })\n\n options.request.signal?.removeEventListener('abort', onAbort)\n\n // Handle the request being aborted while waiting for the request listeners.\n if (isRequestAborted) {\n await options.controller.errorWith(requestAbortReason)\n return\n }\n\n if (resultError) {\n // Handle the error during the request listener execution.\n // These can be thrown responses or request errors.\n if (await handleResponseError(resultError)) {\n return\n }\n\n // If the developer has added \"unhandledException\" listeners,\n // allow them to handle the error. They can translate it to a\n // mocked response, network error, or forward it as-is.\n if (options.emitter.listenerCount('unhandledException') > 0) {\n // Create a new request controller just for the unhandled exception case.\n // This is needed because the original controller might have been already\n // interacted with (e.g. \"respondWith\" or \"errorWith\" called on it).\n const unhandledExceptionController = new RequestController(\n options.request,\n {\n /**\n * @note Intentionally empty passthrough handle.\n * This controller is created within another controller and we only need\n * to know if `unhandledException` listeners handled the request.\n */\n passthrough() {},\n async respondWith(response) {\n await handleResponse(response)\n },\n async errorWith(reason) {\n /**\n * @note Handle the result of the unhandled controller\n * in the same way as the original request controller.\n * The exception here is that thrown errors within the\n * \"unhandledException\" event do NOT result in another\n * emit of the same event. They are forwarded as-is.\n */\n await options.controller.errorWith(reason)\n },\n }\n )\n\n await options.emitter.emitAsPromise(\n new UnhandledHttpException({\n initiator: options.initiator,\n error: resultError,\n request: options.request,\n requestId: options.requestId,\n controller: unhandledExceptionController,\n })\n )\n\n // If all the \"unhandledException\" listeners have finished\n // but have not handled the request in any way, passthrough.\n if (\n unhandledExceptionController.readyState !== RequestController.PENDING\n ) {\n return\n }\n }\n\n // Otherwise, coerce unhandled exceptions to a 500 Internal Server Error response.\n await options.controller.respondWith(\n createServerErrorResponse(resultError)\n )\n return\n }\n\n // If the request hasn't been handled by this point, passthrough.\n if (options.controller.readyState === RequestController.PENDING) {\n return await options.controller.passthrough()\n }\n\n return options.controller.handled\n}\n","import { FetchResponse } from './fetch-utils'\nimport { copyRawHeaders } from '../interceptors/ClientRequest/utils/record-raw-headers'\n\n/** Clone for observers without letting their unread body block caller cancellation. */\nexport function cloneResponse(response: Response): [Response, Response] {\n const clone = FetchResponse.clone(response)\n\n if (!response.body || !clone.body) {\n return [response, clone]\n }\n\n const observer = wrapResponse(clone)\n const caller = wrapResponse(response, observer.cancel)\n\n return [caller.response, observer.response]\n}\n\nfunction wrapResponse(\n response: Response,\n onCancel?: (reason: unknown) => Promise<void>\n) {\n const body = response.body!\n const reader = body.getReader()\n const cancel = (reason: unknown) => {\n return body.locked ? reader.cancel(reason) : body.cancel(reason)\n }\n const stream = new ReadableStream<Uint8Array>(\n {\n async pull(controller) {\n try {\n const { done, value } = await reader.read()\n\n if (done) {\n controller.close()\n reader.releaseLock()\n return\n }\n\n controller.enqueue(value)\n } catch (error) {\n controller.error(error)\n reader.releaseLock()\n }\n },\n async cancel(reason) {\n try {\n const cancellation = cancel(reason)\n\n if (onCancel) {\n // Caller cancellation owns both branches.\n await Promise.all([cancellation, onCancel(reason)])\n } else {\n // An observer must not wait for the caller to consume its branch:\n // Response delivery is still waiting for this listener to finish.\n void cancellation.catch(() => {})\n }\n } finally {\n reader.releaseLock()\n }\n },\n },\n { highWaterMark: 0 }\n )\n const wrappedResponse = new FetchResponse(stream, response)\n copyRawHeaders(response.headers, wrappedResponse.headers)\n Object.defineProperties(wrappedResponse, {\n type: { value: response.type },\n redirected: { value: response.redirected },\n })\n\n return { response: wrappedResponse, cancel }\n}\n","import net from 'node:net'\nimport {\n METHODS,\n STATUS_CODES,\n ServerResponse,\n IncomingMessage,\n} from 'node:http'\nimport { invariant } from 'outvariant'\nimport { HttpResponseEvent, type HttpRequestEventMap } from '../../events/http'\nimport { RequestController } from '../../request-controller'\nimport {\n getRawFetchHeaders,\n recordRawFetchHeaders,\n} from '../ClientRequest/utils/record-raw-headers'\nimport { SocketInterceptor } from '../net'\nimport { connectionOptionsToUrl } from '../net/utils/connection-options-to-url'\nimport { toBuffer } from '../../utils/buffer-utils'\nimport { createRequestId } from '../../create-request-id'\nimport { HttpRequestParser, HttpResponseParser } from './http-parser'\nimport { handleRequest, HandleRequestOptions } from '../../utils/handle-request'\nimport { isResponseError, kErrorResponse } from '../../utils/response-utils'\nimport { createLogger } from '../../utils/logger'\nimport {\n kRawSocket,\n SocketController,\n type FlushPendingDataFunction,\n} from '../net/socket-controller'\nimport { unwrapPendingData } from '../net/utils/flush-writes'\nimport { FetchResponse } from '../../utils/fetch-utils'\nimport { cloneResponse } from '../../utils/clone-response'\nimport { requestContext } from '../../request-context'\nimport { Interceptor } from '#/src/interceptor'\n\nconst httpLogger = createLogger('http-request')\n\n/**\n * Interceptor for HTTP requests in Node.js.\n * Routes socket connections through an HTTP parser.\n */\nexport class NodeHttpRequestSource extends Interceptor<HttpRequestEventMap> {\n static symbol = Symbol.for('node-http-request-source')\n\n protected predicate(): boolean {\n return true\n }\n\n protected setup(): void {\n const socketInterceptor = Interceptor.singleton(SocketInterceptor)\n socketInterceptor.apply(this)\n this.subscriptions.push(() => {\n socketInterceptor.dispose(this)\n })\n\n /**\n * @note Record the raw values provided to Headers set/append\n * in order to support \"IncomingMessage.prototype.rawHeaders\".\n * This is meant for the headers in mocked responses.\n */\n this.subscriptions.push(recordRawFetchHeaders())\n\n const controller = new AbortController()\n this.subscriptions.push(() => controller.abort())\n\n socketInterceptor.on(\n 'connection',\n ({ connectionOptions, socket, controller: socketController }) => {\n let isHttpConnection: boolean | undefined\n let requestParser: HttpRequestParser | undefined\n let tunnelUrl: URL | undefined\n let abortPendingRequest: (() => void) | undefined\n let pendingRequestController: RequestController | undefined\n\n // Protocol detection runs inside a client write. Let the write finish,\n // other data observers run, and the remaining \"connection\" listeners\n // get their chance to claim before flushing it to the real socket.\n const passthroughNonHttp = () => {\n setImmediate(() => {\n if (\n socketController.readyState === SocketController.PENDING &&\n !socket.destroyed\n ) {\n socketController.passthrough()\n }\n })\n }\n\n // A malformed request loses the boundary for subsequent requests.\n // Preserve the original bytes for the client and server to handle.\n const stopParsingRequests = (error: Error) => {\n httpLogger.verbose('stopping HTTP request parsing: %o', error)\n isHttpConnection = false\n\n if (\n pendingRequestController?.readyState === RequestController.PENDING\n ) {\n void pendingRequestController.passthrough()\n } else {\n passthroughNonHttp()\n }\n\n requestParser?.free(error)\n }\n\n /**\n * @note Capture the request context of the connection itself.\n * The socket is created synchronously within the request async\n * context (e.g. inside the patched `http.request()`), but the\n * first data may reach the socket from a foreign context (e.g.\n * a form-data stream piped into the request), where sampling\n * the request context yields nothing.\n */\n const connectionRequestContext = requestContext.getStore()\n\n /**\n * @note The client destroys the socket synchronously (e.g. Undici\n * on request abort) but the socket teardown events (\"error\",\n * \"close\") are emitted asynchronously, after the consumer has\n * already observed the rejected request promise. Hook into the\n * destroy itself so the pending request is aborted before any\n * of its listeners can resume.\n */\n const rawSocket = socketController[kRawSocket]\n const realSocketDestroy = rawSocket._destroy.bind(rawSocket)\n rawSocket._destroy = (error, callback) => {\n abortPendingRequest?.()\n realSocketDestroy(error, callback)\n }\n\n const executeRequestParser = (\n parser: HttpRequestParser,\n chunk: Buffer\n ) => {\n // llhttp pauses permanently at an upgrade boundary. Release the\n // parser after execute returns, outside its native callbacks.\n if (parser.execute(chunk) !== null) {\n socket.removeListener('data', onRequestData)\n parser.free()\n requestParser = undefined\n }\n }\n\n /**\n * @note Inspect the first sent packet to determine the protocol,\n * including when entering a mocked \"CONNECT\" tunnel.\n */\n const onRequestData = (chunk: Buffer) => {\n if (isHttpConnection === false) {\n passthroughNonHttp()\n return\n }\n\n /**\n * @note A mocked \"CONNECT\" request has established a tunnel.\n * The data that follows belongs to a new exchange addressed to\n * the tunnel target. The previous parser was freed at the upgrade\n * boundary, so detect the tunneled protocol anew.\n */\n if (tunnelUrl && !requestParser) {\n isHttpConnection = undefined\n\n /**\n * @note Retarget the connection to the tunnel authority.\n * The exchanges that follow belong to the tunnel target,\n * so an unclaimed exchange (HTTP or not) must pass through\n * to that target — not to the proxy, which never actually\n * established this tunnel — like a real established tunnel\n * relays its traffic.\n */\n socketController.reset({\n host: tunnelUrl.hostname,\n port: Number(tunnelUrl.port) || 80,\n path: null,\n })\n }\n\n if (requestParser) {\n executeRequestParser(requestParser, toBuffer(chunk))\n return\n }\n\n const httpMessage = chunk.toString()\n const httpMethod = httpMessage.split(' ')[0] || ''\n\n // Stop parsing connections that do not carry HTTP traffic.\n if (!METHODS.includes(httpMethod.toUpperCase())) {\n isHttpConnection = false\n passthroughNonHttp()\n return\n }\n\n isHttpConnection = true\n\n const baseUrl =\n tunnelUrl ?? connectionOptionsToUrl(connectionOptions, socket)\n\n httpLogger.verbose('handling http message %o', {\n httpMessage,\n httpMethod,\n baseUrl,\n })\n\n // Get the request initiator from the async context, falling\n // back to the context captured at the connection time, then\n // to the underlying socket.\n const requestContextValue =\n requestContext.getStore() ?? connectionRequestContext\n const initiator = requestContextValue?.initiator || socket\n\n requestParser = new HttpRequestParser({\n onError: stopParsingRequests,\n connectionOptions: {\n method: httpMethod,\n url: baseUrl,\n },\n /**\n * @note The message boundary ends the current exchange.\n * Schedule the controller reset so the next write on this\n * (kept-alive) socket opens a new exchange and buffers for\n * its own verdict instead of following the settled one\n * (e.g. leaking a mocked request to the server of a\n * previously passed-through exchange).\n */\n onMessageComplete: () => {\n socketController.scheduleReset()\n },\n onRequest: async (parsedRequest, requestAbortController) => {\n const request =\n requestContextValue?.transformRequest?.(parsedRequest) ??\n parsedRequest\n\n /**\n * @note A subsequent request arriving on a kept-alive socket\n * that has already been handled (passed through or mocked).\n * Clients like Undici reuse sockets without emitting the\n * \"free\" event, so reset the controller here, at the HTTP\n * message boundary, to handle the new request from the\n * pending state again.\n */\n if (socketController['readyState'] !== SocketController.PENDING) {\n socketController.reset()\n }\n\n const requestId = createRequestId()\n const requestLogger = requestContextValue?.logger ?? httpLogger\n\n httpLogger.verbose('received a parsed HTTP request %o', {\n method: request.method,\n url: request.url,\n })\n\n const requestController = new RequestController(\n request,\n {\n respondWith: async (rawResponse) => {\n httpLogger.verbose('respondWith() %o', {\n status: rawResponse.status,\n statusText: rawResponse.statusText,\n hasBody: rawResponse.body != null,\n })\n\n /**\n * @note The client may destroy the socket (e.g. on request\n * abort) moments before a response arrives. A destroyed\n * socket cannot be claimed and has no one reading it.\n */\n if (socket.destroyed) {\n return\n }\n\n socketController.claim()\n\n const originalResponse = FetchResponse.from(rawResponse, {\n url: request.url,\n })\n const [response, responseClone] =\n !isResponseError(originalResponse) &&\n this.emitter.listenerCount('response') > 0\n ? cloneResponse(originalResponse)\n : [originalResponse, null]\n\n /**\n * @note A successful mocked response to a \"CONNECT\"\n * request establishes a tunnel to the requested authority\n * (e.g. \"127.0.0.1:80\"). The exchange that follows on this\n * socket is addressed to that authority, not to the proxy.\n */\n if (request.method === 'CONNECT' && response.ok) {\n tunnelUrl = new URL(`http://${request.url}`)\n socket.on('data', onRequestData)\n }\n\n const respond = () => {\n return this.respondWith({\n socket: socketController[kRawSocket],\n request: context.request,\n response,\n })\n }\n\n if (responseClone) {\n await this.emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator,\n requestId,\n request: context.request,\n response: responseClone,\n responseType: 'mock',\n })\n )\n }\n\n if (socket.connecting) {\n // Send a mocked response once the socket connects, just like the real server would.\n // This preserves the correct order of events (e.g. connect, then data).\n socket.once('connect', respond)\n } else {\n /**\n * @note Reused sockets stay connected between requests and will not\n * emit \"connect\" anymore. If that's the case, respond immediately.\n */\n await respond()\n }\n },\n errorWith: (reason) => {\n if (reason instanceof Error) {\n socket.destroy(reason)\n }\n },\n passthrough: () => {\n const realSocket = socketController.passthrough(\n isHttpConnection === false\n ? undefined\n : this.#modifyHttpHeaders(context.request)\n )\n\n if (isHttpConnection === false) {\n return\n }\n\n if (this.emitter.listenerCount('response') > 0) {\n httpLogger.verbose(\n 'found \"response\" listener, corking socket reads'\n )\n\n /**\n * Suspend the delivery of the original response to the client\n * until the \"response\" event listeners settle. This guarantees\n * that the request promise (e.g. `await fetch()`) does not\n * resolve before the listeners are done. The real socket keeps\n * emitting data for the response parser meanwhile.\n */\n socketController.corkReads()\n\n let responseParserDisposed = false\n let responseComplete = false\n let hasFinalResponse = false\n const responseParser = new HttpResponseParser({\n onError: (error) => {\n disposeResponseParser(error)\n socketController.uncorkReads()\n },\n onMessageComplete: (status) => {\n responseComplete = status >= 200 || status === 101\n },\n onResponse: async (response) => {\n hasFinalResponse =\n response.status >= 200 || response.status === 101\n httpLogger.verbose(\n 'HTTP response parser parsed: %d %s',\n response.status,\n response.statusText\n )\n\n if (isResponseError(response)) {\n httpLogger.verbose(\n 'response is an error response, uncorking socket reads...'\n )\n\n socketController.uncorkReads()\n return\n }\n\n FetchResponse.setUrl(request.url, response)\n\n try {\n httpLogger.verbose('emitting \"response\" event')\n await this.emitter.emitAsPromise(\n new HttpResponseEvent({\n initiator,\n requestId,\n request: context.request,\n response,\n responseType: 'original',\n })\n )\n } finally {\n httpLogger.verbose('uncorking socket reads')\n socketController.uncorkReads()\n\n /**\n * @note Informational responses other than\n * \"101 Switching Protocols\" are followed by a final\n * response on the same connection. Keep gating that\n * final response on the \"response\" event listeners.\n */\n if (\n !responseParserDisposed &&\n response.status < 200 &&\n response.status !== 101\n ) {\n socketController.corkReads()\n }\n }\n },\n })\n\n const onResponseData = (chunk: Buffer) => {\n responseParser.execute(chunk)\n\n // Free only after llhttp returns from its callbacks.\n if (responseComplete) {\n disposeResponseParser()\n }\n }\n\n const onResponseEnd = () => {\n disposeResponseParser()\n\n // Without a final response, release EOF now. A half-open\n // socket cannot close until the client consumes it.\n if (!hasFinalResponse) {\n socketController.uncorkReads()\n }\n }\n\n const disposeResponseParser = (error?: Error) => {\n responseParserDisposed = true\n realSocket.removeListener('data', onResponseData)\n realSocket.removeListener('end', onResponseEnd)\n realSocket.removeListener('close', onResponseEnd)\n responseParser.free(error)\n }\n\n realSocket\n .on('data', onResponseData)\n .once('end', onResponseEnd)\n .once('close', onResponseEnd)\n }\n },\n },\n {\n logger: requestLogger,\n requestId,\n }\n )\n\n invariant(\n socketController['readyState'] === SocketController.PENDING,\n 'CANNOT HANDLE ALREADY HANDLED REQUEST',\n request.method,\n request.url,\n socketController['readyState']\n )\n\n /**\n * @note Create a request resolution context.\n * This is so modifications to the \"request\" in upstream interceptors\n * are correctly picked up by the underlying HTTP interceptor.\n */\n const context: HandleRequestOptions = {\n initiator,\n requestId,\n request,\n controller: requestController,\n emitter: this.emitter,\n logger: requestLogger,\n }\n\n /**\n * @note The client destroying the socket while the request\n * is still pending means the request was aborted (e.g. via\n * `AbortController`). Abort the parsed request so its\n * handling settles and late interactions with the request\n * controller become controlled errors.\n */\n abortPendingRequest = () => {\n if (\n requestController.readyState === RequestController.PENDING\n ) {\n requestAbortController.abort()\n }\n }\n\n pendingRequestController = requestController\n\n try {\n await handleRequest(context)\n } finally {\n pendingRequestController = undefined\n abortPendingRequest = undefined\n }\n },\n })\n\n // Forward the first frame to the parser.\n executeRequestParser(requestParser, toBuffer(chunk))\n }\n\n socket.on('data', onRequestData)\n socket.on('close', () => requestParser?.free())\n },\n {\n signal: controller.signal,\n }\n )\n }\n\n private async respondWith(args: {\n socket: net.Socket\n request: Request\n response: Response\n }): Promise<void> {\n const { socket, request, response } = args\n\n if (socket.destroyed) {\n return\n }\n\n if (isResponseError(response)) {\n /**\n * @note Reference the error response on the socket error so the\n * client-side interceptors (e.g. fetch) can surface it to the\n * consumer as the reason behind the failed request. Keep the\n * reference non-enumerable so the error remains observably\n * identical for the clients that expose it as-is.\n */\n socket.destroy(\n Object.defineProperty(new TypeError('Network error'), kErrorResponse, {\n value: response,\n enumerable: false,\n })\n )\n return\n }\n\n invariant(\n !socket.connecting,\n 'Failed to mock a response for \"%s %s\": socket has not connected',\n request.method,\n request.url\n )\n\n /**\n * Use native server response handling in Node.js.\n * @see https://github.com/nodejs/node/blob/13eb80f3b718452213e0fc449702aefbbfe4110f/lib/_http_server.js#L202\n */\n const incomingMessage = new IncomingMessage(socket)\n\n /**\n * @note Describe the request method so the response body is\n * handled appropriately (e.g. \"HEAD\" responses must not write\n * a body). The HTTP version is deliberately left unset: with it,\n * `ServerResponse` frames bodies of unknown length as chunked,\n * polluting the mocked response headers with \"Transfer-Encoding\"\n * the mock never specified.\n */\n incomingMessage.method = request.method\n\n const serverResponse = new ServerResponse(incomingMessage)\n\n const responseSocket = new net.Socket()\n\n responseSocket._writeGeneric = (writev, data, encoding, callback) => {\n unwrapPendingData(data, (chunk, encoding) => {\n socket.push(toBuffer(chunk), encoding)\n })\n callback?.()\n }\n\n responseSocket._destroy = (\n error: Error | null,\n callback: (error: Error | null) => void\n ) => {\n /**\n * Only destroy the socket on stream errors.\n * On a clean end, the socket is already signaled via `socket.push(null)`\n * in the main response flow. Destroying it here prematurely would prevent\n * the client from processing the response (e.g. calling `response.destroy()`).\n * @see https://github.com/mswjs/interceptors/issues/738\n */\n if (error) {\n socket.destroy()\n }\n\n callback(null)\n }\n\n responseSocket.on('drain', () => serverResponse.emit('drain'))\n serverResponse.assignSocket(responseSocket)\n\n serverResponse.removeHeader('connection')\n serverResponse.removeHeader('date')\n\n const rawResponseHeaders = getRawFetchHeaders(response.headers)\n serverResponse.writeHead(\n response.status,\n response.statusText || STATUS_CODES[response.status],\n rawResponseHeaders\n )\n\n /**\n * @note Override the socket's `_destroy` before writing the response body.\n * The underlying TCP handle (from `socket.connect()`) makes `_destroy` async\n * (`_handle.close()` callback), which delays the 'error' event. Since the real\n * TCP connection is irrelevant for mocked responses, take the synchronous path\n * so that user-initiated `response.destroy(error)` emits the error promptly.\n * This must happen before `serverResponse.end()` because the HTTP parser may\n * fire the 'response' event synchronously during `socket.push()`.\n */\n socket._destroy = function (\n error: Error | null,\n callback: (error: Error | null) => void\n ) {\n if (error) {\n /**\n * Emit the error event as a microtask instead of relying on the default\n * `process.nextTick(emitErrorNT)` from `callback(error)`. This is necessary\n * because `respondWith` runs inside a microtask (from `await reader.read()`).\n * A resolved promise continuation (from toWebResponse) is queued as\n * another microtask during the same phase. Since microtasks are drained before\n * nextTick, the test's `await` would resolve before the error event fires.\n * Using `queueMicrotask` ensures the error event is emitted within the current\n * microtask phase, before other queued microtasks.\n */\n queueMicrotask(() => this.emit('error', error))\n }\n\n callback(null)\n\n /**\n * @note `net.Socket` is constructed with `emitClose: false`, so Node's\n * stream destroy machinery does not emit `'close'` automatically; the\n * stock `net.Socket._destroy` only emits it via `_handle.close()`.\n * Since this override replaces `_destroy`, emit `'close'` here so the\n * mocked socket completes its lifecycle (otherwise consumers waiting\n * on `'close'`, like `http.ClientRequest`, hang).\n */\n process.nextTick(() => this.emit('close', error != null))\n }\n\n if (response.body) {\n const reader = response.body.getReader()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n serverResponse.end()\n break\n }\n\n if (!serverResponse.write(value)) {\n await new Promise<void>((resolve) => {\n serverResponse.once('drain', resolve)\n })\n }\n }\n } catch {\n /**\n * @note Delay the socket destruction to allow the event loop\n * to flush already-pushed response data (headers + body chunks)\n * through the HTTP parser. Without this, the socket is destroyed\n * on the same tick as `socket.push(data)` and the client never\n * reads the response.\n */\n await new Promise<void>((resolve) => process.nextTick(resolve))\n socket.destroy()\n return\n }\n } else {\n serverResponse.end()\n }\n\n /**\n * @note Self-delimiting responses (chunked, explicit \"Content-Length\",\n * or bodiless by definition) must NOT signal the end-of-stream.\n * The client parser completes them from their framing alone, and\n * ending the socket would kill the kept-alive connection that\n * agents pool and reuse for subsequent requests.\n */\n const isSelfDelimitingResponse =\n request.method === 'HEAD' ||\n response.headers.has('content-length') ||\n response.headers.has('transfer-encoding') ||\n !FetchResponse.isResponseWithBody(response.status)\n\n if (\n /**\n * @note A non-2xx response to a \"CONNECT\" request means the proxy\n * refused the tunnel. Real proxies terminate the connection after\n * sending such a response, regardless of its framing.\n */\n (request.method === 'CONNECT' && !response.ok) ||\n (request.method !== 'CONNECT' && !isSelfDelimitingResponse)\n ) {\n /**\n * @note Defer the end-of-stream signal so the HTTP parser has a chance\n * to process already-pushed response data and fire the 'response' event\n * before the socket is ended. Without this, the parser marks the response\n * as \"complete\" before the client can interact with it (e.g. `response.destroy()`).\n */\n await new Promise<void>((resolve) => process.nextTick(resolve))\n socket.push(null)\n }\n }\n\n #modifyHttpHeaders(request: Request): FlushPendingDataFunction {\n const transformRequestMessage = (\n httpMessage: string | Buffer,\n encoding?: BufferEncoding | 'buffer'\n ): string | Buffer => {\n /**\n * @note Socket can write a buffer (e.g. uploaded file) even before\n * it writes the HTTP message. Bypass those cases.\n */\n if (encoding === 'buffer') {\n return httpMessage\n }\n\n const parts = httpMessage.toString(encoding).split('\\r\\n')\n const headersEndIndex = parts.findIndex((field) => field === '')\n const httpMessageHeaderPairs = parts.slice(1, headersEndIndex)\n\n // Extract raw [name, value] tuples from the wire format so they\n // can be compared against the request's raw fetch headers.\n const httpMessageRawHeaders = httpMessageHeaderPairs.map(\n (line): [string, string] => {\n const separatorIndex = line.indexOf(': ')\n return [line.slice(0, separatorIndex), line.slice(separatorIndex + 2)]\n }\n )\n\n const requestRawHeaders = getRawFetchHeaders(request.headers)\n\n // If the raw headers from the outgoing HTTP message and the request\n // headers are identical, send the message as-is to avoid the cost\n // (and side effects) of reserializing the headers block.\n const headersUnchanged =\n httpMessageRawHeaders.length === requestRawHeaders.length &&\n httpMessageRawHeaders.every((tuple, index) => {\n const requestTuple = requestRawHeaders[index]\n return tuple[0] === requestTuple[0] && tuple[1] === requestTuple[1]\n })\n\n if (headersUnchanged) {\n return httpMessage\n }\n\n const httpMessageHeaders = FetchResponse.parseRawHeaders(\n httpMessageHeaderPairs.flatMap((header) => header.split(': '))\n )\n\n const visitedHeaders = new Set<string>()\n\n for (const [headerName] of requestRawHeaders) {\n const normalizedHeaderName = headerName.toLowerCase()\n\n if (visitedHeaders.has(normalizedHeaderName)) {\n continue\n }\n\n visitedHeaders.add(normalizedHeaderName)\n\n /**\n * @note Forbidden Fetch headers (e.g. Host, Origin, Connection)\n * are stripped from `request.headers` but remain in the raw\n * headers list. Skip them so the original values from the\n * outgoing HTTP message are preserved.\n */\n const headerValue = request.headers.get(headerName)\n if (headerValue === null) {\n continue\n }\n\n // Use the merged value from Headers to correctly handle\n // appended headers (e.g. \"1, 2\" instead of just \"2\").\n httpMessageHeaders.set(headerName, headerValue)\n }\n\n visitedHeaders.clear()\n\n /**\n * @note Remove the headers deleted from the request (e.g. via\n * `request.headers.delete()`). The raw headers start as a copy of\n * the outgoing HTTP message headers and track every mutation, so a\n * header present in the message but absent from the raw headers has\n * been deleted. Forbidden headers stripped from `request.headers`\n * remain in the raw headers and are preserved as-is.\n */\n const rawHeaderNames = new Set(\n requestRawHeaders.map(([headerName]) => headerName.toLowerCase())\n )\n\n for (const [headerName] of httpMessageRawHeaders) {\n if (!rawHeaderNames.has(headerName.toLowerCase())) {\n httpMessageHeaders.delete(headerName)\n }\n }\n\n const httpMessageHeadersString = Array.from(httpMessageHeaders)\n .map(([name, value]) => `${name}: ${value}`)\n .join('\\r\\n')\n parts.splice(1, headersEndIndex - 1, httpMessageHeadersString)\n\n return parts.join('\\r\\n')\n }\n\n return (pendingData, encoding, callback) => {\n if (Array.isArray(pendingData)) {\n pendingData[0].chunk = transformRequestMessage(\n pendingData[0].chunk,\n pendingData[0].encoding\n )\n } else {\n pendingData = transformRequestMessage(pendingData, encoding)\n }\n\n callback(pendingData)\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@depup/mswjs__interceptors",
|
|
4
4
|
"description": "Low-level network interception library for Node.js. (with updated dependencies)",
|
|
5
|
-
"version": "0.43.
|
|
5
|
+
"version": "0.43.2-depup.0",
|
|
6
6
|
"main": "./lib/node/index.js",
|
|
7
7
|
"types": "./lib/node/index.d.ts",
|
|
8
8
|
"exports": {
|
|
@@ -159,8 +159,8 @@
|
|
|
159
159
|
"changes": {},
|
|
160
160
|
"depsUpdated": 0,
|
|
161
161
|
"originalPackage": "@mswjs/interceptors",
|
|
162
|
-
"originalVersion": "0.43.
|
|
163
|
-
"processedAt": "2026-09-
|
|
162
|
+
"originalVersion": "0.43.2",
|
|
163
|
+
"processedAt": "2026-09-18T16:08:47.013Z",
|
|
164
164
|
"smokeTest": "passed"
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -843,8 +843,11 @@ export class XMLHttpRequestController {
|
|
|
843
843
|
body: resolvedBody,
|
|
844
844
|
})
|
|
845
845
|
|
|
846
|
-
const
|
|
846
|
+
const headers = fetchRequest.headers
|
|
847
|
+
const proxyHeaders = createProxy(headers, {
|
|
847
848
|
methodCall: ([methodName, args], invoke) => {
|
|
849
|
+
const result = invoke()
|
|
850
|
+
|
|
848
851
|
// Forward the latest state of the internal request headers
|
|
849
852
|
// because the interceptor might have modified them
|
|
850
853
|
// without responding to the request.
|
|
@@ -852,7 +855,16 @@ export class XMLHttpRequestController {
|
|
|
852
855
|
case 'append':
|
|
853
856
|
case 'set': {
|
|
854
857
|
const [headerName, headerValue] = args as [string, string]
|
|
855
|
-
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* @note Forward only the headers the Fetch API Request accepted.
|
|
861
|
+
* Forbidden request headers (e.g. "Cookie") are dropped silently
|
|
862
|
+
* by the request's headers guard, and forwarding them makes
|
|
863
|
+
* the browser refuse them with an error in the console.
|
|
864
|
+
*/
|
|
865
|
+
if (headers.has(headerName)) {
|
|
866
|
+
this.request.setRequestHeader(headerName, headerValue)
|
|
867
|
+
}
|
|
856
868
|
break
|
|
857
869
|
}
|
|
858
870
|
|
|
@@ -865,7 +877,7 @@ export class XMLHttpRequestController {
|
|
|
865
877
|
}
|
|
866
878
|
}
|
|
867
879
|
|
|
868
|
-
return
|
|
880
|
+
return result
|
|
869
881
|
},
|
|
870
882
|
})
|
|
871
883
|
define(fetchRequest, 'headers', proxyHeaders)
|
|
@@ -790,6 +790,24 @@ export class NodeHttpRequestSource extends Interceptor<HttpRequestEventMap> {
|
|
|
790
790
|
|
|
791
791
|
visitedHeaders.clear()
|
|
792
792
|
|
|
793
|
+
/**
|
|
794
|
+
* @note Remove the headers deleted from the request (e.g. via
|
|
795
|
+
* `request.headers.delete()`). The raw headers start as a copy of
|
|
796
|
+
* the outgoing HTTP message headers and track every mutation, so a
|
|
797
|
+
* header present in the message but absent from the raw headers has
|
|
798
|
+
* been deleted. Forbidden headers stripped from `request.headers`
|
|
799
|
+
* remain in the raw headers and are preserved as-is.
|
|
800
|
+
*/
|
|
801
|
+
const rawHeaderNames = new Set(
|
|
802
|
+
requestRawHeaders.map(([headerName]) => headerName.toLowerCase())
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
for (const [headerName] of httpMessageRawHeaders) {
|
|
806
|
+
if (!rawHeaderNames.has(headerName.toLowerCase())) {
|
|
807
|
+
httpMessageHeaders.delete(headerName)
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
793
811
|
const httpMessageHeadersString = Array.from(httpMessageHeaders)
|
|
794
812
|
.map(([name, value]) => `${name}: ${value}`)
|
|
795
813
|
.join('\r\n')
|