(body2, allowH2)
| 14354 | const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?"; |
| 14355 | return dispatchWithProtocolPreference(body); |
| 14356 | function dispatchWithProtocolPreference(body2, allowH2) { |
| 14357 | return new Promise((resolve, reject) => agent.dispatch( |
| 14358 | { |
| 14359 | path: hasTrailingQuestionMark ? `${path}?` : path, |
| 14360 | origin: url.origin, |
| 14361 | method: request.method, |
| 14362 | body: agent.isMockActive ? request.body && (request.body.source || request.body.stream) : body2, |
| 14363 | // Preserve the serialized fetch body for MockAgent net-connect fallthroughs. |
| 14364 | __mockAgentBodyForDispatch: body2, |
| 14365 | headers: request.headersList.entries, |
| 14366 | maxRedirections: 0, |
| 14367 | upgrade: request.mode === "websocket" ? "websocket" : void 0, |
| 14368 | ...allowH2 === false ? { allowH2 } : null |
| 14369 | }, |
| 14370 | { |
| 14371 | body: null, |
| 14372 | abort: null, |
| 14373 | onRequestStart(controller) { |
| 14374 | const { connection } = fetchParams.controller; |
| 14375 | timingInfo.finalConnectionTimingInfo = clampAndCoarsenConnectionTimingInfo(void 0, timingInfo.postRedirectStartTime, fetchParams.crossOriginIsolatedCapability); |
| 14376 | const abort = /* @__PURE__ */ __name((reason) => controller.abort(reason), "abort"); |
| 14377 | if (connection.destroyed) { |
| 14378 | abort(new DOMException("The operation was aborted.", "AbortError")); |
| 14379 | } else { |
| 14380 | fetchParams.controller.on("terminated", abort); |
| 14381 | this.abort = connection.abort = abort; |
| 14382 | } |
| 14383 | timingInfo.finalNetworkRequestStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); |
| 14384 | }, |
| 14385 | onResponseStarted() { |
| 14386 | timingInfo.finalNetworkResponseStartTime = coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability); |
| 14387 | }, |
| 14388 | onResponseStart(controller, status, headers, statusText) { |
| 14389 | if (status < 200) { |
| 14390 | return; |
| 14391 | } |
| 14392 | const rawHeaders = controller?.rawHeaders ?? []; |
| 14393 | const headersList = new HeadersList(); |
| 14394 | appendHeadersListFromResponseHeaders(headersList, headers, rawHeaders); |
| 14395 | const location = headersList.get("location", true); |
| 14396 | this.body = new Readable({ read: /* @__PURE__ */ __name(() => controller.resume(), "read") }); |
| 14397 | const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); |
| 14398 | const decoders = []; |
| 14399 | if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { |
| 14400 | const contentEncoding = headersList.get("content-encoding", true); |
| 14401 | const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; |
| 14402 | const maxContentEncodings = 5; |
| 14403 | if (codings.length > maxContentEncodings) { |
| 14404 | reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); |
| 14405 | return; |
| 14406 | } |
| 14407 | for (let i = codings.length - 1; i >= 0; --i) { |
| 14408 | const coding = codings[i].trim(); |
| 14409 | if (coding === "x-gzip" || coding === "gzip") { |
| 14410 | decoders.push(zlib.createGunzip({ |
| 14411 | // Be less strict when decoding compressed responses, since sometimes |
| 14412 | // servers send slightly invalid responses that are still accepted |
| 14413 | // by common browsers. |
no test coverage detected