1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.NodeHttpHandler = void 0;
|
4 | const protocol_http_1 = require("@aws-sdk/protocol-http");
|
5 | const querystring_builder_1 = require("@aws-sdk/querystring-builder");
|
6 | const http_1 = require("http");
|
7 | const https_1 = require("https");
|
8 | const constants_1 = require("./constants");
|
9 | const get_transformed_headers_1 = require("./get-transformed-headers");
|
10 | const set_connection_timeout_1 = require("./set-connection-timeout");
|
11 | const set_socket_timeout_1 = require("./set-socket-timeout");
|
12 | const write_request_body_1 = require("./write-request-body");
|
13 | class NodeHttpHandler {
|
14 | constructor(options) {
|
15 | this.metadata = { handlerProtocol: "http/1.1" };
|
16 | this.configProvider = new Promise((resolve, reject) => {
|
17 | if (typeof options === "function") {
|
18 | options()
|
19 | .then((_options) => {
|
20 | resolve(this.resolveDefaultConfig(_options));
|
21 | })
|
22 | .catch(reject);
|
23 | }
|
24 | else {
|
25 | resolve(this.resolveDefaultConfig(options));
|
26 | }
|
27 | });
|
28 | }
|
29 | resolveDefaultConfig(options) {
|
30 | const { connectionTimeout, socketTimeout, httpAgent, httpsAgent } = options || {};
|
31 | const keepAlive = true;
|
32 | const maxSockets = 50;
|
33 | return {
|
34 | connectionTimeout,
|
35 | socketTimeout,
|
36 | httpAgent: httpAgent || new http_1.Agent({ keepAlive, maxSockets }),
|
37 | httpsAgent: httpsAgent || new https_1.Agent({ keepAlive, maxSockets }),
|
38 | };
|
39 | }
|
40 | destroy() {
|
41 | var _a, _b, _c, _d;
|
42 | (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.httpAgent) === null || _b === void 0 ? void 0 : _b.destroy();
|
43 | (_d = (_c = this.config) === null || _c === void 0 ? void 0 : _c.httpsAgent) === null || _d === void 0 ? void 0 : _d.destroy();
|
44 | }
|
45 | async handle(request, { abortSignal } = {}) {
|
46 | if (!this.config) {
|
47 | this.config = await this.configProvider;
|
48 | }
|
49 | return new Promise((resolve, reject) => {
|
50 | if (!this.config) {
|
51 | throw new Error("Node HTTP request handler config is not resolved");
|
52 | }
|
53 | if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
|
54 | const abortError = new Error("Request aborted");
|
55 | abortError.name = "AbortError";
|
56 | reject(abortError);
|
57 | return;
|
58 | }
|
59 | const isSSL = request.protocol === "https:";
|
60 | const queryString = (0, querystring_builder_1.buildQueryString)(request.query || {});
|
61 | const nodeHttpsOptions = {
|
62 | headers: request.headers,
|
63 | host: request.hostname,
|
64 | method: request.method,
|
65 | path: queryString ? `${request.path}?${queryString}` : request.path,
|
66 | port: request.port,
|
67 | agent: isSSL ? this.config.httpsAgent : this.config.httpAgent,
|
68 | };
|
69 | const requestFunc = isSSL ? https_1.request : http_1.request;
|
70 | const req = requestFunc(nodeHttpsOptions, (res) => {
|
71 | const httpResponse = new protocol_http_1.HttpResponse({
|
72 | statusCode: res.statusCode || -1,
|
73 | headers: (0, get_transformed_headers_1.getTransformedHeaders)(res.headers),
|
74 | body: res,
|
75 | });
|
76 | resolve({ response: httpResponse });
|
77 | });
|
78 | req.on("error", (err) => {
|
79 | if (constants_1.NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
80 | reject(Object.assign(err, { name: "TimeoutError" }));
|
81 | }
|
82 | else {
|
83 | reject(err);
|
84 | }
|
85 | });
|
86 | (0, set_connection_timeout_1.setConnectionTimeout)(req, reject, this.config.connectionTimeout);
|
87 | (0, set_socket_timeout_1.setSocketTimeout)(req, reject, this.config.socketTimeout);
|
88 | if (abortSignal) {
|
89 | abortSignal.onabort = () => {
|
90 | req.abort();
|
91 | const abortError = new Error("Request aborted");
|
92 | abortError.name = "AbortError";
|
93 | reject(abortError);
|
94 | };
|
95 | }
|
96 | (0, write_request_body_1.writeRequestBody)(req, request);
|
97 | });
|
98 | }
|
99 | }
|
100 | exports.NodeHttpHandler = NodeHttpHandler;
|