@psnext/slingcli 2.4.20260528-1 → 2.4.20260601-1
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/node_modules/@aws-sdk/core/package.json +3 -3
- package/node_modules/@aws-sdk/credential-provider-env/package.json +3 -3
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/LICENSE +201 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/README.md +9 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-cjs/index.js +888 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +19 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/constants.js +1 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +9 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/http2/ClientHttp2SessionRef.js +50 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/index.js +3 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +240 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +136 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +46 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +172 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +36 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +21 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +22 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +23 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +8 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +41 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/timing.js +4 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +63 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +10 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +5 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +4 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/http2/ClientHttp2SessionRef.d.ts +46 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +3 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +47 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +46 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +36 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +76 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +6 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +6 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +2 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +5 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +7 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +9 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +12 -0
- package/node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/node-http-handler/package.json +66 -0
- package/node_modules/@aws-sdk/credential-provider-http/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-ini/package.json +11 -11
- package/node_modules/@aws-sdk/credential-provider-login/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-node/package.json +9 -9
- package/node_modules/@aws-sdk/credential-provider-process/package.json +3 -3
- package/node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers/package.json +4 -4
- package/node_modules/@aws-sdk/credential-provider-sso/package.json +5 -5
- package/node_modules/@aws-sdk/credential-provider-web-identity/package.json +4 -4
- package/node_modules/@aws-sdk/eventstream-handler-node/package.json +2 -2
- package/node_modules/@aws-sdk/middleware-eventstream/package.json +2 -2
- package/node_modules/@aws-sdk/middleware-websocket/package.json +5 -5
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/cognito-identity/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js +1 -1
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/LICENSE +201 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/README.md +9 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-cjs/index.js +888 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +19 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/constants.js +1 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +9 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/http2/ClientHttp2SessionRef.js +50 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/index.js +3 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +240 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +136 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +46 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +172 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +36 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +21 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +22 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +23 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +8 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +41 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/timing.js +4 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +63 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +10 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +5 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +4 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/http2/ClientHttp2SessionRef.d.ts +46 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +3 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +47 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +46 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +36 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +76 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +6 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +6 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +2 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +5 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +7 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +9 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +12 -0
- package/node_modules/@aws-sdk/nested-clients/node_modules/@smithy/node-http-handler/package.json +66 -0
- package/node_modules/@aws-sdk/nested-clients/package.json +6 -6
- package/node_modules/@aws-sdk/signature-v4-multi-region/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +542 -339
- package/node_modules/@smithy/credential-provider-imds/dist-cjs/index.js +14 -13
- package/node_modules/@smithy/credential-provider-imds/dist-es/fromContainerMetadata.js +14 -13
- package/node_modules/@smithy/credential-provider-imds/package.json +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.js +7 -5
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +7 -5
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +1 -1
- package/node_modules/protobufjs/src/converter.js +4 -2
- package/node_modules/protobufjs/src/roots.js +1 -1
- package/node_modules/undici/lib/global.js +10 -1
- package/node_modules/undici/package.json +1 -1
- package/package.json +2 -2
- package/slingshot/index.js +139 -139
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function buildAbortError(abortSignal) {
|
|
2
|
+
const reason = abortSignal && typeof abortSignal === "object" && "reason" in abortSignal
|
|
3
|
+
? abortSignal.reason
|
|
4
|
+
: undefined;
|
|
5
|
+
if (reason) {
|
|
6
|
+
if (reason instanceof Error) {
|
|
7
|
+
const abortError = new Error("Request aborted");
|
|
8
|
+
abortError.name = "AbortError";
|
|
9
|
+
abortError.cause = reason;
|
|
10
|
+
return abortError;
|
|
11
|
+
}
|
|
12
|
+
const abortError = new Error(String(reason));
|
|
13
|
+
abortError.name = "AbortError";
|
|
14
|
+
return abortError;
|
|
15
|
+
}
|
|
16
|
+
const abortError = new Error("Request aborted");
|
|
17
|
+
abortError.name = "AbortError";
|
|
18
|
+
return abortError;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const NODEJS_TIMEOUT_ERROR_CODES = ["ECONNRESET", "EPIPE", "ETIMEDOUT"];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const getTransformedHeaders = (headers) => {
|
|
2
|
+
const transformedHeaders = {};
|
|
3
|
+
for (const name in headers) {
|
|
4
|
+
const headerValues = headers[name];
|
|
5
|
+
transformedHeaders[name] = Array.isArray(headerValues) ? headerValues.join(",") : headerValues;
|
|
6
|
+
}
|
|
7
|
+
return transformedHeaders;
|
|
8
|
+
};
|
|
9
|
+
export { getTransformedHeaders };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const ids = new Uint16Array(1);
|
|
2
|
+
export class ClientHttp2SessionRef {
|
|
3
|
+
id = ids[0]++;
|
|
4
|
+
total = 0;
|
|
5
|
+
max = 0;
|
|
6
|
+
session;
|
|
7
|
+
refs = 0;
|
|
8
|
+
constructor(session) {
|
|
9
|
+
session.unref();
|
|
10
|
+
this.session = session;
|
|
11
|
+
}
|
|
12
|
+
retain() {
|
|
13
|
+
if (this.session.destroyed) {
|
|
14
|
+
throw new Error("@smithy/node-http-handler - cannot acquire reference to destroyed session.");
|
|
15
|
+
}
|
|
16
|
+
this.refs += 1;
|
|
17
|
+
this.total += 1;
|
|
18
|
+
this.max = Math.max(this.refs, this.max);
|
|
19
|
+
this.session.ref();
|
|
20
|
+
}
|
|
21
|
+
free() {
|
|
22
|
+
if (this.session.destroyed) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.refs -= 1;
|
|
26
|
+
if (this.refs === 0) {
|
|
27
|
+
this.session.unref();
|
|
28
|
+
}
|
|
29
|
+
if (this.refs < 0) {
|
|
30
|
+
throw new Error("@smithy/node-http-handler - ClientHttp2Session refcount at zero, cannot decrement.");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
deref() {
|
|
34
|
+
return this.session;
|
|
35
|
+
}
|
|
36
|
+
close() {
|
|
37
|
+
if (!this.session.closed) {
|
|
38
|
+
this.session.close();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
destroy() {
|
|
42
|
+
this.refs = 0;
|
|
43
|
+
if (!this.session.destroyed) {
|
|
44
|
+
this.session.destroy();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
useCount() {
|
|
48
|
+
return this.refs;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Agent as hsAgent, request as hsRequest } from "node:https";
|
|
2
|
+
import { HttpResponse, buildQueryString } from "@smithy/core/protocols";
|
|
3
|
+
import { buildAbortError } from "./build-abort-error";
|
|
4
|
+
import { NODEJS_TIMEOUT_ERROR_CODES } from "./constants";
|
|
5
|
+
import { getTransformedHeaders } from "./get-transformed-headers";
|
|
6
|
+
import { setConnectionTimeout } from "./set-connection-timeout";
|
|
7
|
+
import { setRequestTimeout } from "./set-request-timeout";
|
|
8
|
+
import { setSocketKeepAlive } from "./set-socket-keep-alive";
|
|
9
|
+
import { setSocketTimeout } from "./set-socket-timeout";
|
|
10
|
+
import { timing } from "./timing";
|
|
11
|
+
import { writeRequestBody } from "./write-request-body";
|
|
12
|
+
export const DEFAULT_REQUEST_TIMEOUT = 0;
|
|
13
|
+
let hAgent = undefined;
|
|
14
|
+
let hRequest = undefined;
|
|
15
|
+
export class NodeHttpHandler {
|
|
16
|
+
config;
|
|
17
|
+
configProvider;
|
|
18
|
+
socketWarningTimestamp = 0;
|
|
19
|
+
externalAgent = false;
|
|
20
|
+
metadata = { handlerProtocol: "http/1.1" };
|
|
21
|
+
static create(instanceOrOptions) {
|
|
22
|
+
if (typeof instanceOrOptions?.handle === "function") {
|
|
23
|
+
return instanceOrOptions;
|
|
24
|
+
}
|
|
25
|
+
return new NodeHttpHandler(instanceOrOptions);
|
|
26
|
+
}
|
|
27
|
+
static checkSocketUsage(agent, socketWarningTimestamp, logger = console) {
|
|
28
|
+
const { sockets, requests, maxSockets } = agent;
|
|
29
|
+
if (typeof maxSockets !== "number" || maxSockets === Infinity) {
|
|
30
|
+
return socketWarningTimestamp;
|
|
31
|
+
}
|
|
32
|
+
const interval = 15_000;
|
|
33
|
+
if (Date.now() - interval < socketWarningTimestamp) {
|
|
34
|
+
return socketWarningTimestamp;
|
|
35
|
+
}
|
|
36
|
+
if (sockets && requests) {
|
|
37
|
+
for (const origin in sockets) {
|
|
38
|
+
const socketsInUse = sockets[origin]?.length ?? 0;
|
|
39
|
+
const requestsEnqueued = requests[origin]?.length ?? 0;
|
|
40
|
+
if (socketsInUse >= maxSockets && requestsEnqueued >= 2 * maxSockets) {
|
|
41
|
+
logger?.warn?.(`@smithy/node-http-handler:WARN - socket usage at capacity=${socketsInUse} and ${requestsEnqueued} additional requests are enqueued.
|
|
42
|
+
See https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-configuring-maxsockets.html
|
|
43
|
+
or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler config.`);
|
|
44
|
+
return Date.now();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return socketWarningTimestamp;
|
|
49
|
+
}
|
|
50
|
+
constructor(options) {
|
|
51
|
+
this.configProvider = new Promise((resolve, reject) => {
|
|
52
|
+
if (typeof options === "function") {
|
|
53
|
+
options()
|
|
54
|
+
.then((_options) => {
|
|
55
|
+
resolve(this.resolveDefaultConfig(_options));
|
|
56
|
+
})
|
|
57
|
+
.catch(reject);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
resolve(this.resolveDefaultConfig(options));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
destroy() {
|
|
65
|
+
this.config?.httpAgent?.destroy();
|
|
66
|
+
this.config?.httpsAgent?.destroy();
|
|
67
|
+
}
|
|
68
|
+
async handle(request, { abortSignal, requestTimeout } = {}) {
|
|
69
|
+
if (!this.config) {
|
|
70
|
+
this.config = await this.configProvider;
|
|
71
|
+
}
|
|
72
|
+
const config = this.config;
|
|
73
|
+
const isSSL = request.protocol === "https:";
|
|
74
|
+
if (!isSSL && !this.config.httpAgent) {
|
|
75
|
+
this.config.httpAgent = await this.config.httpAgentProvider();
|
|
76
|
+
}
|
|
77
|
+
return new Promise((_resolve, _reject) => {
|
|
78
|
+
let writeRequestBodyPromise = undefined;
|
|
79
|
+
let socketWarningTimeoutId = -1;
|
|
80
|
+
let connectionTimeoutId = -1;
|
|
81
|
+
let requestTimeoutId = -1;
|
|
82
|
+
let socketTimeoutId = -1;
|
|
83
|
+
let keepAliveTimeoutId = -1;
|
|
84
|
+
const clearTimeouts = () => {
|
|
85
|
+
timing.clearTimeout(socketWarningTimeoutId);
|
|
86
|
+
timing.clearTimeout(connectionTimeoutId);
|
|
87
|
+
timing.clearTimeout(requestTimeoutId);
|
|
88
|
+
timing.clearTimeout(socketTimeoutId);
|
|
89
|
+
timing.clearTimeout(keepAliveTimeoutId);
|
|
90
|
+
};
|
|
91
|
+
const resolve = async (arg) => {
|
|
92
|
+
await writeRequestBodyPromise;
|
|
93
|
+
clearTimeouts();
|
|
94
|
+
_resolve(arg);
|
|
95
|
+
};
|
|
96
|
+
const reject = async (arg) => {
|
|
97
|
+
await writeRequestBodyPromise;
|
|
98
|
+
clearTimeouts();
|
|
99
|
+
_reject(arg);
|
|
100
|
+
};
|
|
101
|
+
if (abortSignal?.aborted) {
|
|
102
|
+
const abortError = buildAbortError(abortSignal);
|
|
103
|
+
reject(abortError);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const headers = request.headers;
|
|
107
|
+
const expectContinue = headers ? (headers.Expect ?? headers.expect) === "100-continue" : false;
|
|
108
|
+
let agent = isSSL ? config.httpsAgent : config.httpAgent;
|
|
109
|
+
if (expectContinue && !this.externalAgent) {
|
|
110
|
+
agent = new (isSSL ? hsAgent : hAgent)({
|
|
111
|
+
keepAlive: false,
|
|
112
|
+
maxSockets: Infinity,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
socketWarningTimeoutId = timing.setTimeout(() => {
|
|
116
|
+
this.socketWarningTimestamp = NodeHttpHandler.checkSocketUsage(agent, this.socketWarningTimestamp, config.logger);
|
|
117
|
+
}, config.socketAcquisitionWarningTimeout ?? (config.requestTimeout ?? 2000) + (config.connectionTimeout ?? 1000));
|
|
118
|
+
const queryString = request.query ? buildQueryString(request.query) : "";
|
|
119
|
+
let auth = undefined;
|
|
120
|
+
if (request.username != null || request.password != null) {
|
|
121
|
+
const username = request.username ?? "";
|
|
122
|
+
const password = request.password ?? "";
|
|
123
|
+
auth = `${username}:${password}`;
|
|
124
|
+
}
|
|
125
|
+
let path = request.path;
|
|
126
|
+
if (queryString) {
|
|
127
|
+
path += `?${queryString}`;
|
|
128
|
+
}
|
|
129
|
+
if (request.fragment) {
|
|
130
|
+
path += `#${request.fragment}`;
|
|
131
|
+
}
|
|
132
|
+
let hostname = request.hostname ?? "";
|
|
133
|
+
if (hostname[0] === "[" && hostname.endsWith("]")) {
|
|
134
|
+
hostname = request.hostname.slice(1, -1);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
hostname = request.hostname;
|
|
138
|
+
}
|
|
139
|
+
const nodeHttpsOptions = {
|
|
140
|
+
headers: request.headers,
|
|
141
|
+
host: hostname,
|
|
142
|
+
method: request.method,
|
|
143
|
+
path,
|
|
144
|
+
port: request.port,
|
|
145
|
+
agent,
|
|
146
|
+
auth,
|
|
147
|
+
};
|
|
148
|
+
const requestFunc = isSSL ? hsRequest : hRequest;
|
|
149
|
+
const req = requestFunc(nodeHttpsOptions, (res) => {
|
|
150
|
+
const httpResponse = new HttpResponse({
|
|
151
|
+
statusCode: res.statusCode || -1,
|
|
152
|
+
reason: res.statusMessage,
|
|
153
|
+
headers: getTransformedHeaders(res.headers),
|
|
154
|
+
body: res,
|
|
155
|
+
});
|
|
156
|
+
resolve({ response: httpResponse });
|
|
157
|
+
});
|
|
158
|
+
req.on("error", (err) => {
|
|
159
|
+
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
160
|
+
reject(Object.assign(err, { name: "TimeoutError" }));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
reject(err);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
if (abortSignal) {
|
|
167
|
+
const onAbort = () => {
|
|
168
|
+
req.destroy();
|
|
169
|
+
const abortError = buildAbortError(abortSignal);
|
|
170
|
+
reject(abortError);
|
|
171
|
+
};
|
|
172
|
+
if (typeof abortSignal.addEventListener === "function") {
|
|
173
|
+
const signal = abortSignal;
|
|
174
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
175
|
+
req.once("close", () => signal.removeEventListener("abort", onAbort));
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
abortSignal.onabort = onAbort;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const effectiveRequestTimeout = requestTimeout ?? config.requestTimeout;
|
|
182
|
+
connectionTimeoutId = setConnectionTimeout(req, reject, config.connectionTimeout);
|
|
183
|
+
requestTimeoutId = setRequestTimeout(req, reject, effectiveRequestTimeout, config.throwOnRequestTimeout, config.logger ?? console);
|
|
184
|
+
socketTimeoutId = setSocketTimeout(req, reject, config.socketTimeout);
|
|
185
|
+
const httpAgent = nodeHttpsOptions.agent;
|
|
186
|
+
if (typeof httpAgent === "object" && "keepAlive" in httpAgent) {
|
|
187
|
+
keepAliveTimeoutId = setSocketKeepAlive(req, {
|
|
188
|
+
keepAlive: httpAgent.keepAlive,
|
|
189
|
+
keepAliveMsecs: httpAgent.keepAliveMsecs,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
writeRequestBodyPromise = writeRequestBody(req, request, effectiveRequestTimeout, this.externalAgent).catch((e) => {
|
|
193
|
+
clearTimeouts();
|
|
194
|
+
return _reject(e);
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
updateHttpClientConfig(key, value) {
|
|
199
|
+
this.config = undefined;
|
|
200
|
+
this.configProvider = this.configProvider.then((config) => {
|
|
201
|
+
return {
|
|
202
|
+
...config,
|
|
203
|
+
[key]: value,
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
httpHandlerConfigs() {
|
|
208
|
+
return this.config ?? {};
|
|
209
|
+
}
|
|
210
|
+
resolveDefaultConfig(options) {
|
|
211
|
+
const { requestTimeout, connectionTimeout, socketTimeout, socketAcquisitionWarningTimeout, httpAgent, httpsAgent, throwOnRequestTimeout, logger, } = options || {};
|
|
212
|
+
const keepAlive = true;
|
|
213
|
+
const maxSockets = 50;
|
|
214
|
+
return {
|
|
215
|
+
connectionTimeout,
|
|
216
|
+
requestTimeout,
|
|
217
|
+
socketTimeout,
|
|
218
|
+
socketAcquisitionWarningTimeout,
|
|
219
|
+
throwOnRequestTimeout,
|
|
220
|
+
httpAgentProvider: async () => {
|
|
221
|
+
const { Agent, request } = await import("node:http");
|
|
222
|
+
hRequest = request;
|
|
223
|
+
hAgent = Agent;
|
|
224
|
+
if (httpAgent instanceof hAgent || typeof httpAgent?.destroy === "function") {
|
|
225
|
+
this.externalAgent = true;
|
|
226
|
+
return httpAgent;
|
|
227
|
+
}
|
|
228
|
+
return new hAgent({ keepAlive, maxSockets, ...httpAgent });
|
|
229
|
+
},
|
|
230
|
+
httpsAgent: (() => {
|
|
231
|
+
if (httpsAgent instanceof hsAgent || typeof httpsAgent?.destroy === "function") {
|
|
232
|
+
this.externalAgent = true;
|
|
233
|
+
return httpsAgent;
|
|
234
|
+
}
|
|
235
|
+
return new hsAgent({ keepAlive, maxSockets, ...httpsAgent });
|
|
236
|
+
})(),
|
|
237
|
+
logger,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import http2 from "node:http2";
|
|
2
|
+
import { ClientHttp2SessionRef } from "./http2/ClientHttp2SessionRef";
|
|
3
|
+
import { NodeHttp2ConnectionPool } from "./node-http2-connection-pool";
|
|
4
|
+
export class NodeHttp2ConnectionManager {
|
|
5
|
+
config;
|
|
6
|
+
connectOptions;
|
|
7
|
+
connectionPools = new Map();
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
if (this.config.maxConcurrency && this.config.maxConcurrency <= 0) {
|
|
11
|
+
throw new RangeError("maxConcurrency must be greater than zero.");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
lease(requestContext, connectionConfiguration) {
|
|
15
|
+
const url = this.getUrlString(requestContext);
|
|
16
|
+
const pool = this.getPool(url);
|
|
17
|
+
if (!this.config.disableConcurrency && !connectionConfiguration.isEventStream) {
|
|
18
|
+
const available = pool.poll();
|
|
19
|
+
if (available) {
|
|
20
|
+
available.retain();
|
|
21
|
+
return available;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const ref = new ClientHttp2SessionRef(this.connect(url));
|
|
25
|
+
const session = ref.deref();
|
|
26
|
+
if (this.config.maxConcurrency) {
|
|
27
|
+
session.settings({ maxConcurrentStreams: this.config.maxConcurrency }, (err) => {
|
|
28
|
+
if (err) {
|
|
29
|
+
throw new Error("Fail to set maxConcurrentStreams to " +
|
|
30
|
+
this.config.maxConcurrency +
|
|
31
|
+
"when creating new session for " +
|
|
32
|
+
requestContext.destination.toString());
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const graceful = () => {
|
|
37
|
+
this.removeFromPoolAndClose(url, ref);
|
|
38
|
+
};
|
|
39
|
+
const ensureDestroyed = () => {
|
|
40
|
+
this.removeFromPoolAndCheckedDestroy(url, ref);
|
|
41
|
+
};
|
|
42
|
+
session.on("goaway", graceful);
|
|
43
|
+
session.on("error", ensureDestroyed);
|
|
44
|
+
session.on("frameError", ensureDestroyed);
|
|
45
|
+
session.on("close", ensureDestroyed);
|
|
46
|
+
if (connectionConfiguration.requestTimeout) {
|
|
47
|
+
session.setTimeout(connectionConfiguration.requestTimeout, ensureDestroyed);
|
|
48
|
+
}
|
|
49
|
+
pool.offerLast(ref);
|
|
50
|
+
ref.retain();
|
|
51
|
+
return ref;
|
|
52
|
+
}
|
|
53
|
+
release(_requestContext, ref) {
|
|
54
|
+
ref.free();
|
|
55
|
+
}
|
|
56
|
+
createIsolatedSession(requestContext, connectionConfiguration) {
|
|
57
|
+
const url = this.getUrlString(requestContext);
|
|
58
|
+
const ref = new ClientHttp2SessionRef(this.connect(url));
|
|
59
|
+
const session = ref.deref();
|
|
60
|
+
session.settings({ maxConcurrentStreams: 1 });
|
|
61
|
+
const ensureDestroyed = () => {
|
|
62
|
+
ref.destroy();
|
|
63
|
+
};
|
|
64
|
+
session.on("error", ensureDestroyed);
|
|
65
|
+
session.on("frameError", ensureDestroyed);
|
|
66
|
+
session.on("close", ensureDestroyed);
|
|
67
|
+
if (connectionConfiguration.requestTimeout) {
|
|
68
|
+
session.setTimeout(connectionConfiguration.requestTimeout, ensureDestroyed);
|
|
69
|
+
}
|
|
70
|
+
ref.retain();
|
|
71
|
+
return ref;
|
|
72
|
+
}
|
|
73
|
+
destroy() {
|
|
74
|
+
for (const [url, connectionPool] of this.connectionPools) {
|
|
75
|
+
for (const session of [...connectionPool]) {
|
|
76
|
+
session.destroy();
|
|
77
|
+
}
|
|
78
|
+
this.connectionPools.delete(url);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
setMaxConcurrentStreams(maxConcurrentStreams) {
|
|
82
|
+
if (maxConcurrentStreams && maxConcurrentStreams <= 0) {
|
|
83
|
+
throw new RangeError("maxConcurrentStreams must be greater than zero.");
|
|
84
|
+
}
|
|
85
|
+
this.config.maxConcurrency = maxConcurrentStreams;
|
|
86
|
+
for (const pool of this.connectionPools.values()) {
|
|
87
|
+
pool.setMaxConcurrency(maxConcurrentStreams);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
setDisableConcurrentStreams(disableConcurrentStreams) {
|
|
91
|
+
this.config.disableConcurrency = disableConcurrentStreams;
|
|
92
|
+
}
|
|
93
|
+
setNodeHttp2ConnectOptions(nodeHttp2ConnectOptions) {
|
|
94
|
+
this.connectOptions = nodeHttp2ConnectOptions;
|
|
95
|
+
}
|
|
96
|
+
debug() {
|
|
97
|
+
const pools = {};
|
|
98
|
+
for (const [url, pool] of this.connectionPools) {
|
|
99
|
+
const sessions = [];
|
|
100
|
+
for (const ref of pool) {
|
|
101
|
+
sessions.push({
|
|
102
|
+
id: ref.id,
|
|
103
|
+
active: ref.useCount(),
|
|
104
|
+
maxConcurrent: ref.max,
|
|
105
|
+
totalRequests: ref.total,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
pools[url] = { sessions };
|
|
109
|
+
}
|
|
110
|
+
return pools;
|
|
111
|
+
}
|
|
112
|
+
removeFromPoolAndClose(authority, ref) {
|
|
113
|
+
this.connectionPools.get(authority)?.remove(ref);
|
|
114
|
+
ref.close();
|
|
115
|
+
}
|
|
116
|
+
removeFromPoolAndCheckedDestroy(authority, ref) {
|
|
117
|
+
this.connectionPools.get(authority)?.remove(ref);
|
|
118
|
+
ref.destroy();
|
|
119
|
+
}
|
|
120
|
+
getPool(url) {
|
|
121
|
+
if (!this.connectionPools.has(url)) {
|
|
122
|
+
const pool = new NodeHttp2ConnectionPool();
|
|
123
|
+
if (this.config.maxConcurrency) {
|
|
124
|
+
pool.setMaxConcurrency(this.config.maxConcurrency);
|
|
125
|
+
}
|
|
126
|
+
this.connectionPools.set(url, pool);
|
|
127
|
+
}
|
|
128
|
+
return this.connectionPools.get(url);
|
|
129
|
+
}
|
|
130
|
+
getUrlString(request) {
|
|
131
|
+
return request.destination.toString();
|
|
132
|
+
}
|
|
133
|
+
connect(url) {
|
|
134
|
+
return this.connectOptions === undefined ? http2.connect(url) : http2.connect(url, this.connectOptions);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ClientHttp2SessionRef } from "./http2/ClientHttp2SessionRef";
|
|
2
|
+
export class NodeHttp2ConnectionPool {
|
|
3
|
+
sessions = [];
|
|
4
|
+
maxConcurrency = 0;
|
|
5
|
+
constructor(sessions) {
|
|
6
|
+
this.sessions = (sessions ?? []).map((session) => new ClientHttp2SessionRef(session));
|
|
7
|
+
}
|
|
8
|
+
poll() {
|
|
9
|
+
let cleanup = false;
|
|
10
|
+
for (const session of this.sessions) {
|
|
11
|
+
if (session.deref().destroyed) {
|
|
12
|
+
cleanup = true;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (!this.maxConcurrency || session.useCount() < this.maxConcurrency) {
|
|
16
|
+
return session;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (cleanup) {
|
|
20
|
+
for (const session of this.sessions) {
|
|
21
|
+
if (session.deref().destroyed) {
|
|
22
|
+
this.remove(session);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
offerLast(ref) {
|
|
28
|
+
this.sessions.push(ref);
|
|
29
|
+
}
|
|
30
|
+
remove(ref) {
|
|
31
|
+
const ix = this.sessions.indexOf(ref);
|
|
32
|
+
if (ix > -1) {
|
|
33
|
+
this.sessions.splice(ix, 1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
[Symbol.iterator]() {
|
|
37
|
+
return this.sessions[Symbol.iterator]();
|
|
38
|
+
}
|
|
39
|
+
setMaxConcurrency(maxConcurrency) {
|
|
40
|
+
this.maxConcurrency = maxConcurrency;
|
|
41
|
+
}
|
|
42
|
+
destroy(ref) {
|
|
43
|
+
this.remove(ref);
|
|
44
|
+
ref.destroy();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { constants } from "node:http2";
|
|
2
|
+
import { HttpResponse, buildQueryString } from "@smithy/core/protocols";
|
|
3
|
+
import { buildAbortError } from "./build-abort-error";
|
|
4
|
+
import { getTransformedHeaders } from "./get-transformed-headers";
|
|
5
|
+
import { NodeHttp2ConnectionManager } from "./node-http2-connection-manager";
|
|
6
|
+
import { writeRequestBody } from "./write-request-body";
|
|
7
|
+
export class NodeHttp2Handler {
|
|
8
|
+
config;
|
|
9
|
+
configProvider;
|
|
10
|
+
metadata = { handlerProtocol: "h2" };
|
|
11
|
+
connectionManager = new NodeHttp2ConnectionManager({});
|
|
12
|
+
static create(instanceOrOptions) {
|
|
13
|
+
if (typeof instanceOrOptions?.handle === "function") {
|
|
14
|
+
return instanceOrOptions;
|
|
15
|
+
}
|
|
16
|
+
return new NodeHttp2Handler(instanceOrOptions);
|
|
17
|
+
}
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.configProvider = new Promise((resolve, reject) => {
|
|
20
|
+
if (typeof options === "function") {
|
|
21
|
+
options()
|
|
22
|
+
.then((opts) => {
|
|
23
|
+
resolve(opts || {});
|
|
24
|
+
})
|
|
25
|
+
.catch(reject);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
resolve(options || {});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
destroy() {
|
|
33
|
+
this.connectionManager.destroy();
|
|
34
|
+
}
|
|
35
|
+
async handle(request, { abortSignal, requestTimeout, isEventStream } = {}) {
|
|
36
|
+
if (!this.config) {
|
|
37
|
+
this.config = await this.configProvider;
|
|
38
|
+
const { disableConcurrentStreams, maxConcurrentStreams, nodeHttp2ConnectOptions } = this.config;
|
|
39
|
+
this.connectionManager.setDisableConcurrentStreams(disableConcurrentStreams ?? false);
|
|
40
|
+
if (maxConcurrentStreams) {
|
|
41
|
+
this.connectionManager.setMaxConcurrentStreams(maxConcurrentStreams);
|
|
42
|
+
}
|
|
43
|
+
if (nodeHttp2ConnectOptions) {
|
|
44
|
+
this.connectionManager.setNodeHttp2ConnectOptions(nodeHttp2ConnectOptions);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const { requestTimeout: configRequestTimeout, disableConcurrentStreams } = this.config;
|
|
48
|
+
const useIsolatedSession = disableConcurrentStreams || isEventStream;
|
|
49
|
+
const effectiveRequestTimeout = requestTimeout ?? configRequestTimeout;
|
|
50
|
+
return new Promise((_resolve, _reject) => {
|
|
51
|
+
let fulfilled = false;
|
|
52
|
+
let writeRequestBodyPromise = undefined;
|
|
53
|
+
const resolve = async (arg) => {
|
|
54
|
+
await writeRequestBodyPromise;
|
|
55
|
+
_resolve(arg);
|
|
56
|
+
};
|
|
57
|
+
const reject = async (arg) => {
|
|
58
|
+
await writeRequestBodyPromise;
|
|
59
|
+
_reject(arg);
|
|
60
|
+
};
|
|
61
|
+
if (abortSignal?.aborted) {
|
|
62
|
+
fulfilled = true;
|
|
63
|
+
const abortError = buildAbortError(abortSignal);
|
|
64
|
+
reject(abortError);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const { hostname, method, port, protocol, query } = request;
|
|
68
|
+
let auth = "";
|
|
69
|
+
if (request.username != null || request.password != null) {
|
|
70
|
+
const username = request.username ?? "";
|
|
71
|
+
const password = request.password ?? "";
|
|
72
|
+
auth = `${username}:${password}@`;
|
|
73
|
+
}
|
|
74
|
+
const authority = `${protocol}//${auth}${hostname}${port ? `:${port}` : ""}`;
|
|
75
|
+
const requestContext = { destination: new URL(authority) };
|
|
76
|
+
const connectConfig = {
|
|
77
|
+
requestTimeout: this.config?.sessionTimeout,
|
|
78
|
+
isEventStream,
|
|
79
|
+
};
|
|
80
|
+
const ref = useIsolatedSession
|
|
81
|
+
? this.connectionManager.createIsolatedSession(requestContext, connectConfig)
|
|
82
|
+
: this.connectionManager.lease(requestContext, connectConfig);
|
|
83
|
+
const session = ref.deref();
|
|
84
|
+
const rejectWithDestroy = (err) => {
|
|
85
|
+
if (useIsolatedSession) {
|
|
86
|
+
ref.destroy();
|
|
87
|
+
}
|
|
88
|
+
fulfilled = true;
|
|
89
|
+
reject(err);
|
|
90
|
+
};
|
|
91
|
+
const queryString = query ? buildQueryString(query) : "";
|
|
92
|
+
let path = request.path;
|
|
93
|
+
if (queryString) {
|
|
94
|
+
path += `?${queryString}`;
|
|
95
|
+
}
|
|
96
|
+
if (request.fragment) {
|
|
97
|
+
path += `#${request.fragment}`;
|
|
98
|
+
}
|
|
99
|
+
const clientHttp2Stream = session.request({
|
|
100
|
+
...request.headers,
|
|
101
|
+
[constants.HTTP2_HEADER_PATH]: path,
|
|
102
|
+
[constants.HTTP2_HEADER_METHOD]: method,
|
|
103
|
+
});
|
|
104
|
+
if (effectiveRequestTimeout) {
|
|
105
|
+
clientHttp2Stream.setTimeout(effectiveRequestTimeout, () => {
|
|
106
|
+
clientHttp2Stream.close();
|
|
107
|
+
const timeoutError = new Error(`Stream timed out because of no activity for ${effectiveRequestTimeout} ms`);
|
|
108
|
+
timeoutError.name = "TimeoutError";
|
|
109
|
+
rejectWithDestroy(timeoutError);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if (abortSignal) {
|
|
113
|
+
const onAbort = () => {
|
|
114
|
+
clientHttp2Stream.close();
|
|
115
|
+
const abortError = buildAbortError(abortSignal);
|
|
116
|
+
rejectWithDestroy(abortError);
|
|
117
|
+
};
|
|
118
|
+
if (typeof abortSignal.addEventListener === "function") {
|
|
119
|
+
const signal = abortSignal;
|
|
120
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
121
|
+
clientHttp2Stream.once("close", () => signal.removeEventListener("abort", onAbort));
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
abortSignal.onabort = onAbort;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
clientHttp2Stream.on("frameError", (type, code, id) => {
|
|
128
|
+
rejectWithDestroy(new Error(`Frame type id ${type} in stream id ${id} has failed with code ${code}.`));
|
|
129
|
+
});
|
|
130
|
+
clientHttp2Stream.on("error", rejectWithDestroy);
|
|
131
|
+
clientHttp2Stream.on("aborted", () => {
|
|
132
|
+
rejectWithDestroy(new Error(`HTTP/2 stream is abnormally aborted in mid-communication with result code ${clientHttp2Stream.rstCode}.`));
|
|
133
|
+
});
|
|
134
|
+
clientHttp2Stream.on("response", (headers) => {
|
|
135
|
+
const httpResponse = new HttpResponse({
|
|
136
|
+
statusCode: headers[":status"] ?? -1,
|
|
137
|
+
headers: getTransformedHeaders(headers),
|
|
138
|
+
body: clientHttp2Stream,
|
|
139
|
+
});
|
|
140
|
+
fulfilled = true;
|
|
141
|
+
resolve({ response: httpResponse });
|
|
142
|
+
if (useIsolatedSession) {
|
|
143
|
+
session.close();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
clientHttp2Stream.on("close", () => {
|
|
147
|
+
if (useIsolatedSession) {
|
|
148
|
+
ref.destroy();
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.connectionManager.release(requestContext, ref);
|
|
152
|
+
}
|
|
153
|
+
if (!fulfilled) {
|
|
154
|
+
rejectWithDestroy(new Error("Unexpected error: http2 request did not get a response"));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
writeRequestBodyPromise = writeRequestBody(clientHttp2Stream, request, effectiveRequestTimeout);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
updateHttpClientConfig(key, value) {
|
|
161
|
+
this.config = undefined;
|
|
162
|
+
this.configProvider = this.configProvider.then((config) => {
|
|
163
|
+
return {
|
|
164
|
+
...config,
|
|
165
|
+
[key]: value,
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
httpHandlerConfigs() {
|
|
170
|
+
return this.config ?? {};
|
|
171
|
+
}
|
|
172
|
+
}
|