(attempt, expires, delay, _request, _response)
| 422 | } |
| 423 | } |
| 424 | async #send(attempt, expires, delay, _request, _response) { |
| 425 | if (attempt >= this.#throttle.maxAttempts) { |
| 426 | return _response.makeServerError("exceeded maximum retry limit"); |
| 427 | } |
| 428 | (0, errors_js_1.assert)(getTime() <= expires, "timeout", "TIMEOUT", { |
| 429 | operation: "request.send", reason: "timeout", request: _request |
| 430 | }); |
| 431 | if (delay > 0) { |
| 432 | await wait(delay); |
| 433 | } |
| 434 | let req = this.clone(); |
| 435 | const scheme = (req.url.split(":")[0] || "").toLowerCase(); |
| 436 | // Process any Gateways |
| 437 | if (scheme in Gateways) { |
| 438 | const result = await Gateways[scheme](req.url, checkSignal(_request.#signal)); |
| 439 | if (result instanceof FetchResponse) { |
| 440 | let response = result; |
| 441 | if (this.processFunc) { |
| 442 | checkSignal(_request.#signal); |
| 443 | try { |
| 444 | response = await this.processFunc(req, response); |
| 445 | } |
| 446 | catch (error) { |
| 447 | // Something went wrong during processing; throw a 5xx server error |
| 448 | if (error.throttle == null || typeof (error.stall) !== "number") { |
| 449 | response.makeServerError("error in post-processing function", error).assertOk(); |
| 450 | } |
| 451 | // Ignore throttling |
| 452 | } |
| 453 | } |
| 454 | return response; |
| 455 | } |
| 456 | req = result; |
| 457 | } |
| 458 | // We have a preflight function; update the request |
| 459 | if (this.preflightFunc) { |
| 460 | req = await this.preflightFunc(req); |
| 461 | } |
| 462 | const resp = await this.getUrlFunc(req, checkSignal(_request.#signal)); |
| 463 | let response = new FetchResponse(resp.statusCode, resp.statusMessage, resp.headers, resp.body, _request); |
| 464 | if (response.statusCode === 301 || response.statusCode === 302) { |
| 465 | // Redirect |
| 466 | try { |
| 467 | const location = response.headers.location || ""; |
| 468 | return req.redirect(location).#send(attempt + 1, expires, 0, _request, response); |
| 469 | } |
| 470 | catch (error) { } |
| 471 | // Things won't get any better on another attempt; abort |
| 472 | return response; |
| 473 | } |
| 474 | else if (response.statusCode === 429) { |
| 475 | // Throttle |
| 476 | if (this.retryFunc == null || (await this.retryFunc(req, response, attempt))) { |
| 477 | const retryAfter = response.headers["retry-after"]; |
| 478 | let delay = this.#throttle.slotInterval * Math.trunc(Math.random() * Math.pow(2, attempt)); |
| 479 | if (typeof (retryAfter) === "string" && retryAfter.match(/^[1-9][0-9]*$/)) { |
| 480 | delay = parseInt(retryAfter); |
| 481 | } |
no test coverage detected