@trivikr-test/undici-http-handler 0.1.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/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/undici-http-handler.js +166 -0
- package/dist/cjs/undici-http-handler.js.map +1 -0
- package/dist/cjs/undici-http-handler.spec.js +251 -0
- package/dist/cjs/undici-http-handler.spec.js.map +1 -0
- package/dist/es/index.js +2 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/undici-http-handler.js +162 -0
- package/dist/es/undici-http-handler.js.map +1 -0
- package/dist/es/undici-http-handler.spec.js +249 -0
- package/dist/es/undici-http-handler.spec.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/undici-http-handler.d.ts +63 -0
- package/dist/types/undici-http-handler.spec.d.ts +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Trivikram Kamat
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @trivikr-test/undici-http-handler
|
|
2
|
+
|
|
3
|
+
Test Http Handler which use Node.js undici instead of NodeHttpHandler
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Use UndiciHttpHandler as drop-in replacement for NodeHttpHandler from
|
|
8
|
+
@smithy/node-http-handler, by passing it in requestHandler configuration of client.
|
|
9
|
+
|
|
10
|
+
Example
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import { S3 } from "@aws-sdk/client-s3";
|
|
14
|
+
import { UndiciHttpHandler } from "@trivikr-test/undici-http-handler";
|
|
15
|
+
|
|
16
|
+
const client = new S3({
|
|
17
|
+
requestHandler: new UndiciHttpHandler(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
client.listBuckets().then(console.log);
|
|
21
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UndiciHttpHandler = void 0;
|
|
4
|
+
var undici_http_handler_1 = require("./undici-http-handler");
|
|
5
|
+
Object.defineProperty(exports, "UndiciHttpHandler", { enumerable: true, get: function () { return undici_http_handler_1.UndiciHttpHandler; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,6DAA0D;AAAjD,wHAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UndiciHttpHandler = void 0;
|
|
4
|
+
const protocol_http_1 = require("@smithy/protocol-http");
|
|
5
|
+
const querystring_builder_1 = require("@smithy/querystring-builder");
|
|
6
|
+
const undici_1 = require("undici");
|
|
7
|
+
/**
|
|
8
|
+
* An HTTP handler that uses undici instead of Node.js native http/https modules.
|
|
9
|
+
* Drop-in replacement for `NodeHttpHandler` from `@smithy/node-http-handler`.
|
|
10
|
+
*/
|
|
11
|
+
class UndiciHttpHandler {
|
|
12
|
+
config;
|
|
13
|
+
configProvider;
|
|
14
|
+
dispatcher;
|
|
15
|
+
externalDispatcher = false;
|
|
16
|
+
metadata = { handlerProtocol: "http/1.1" };
|
|
17
|
+
/**
|
|
18
|
+
* Returns the input if it is an HttpHandler of any class,
|
|
19
|
+
* or instantiates a new instance of this handler.
|
|
20
|
+
*/
|
|
21
|
+
static create(instanceOrOptions) {
|
|
22
|
+
if (typeof instanceOrOptions?.handle === "function") {
|
|
23
|
+
return instanceOrOptions;
|
|
24
|
+
}
|
|
25
|
+
return new UndiciHttpHandler(instanceOrOptions);
|
|
26
|
+
}
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.configProvider = new Promise((resolve, reject) => {
|
|
29
|
+
if (typeof options === "function") {
|
|
30
|
+
options()
|
|
31
|
+
.then((_options) => resolve(this.resolveConfig(_options)))
|
|
32
|
+
.catch(reject);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
resolve(this.resolveConfig(options));
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
resolveConfig(options) {
|
|
40
|
+
const resolved = { ...options };
|
|
41
|
+
if (resolved.dispatcher) {
|
|
42
|
+
this.externalDispatcher = true;
|
|
43
|
+
this.dispatcher = resolved.dispatcher;
|
|
44
|
+
}
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
getOrCreateDispatcher(config) {
|
|
48
|
+
if (this.dispatcher) {
|
|
49
|
+
return this.dispatcher;
|
|
50
|
+
}
|
|
51
|
+
const connectTimeout = config.connectionTimeout ?? 0;
|
|
52
|
+
const bodyTimeout = config.requestTimeout ?? 0;
|
|
53
|
+
const headersTimeout = config.requestTimeout ?? 0;
|
|
54
|
+
const connections = config.maxConnectionsPerOrigin ?? 50;
|
|
55
|
+
this.dispatcher = new undici_1.Agent({
|
|
56
|
+
connections,
|
|
57
|
+
bodyTimeout: bodyTimeout || undefined,
|
|
58
|
+
headersTimeout: headersTimeout || undefined,
|
|
59
|
+
connect: {
|
|
60
|
+
timeout: connectTimeout || undefined,
|
|
61
|
+
keepAlive: true,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
return this.dispatcher;
|
|
65
|
+
}
|
|
66
|
+
destroy() {
|
|
67
|
+
if (this.dispatcher && !this.externalDispatcher) {
|
|
68
|
+
this.dispatcher.destroy();
|
|
69
|
+
this.dispatcher = undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async handle(request, { abortSignal, requestTimeout } = {}) {
|
|
73
|
+
if (!this.config) {
|
|
74
|
+
this.config = await this.configProvider;
|
|
75
|
+
}
|
|
76
|
+
const config = this.config;
|
|
77
|
+
const dispatcher = this.getOrCreateDispatcher(config);
|
|
78
|
+
if (abortSignal?.aborted) {
|
|
79
|
+
throw buildAbortError();
|
|
80
|
+
}
|
|
81
|
+
// Build the full URL
|
|
82
|
+
const queryString = (0, querystring_builder_1.buildQueryString)(request.query || {});
|
|
83
|
+
let path = request.path;
|
|
84
|
+
if (queryString) {
|
|
85
|
+
path += `?${queryString}`;
|
|
86
|
+
}
|
|
87
|
+
if (request.fragment) {
|
|
88
|
+
path += `#${request.fragment}`;
|
|
89
|
+
}
|
|
90
|
+
let auth;
|
|
91
|
+
if (request.username != null || request.password != null) {
|
|
92
|
+
const username = request.username ?? "";
|
|
93
|
+
const password = request.password ?? "";
|
|
94
|
+
auth = `${username}:${password}`;
|
|
95
|
+
}
|
|
96
|
+
const port = request.port ? `:${request.port}` : "";
|
|
97
|
+
let origin = `${request.protocol}//${request.hostname}${port}`;
|
|
98
|
+
if (auth) {
|
|
99
|
+
origin = `${request.protocol}//${auth}@${request.hostname}${port}`;
|
|
100
|
+
}
|
|
101
|
+
// undici natively supports string | Buffer | Uint8Array | Readable | AsyncIterable as body.
|
|
102
|
+
// Pass through directly to avoid buffering streams into memory.
|
|
103
|
+
const body = request.body ?? null;
|
|
104
|
+
// Build undici request options
|
|
105
|
+
const effectiveTimeout = requestTimeout ?? config.requestTimeout ?? 0;
|
|
106
|
+
const requestOptions = {
|
|
107
|
+
origin,
|
|
108
|
+
path,
|
|
109
|
+
method: request.method,
|
|
110
|
+
headers: request.headers,
|
|
111
|
+
body,
|
|
112
|
+
headersTimeout: effectiveTimeout || undefined,
|
|
113
|
+
bodyTimeout: effectiveTimeout || undefined,
|
|
114
|
+
signal: abortSignal,
|
|
115
|
+
};
|
|
116
|
+
try {
|
|
117
|
+
const { statusCode, headers: responseHeaders, body: responseBody, } = await dispatcher.request(requestOptions);
|
|
118
|
+
// Transform undici headers (Record<string, string | string[]>) to HeaderBag (Record<string, string>)
|
|
119
|
+
const transformedHeaders = {};
|
|
120
|
+
for (const key in responseHeaders) {
|
|
121
|
+
const value = responseHeaders[key];
|
|
122
|
+
if (value !== undefined) {
|
|
123
|
+
transformedHeaders[key] = Array.isArray(value)
|
|
124
|
+
? value.join(", ")
|
|
125
|
+
: value;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const httpResponse = new protocol_http_1.HttpResponse({
|
|
129
|
+
statusCode,
|
|
130
|
+
headers: transformedHeaders,
|
|
131
|
+
body: responseBody,
|
|
132
|
+
});
|
|
133
|
+
return { response: httpResponse };
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err?.name === "AbortError" || err?.code === "UND_ERR_ABORTED") {
|
|
137
|
+
throw buildAbortError();
|
|
138
|
+
}
|
|
139
|
+
if (err?.code === "UND_ERR_HEADERS_TIMEOUT" ||
|
|
140
|
+
err?.code === "UND_ERR_BODY_TIMEOUT" ||
|
|
141
|
+
err?.code === "UND_ERR_CONNECT_TIMEOUT") {
|
|
142
|
+
throw Object.assign(new Error(`Request timeout: ${err.message}`), {
|
|
143
|
+
name: "TimeoutError",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
updateHttpClientConfig(key, value) {
|
|
150
|
+
this.config = undefined;
|
|
151
|
+
this.configProvider = this.configProvider.then((config) => ({
|
|
152
|
+
...config,
|
|
153
|
+
[key]: value,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
httpHandlerConfigs() {
|
|
157
|
+
return this.config ?? {};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.UndiciHttpHandler = UndiciHttpHandler;
|
|
161
|
+
function buildAbortError() {
|
|
162
|
+
return Object.assign(new Error("Request aborted"), {
|
|
163
|
+
name: "AbortError",
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=undici-http-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undici-http-handler.js","sourceRoot":"","sources":["../../src/undici-http-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const protocol_http_1 = require("@smithy/protocol-http");
|
|
4
|
+
const node_http_1 = require("node:http");
|
|
5
|
+
const vitest_1 = require("vitest");
|
|
6
|
+
const undici_http_handler_1 = require("./undici-http-handler");
|
|
7
|
+
let server;
|
|
8
|
+
let port;
|
|
9
|
+
function createMockRequest(overrides = {}) {
|
|
10
|
+
return Object.assign(new protocol_http_1.HttpRequest({
|
|
11
|
+
protocol: "http:",
|
|
12
|
+
hostname: "localhost",
|
|
13
|
+
port,
|
|
14
|
+
method: "GET",
|
|
15
|
+
path: "/",
|
|
16
|
+
headers: {},
|
|
17
|
+
}), overrides);
|
|
18
|
+
}
|
|
19
|
+
(0, vitest_1.beforeAll)(async () => {
|
|
20
|
+
server = (0, node_http_1.createServer)((req, res) => {
|
|
21
|
+
const url = new URL(req.url, `http://localhost`);
|
|
22
|
+
if (url.pathname === "/delay") {
|
|
23
|
+
const ms = parseInt(url.searchParams.get("ms") ?? "1000", 10);
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
res.writeHead(200, { "content-type": "text/plain" });
|
|
26
|
+
res.end("delayed");
|
|
27
|
+
}, ms);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (url.pathname === "/echo") {
|
|
31
|
+
const chunks = [];
|
|
32
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
33
|
+
req.on("end", () => {
|
|
34
|
+
res.writeHead(200, {
|
|
35
|
+
"content-type": "application/octet-stream",
|
|
36
|
+
"x-method": req.method,
|
|
37
|
+
"x-url": req.url,
|
|
38
|
+
});
|
|
39
|
+
res.end(Buffer.concat(chunks));
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (url.pathname === "/multi-header") {
|
|
44
|
+
// Manually write raw response with duplicate headers
|
|
45
|
+
res.writeHead(200, [
|
|
46
|
+
["set-cookie", "a=1"],
|
|
47
|
+
["set-cookie", "b=2"],
|
|
48
|
+
]);
|
|
49
|
+
res.end("ok");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
res.writeHead(200, { "content-type": "text/plain" });
|
|
53
|
+
res.end("ok");
|
|
54
|
+
});
|
|
55
|
+
await new Promise((resolve) => {
|
|
56
|
+
server.listen(0, "127.0.0.1", () => {
|
|
57
|
+
port = server.address().port;
|
|
58
|
+
resolve();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
(0, vitest_1.afterAll)(async () => {
|
|
63
|
+
await new Promise((resolve, reject) => {
|
|
64
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.describe)("UndiciHttpHandler", () => {
|
|
68
|
+
let handler;
|
|
69
|
+
(0, vitest_1.afterEach)(() => {
|
|
70
|
+
handler?.destroy();
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.describe)("constructor and create", () => {
|
|
73
|
+
(0, vitest_1.it)("creates a new instance with no options", () => {
|
|
74
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
75
|
+
(0, vitest_1.expect)(handler.metadata).toEqual({ handlerProtocol: "http/1.1" });
|
|
76
|
+
});
|
|
77
|
+
(0, vitest_1.it)("creates a new instance with options", () => {
|
|
78
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ requestTimeout: 5000 });
|
|
79
|
+
(0, vitest_1.expect)(handler.metadata).toEqual({ handlerProtocol: "http/1.1" });
|
|
80
|
+
});
|
|
81
|
+
(0, vitest_1.it)("creates a new instance with a provider function", async () => {
|
|
82
|
+
handler = new undici_http_handler_1.UndiciHttpHandler(async () => ({ requestTimeout: 5000 }));
|
|
83
|
+
const { response } = await handler.handle(createMockRequest());
|
|
84
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
85
|
+
});
|
|
86
|
+
(0, vitest_1.it)("static create returns existing HttpHandler instance", () => {
|
|
87
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
88
|
+
const result = undici_http_handler_1.UndiciHttpHandler.create(handler);
|
|
89
|
+
(0, vitest_1.expect)(result).toBe(handler);
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)("static create instantiates from options", () => {
|
|
92
|
+
const result = undici_http_handler_1.UndiciHttpHandler.create({ requestTimeout: 1000 });
|
|
93
|
+
(0, vitest_1.expect)(result).toBeInstanceOf(undici_http_handler_1.UndiciHttpHandler);
|
|
94
|
+
handler = result;
|
|
95
|
+
});
|
|
96
|
+
(0, vitest_1.it)("static create instantiates with no arguments", () => {
|
|
97
|
+
const result = undici_http_handler_1.UndiciHttpHandler.create();
|
|
98
|
+
(0, vitest_1.expect)(result).toBeInstanceOf(undici_http_handler_1.UndiciHttpHandler);
|
|
99
|
+
handler = result;
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
(0, vitest_1.describe)("handle", () => {
|
|
103
|
+
(0, vitest_1.it)("makes a basic GET request", async () => {
|
|
104
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
105
|
+
const { response } = await handler.handle(createMockRequest());
|
|
106
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
107
|
+
(0, vitest_1.expect)(response.headers["content-type"]).toBe("text/plain");
|
|
108
|
+
});
|
|
109
|
+
(0, vitest_1.it)("sends request body on POST", async () => {
|
|
110
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
111
|
+
const body = "hello world";
|
|
112
|
+
const { response } = await handler.handle(createMockRequest({
|
|
113
|
+
method: "POST",
|
|
114
|
+
path: "/echo",
|
|
115
|
+
body,
|
|
116
|
+
headers: { "content-type": "text/plain" },
|
|
117
|
+
}));
|
|
118
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
119
|
+
(0, vitest_1.expect)(response.headers["x-method"]).toBe("POST");
|
|
120
|
+
const text = await new Response(response.body).text();
|
|
121
|
+
(0, vitest_1.expect)(text).toBe("hello world");
|
|
122
|
+
});
|
|
123
|
+
(0, vitest_1.it)("sends Buffer body", async () => {
|
|
124
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
125
|
+
const body = Buffer.from("buffer body");
|
|
126
|
+
const { response } = await handler.handle(createMockRequest({
|
|
127
|
+
method: "POST",
|
|
128
|
+
path: "/echo",
|
|
129
|
+
headers: { "content-type": "application/octet-stream" },
|
|
130
|
+
body,
|
|
131
|
+
}));
|
|
132
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
133
|
+
const text = await new Response(response.body).text();
|
|
134
|
+
(0, vitest_1.expect)(text).toBe("buffer body");
|
|
135
|
+
});
|
|
136
|
+
(0, vitest_1.it)("appends query string to path", async () => {
|
|
137
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
138
|
+
const { response } = await handler.handle(createMockRequest({
|
|
139
|
+
path: "/echo",
|
|
140
|
+
query: { foo: "bar", baz: "qux" },
|
|
141
|
+
}));
|
|
142
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
143
|
+
(0, vitest_1.expect)(response.headers["x-url"]).toContain("foo=bar");
|
|
144
|
+
(0, vitest_1.expect)(response.headers["x-url"]).toContain("baz=qux");
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.it)("joins multi-value response headers with comma", async () => {
|
|
147
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
148
|
+
const { response } = await handler.handle(createMockRequest({ path: "/multi-header" }));
|
|
149
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
150
|
+
(0, vitest_1.expect)(response.headers["set-cookie"]).toBe("a=1, b=2");
|
|
151
|
+
});
|
|
152
|
+
(0, vitest_1.it)("handles fragment in path", async () => {
|
|
153
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
154
|
+
const { response } = await handler.handle(createMockRequest({
|
|
155
|
+
path: "/echo",
|
|
156
|
+
fragment: "section1",
|
|
157
|
+
}));
|
|
158
|
+
(0, vitest_1.expect)(response.statusCode).toBe(200);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
(0, vitest_1.describe)("abort signal", () => {
|
|
162
|
+
(0, vitest_1.it)("throws AbortError if signal is already aborted", async () => {
|
|
163
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
164
|
+
const controller = new AbortController();
|
|
165
|
+
controller.abort();
|
|
166
|
+
await (0, vitest_1.expect)(handler.handle(createMockRequest(), {
|
|
167
|
+
abortSignal: controller.signal,
|
|
168
|
+
})).rejects.toThrow("Request aborted");
|
|
169
|
+
});
|
|
170
|
+
(0, vitest_1.it)("throws AbortError when signal is aborted during request", async () => {
|
|
171
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
172
|
+
const controller = new AbortController();
|
|
173
|
+
setTimeout(() => controller.abort(), 10);
|
|
174
|
+
await (0, vitest_1.expect)(handler.handle(createMockRequest({ path: "/delay?ms=5000" }), {
|
|
175
|
+
abortSignal: controller.signal,
|
|
176
|
+
})).rejects.toThrow();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
(0, vitest_1.describe)("timeouts", () => {
|
|
180
|
+
(0, vitest_1.it)("uses requestTimeout from options", async () => {
|
|
181
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ requestTimeout: 50 });
|
|
182
|
+
await (0, vitest_1.expect)(handler.handle(createMockRequest({ path: "/delay?ms=5000" }))).rejects.toThrow();
|
|
183
|
+
});
|
|
184
|
+
(0, vitest_1.it)("uses requestTimeout from handle options", async () => {
|
|
185
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
186
|
+
await (0, vitest_1.expect)(handler.handle(createMockRequest({ path: "/delay?ms=5000" }), {
|
|
187
|
+
requestTimeout: 50,
|
|
188
|
+
})).rejects.toThrow();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
(0, vitest_1.describe)("external dispatcher", () => {
|
|
192
|
+
(0, vitest_1.it)("uses provided dispatcher", async () => {
|
|
193
|
+
const mockDispatcher = {
|
|
194
|
+
request: vitest_1.vi.fn().mockResolvedValue({
|
|
195
|
+
statusCode: 201,
|
|
196
|
+
headers: { "x-custom": "value" },
|
|
197
|
+
body: null,
|
|
198
|
+
}),
|
|
199
|
+
destroy: vitest_1.vi.fn(),
|
|
200
|
+
};
|
|
201
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ dispatcher: mockDispatcher });
|
|
202
|
+
const { response } = await handler.handle(createMockRequest());
|
|
203
|
+
(0, vitest_1.expect)(response.statusCode).toBe(201);
|
|
204
|
+
(0, vitest_1.expect)(response.headers["x-custom"]).toBe("value");
|
|
205
|
+
(0, vitest_1.expect)(mockDispatcher.request).toHaveBeenCalledOnce();
|
|
206
|
+
});
|
|
207
|
+
(0, vitest_1.it)("does not destroy external dispatcher on handler destroy", () => {
|
|
208
|
+
const mockDispatcher = {
|
|
209
|
+
destroy: vitest_1.vi.fn(),
|
|
210
|
+
};
|
|
211
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ dispatcher: mockDispatcher });
|
|
212
|
+
handler.destroy();
|
|
213
|
+
(0, vitest_1.expect)(mockDispatcher.destroy).not.toHaveBeenCalled();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
(0, vitest_1.describe)("destroy", () => {
|
|
217
|
+
(0, vitest_1.it)("destroys internal dispatcher", async () => {
|
|
218
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
219
|
+
// Trigger dispatcher creation
|
|
220
|
+
await handler.handle(createMockRequest());
|
|
221
|
+
// Should not throw
|
|
222
|
+
handler.destroy();
|
|
223
|
+
});
|
|
224
|
+
(0, vitest_1.it)("is safe to call multiple times", () => {
|
|
225
|
+
handler = new undici_http_handler_1.UndiciHttpHandler();
|
|
226
|
+
handler.destroy();
|
|
227
|
+
handler.destroy();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
(0, vitest_1.describe)("updateHttpClientConfig / httpHandlerConfigs", () => {
|
|
231
|
+
(0, vitest_1.it)("returns empty object before first request", () => {
|
|
232
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ requestTimeout: 1000 });
|
|
233
|
+
(0, vitest_1.expect)(handler.httpHandlerConfigs()).toEqual({});
|
|
234
|
+
});
|
|
235
|
+
(0, vitest_1.it)("returns config after first request", async () => {
|
|
236
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ requestTimeout: 1000 });
|
|
237
|
+
await handler.handle(createMockRequest());
|
|
238
|
+
const configs = handler.httpHandlerConfigs();
|
|
239
|
+
(0, vitest_1.expect)(configs.requestTimeout).toBe(1000);
|
|
240
|
+
});
|
|
241
|
+
(0, vitest_1.it)("updates config", async () => {
|
|
242
|
+
handler = new undici_http_handler_1.UndiciHttpHandler({ requestTimeout: 1000 });
|
|
243
|
+
await handler.handle(createMockRequest());
|
|
244
|
+
handler.updateHttpClientConfig("requestTimeout", 2000);
|
|
245
|
+
// Config is reset, need another request to resolve
|
|
246
|
+
await handler.handle(createMockRequest());
|
|
247
|
+
(0, vitest_1.expect)(handler.httpHandlerConfigs().requestTimeout).toBe(2000);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
//# sourceMappingURL=undici-http-handler.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undici-http-handler.spec.js","sourceRoot":"","sources":["../../src/undici-http-handler.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { HttpResponse } from "@smithy/protocol-http";
|
|
2
|
+
import { buildQueryString } from "@smithy/querystring-builder";
|
|
3
|
+
import { Agent } from "undici";
|
|
4
|
+
/**
|
|
5
|
+
* An HTTP handler that uses undici instead of Node.js native http/https modules.
|
|
6
|
+
* Drop-in replacement for `NodeHttpHandler` from `@smithy/node-http-handler`.
|
|
7
|
+
*/
|
|
8
|
+
export class UndiciHttpHandler {
|
|
9
|
+
config;
|
|
10
|
+
configProvider;
|
|
11
|
+
dispatcher;
|
|
12
|
+
externalDispatcher = false;
|
|
13
|
+
metadata = { handlerProtocol: "http/1.1" };
|
|
14
|
+
/**
|
|
15
|
+
* Returns the input if it is an HttpHandler of any class,
|
|
16
|
+
* or instantiates a new instance of this handler.
|
|
17
|
+
*/
|
|
18
|
+
static create(instanceOrOptions) {
|
|
19
|
+
if (typeof instanceOrOptions?.handle === "function") {
|
|
20
|
+
return instanceOrOptions;
|
|
21
|
+
}
|
|
22
|
+
return new UndiciHttpHandler(instanceOrOptions);
|
|
23
|
+
}
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.configProvider = new Promise((resolve, reject) => {
|
|
26
|
+
if (typeof options === "function") {
|
|
27
|
+
options()
|
|
28
|
+
.then((_options) => resolve(this.resolveConfig(_options)))
|
|
29
|
+
.catch(reject);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
resolve(this.resolveConfig(options));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
resolveConfig(options) {
|
|
37
|
+
const resolved = { ...options };
|
|
38
|
+
if (resolved.dispatcher) {
|
|
39
|
+
this.externalDispatcher = true;
|
|
40
|
+
this.dispatcher = resolved.dispatcher;
|
|
41
|
+
}
|
|
42
|
+
return resolved;
|
|
43
|
+
}
|
|
44
|
+
getOrCreateDispatcher(config) {
|
|
45
|
+
if (this.dispatcher) {
|
|
46
|
+
return this.dispatcher;
|
|
47
|
+
}
|
|
48
|
+
const connectTimeout = config.connectionTimeout ?? 0;
|
|
49
|
+
const bodyTimeout = config.requestTimeout ?? 0;
|
|
50
|
+
const headersTimeout = config.requestTimeout ?? 0;
|
|
51
|
+
const connections = config.maxConnectionsPerOrigin ?? 50;
|
|
52
|
+
this.dispatcher = new Agent({
|
|
53
|
+
connections,
|
|
54
|
+
bodyTimeout: bodyTimeout || undefined,
|
|
55
|
+
headersTimeout: headersTimeout || undefined,
|
|
56
|
+
connect: {
|
|
57
|
+
timeout: connectTimeout || undefined,
|
|
58
|
+
keepAlive: true,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
return this.dispatcher;
|
|
62
|
+
}
|
|
63
|
+
destroy() {
|
|
64
|
+
if (this.dispatcher && !this.externalDispatcher) {
|
|
65
|
+
this.dispatcher.destroy();
|
|
66
|
+
this.dispatcher = undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async handle(request, { abortSignal, requestTimeout } = {}) {
|
|
70
|
+
if (!this.config) {
|
|
71
|
+
this.config = await this.configProvider;
|
|
72
|
+
}
|
|
73
|
+
const config = this.config;
|
|
74
|
+
const dispatcher = this.getOrCreateDispatcher(config);
|
|
75
|
+
if (abortSignal?.aborted) {
|
|
76
|
+
throw buildAbortError();
|
|
77
|
+
}
|
|
78
|
+
// Build the full URL
|
|
79
|
+
const queryString = buildQueryString(request.query || {});
|
|
80
|
+
let path = request.path;
|
|
81
|
+
if (queryString) {
|
|
82
|
+
path += `?${queryString}`;
|
|
83
|
+
}
|
|
84
|
+
if (request.fragment) {
|
|
85
|
+
path += `#${request.fragment}`;
|
|
86
|
+
}
|
|
87
|
+
let auth;
|
|
88
|
+
if (request.username != null || request.password != null) {
|
|
89
|
+
const username = request.username ?? "";
|
|
90
|
+
const password = request.password ?? "";
|
|
91
|
+
auth = `${username}:${password}`;
|
|
92
|
+
}
|
|
93
|
+
const port = request.port ? `:${request.port}` : "";
|
|
94
|
+
let origin = `${request.protocol}//${request.hostname}${port}`;
|
|
95
|
+
if (auth) {
|
|
96
|
+
origin = `${request.protocol}//${auth}@${request.hostname}${port}`;
|
|
97
|
+
}
|
|
98
|
+
// undici natively supports string | Buffer | Uint8Array | Readable | AsyncIterable as body.
|
|
99
|
+
// Pass through directly to avoid buffering streams into memory.
|
|
100
|
+
const body = request.body ?? null;
|
|
101
|
+
// Build undici request options
|
|
102
|
+
const effectiveTimeout = requestTimeout ?? config.requestTimeout ?? 0;
|
|
103
|
+
const requestOptions = {
|
|
104
|
+
origin,
|
|
105
|
+
path,
|
|
106
|
+
method: request.method,
|
|
107
|
+
headers: request.headers,
|
|
108
|
+
body,
|
|
109
|
+
headersTimeout: effectiveTimeout || undefined,
|
|
110
|
+
bodyTimeout: effectiveTimeout || undefined,
|
|
111
|
+
signal: abortSignal,
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
const { statusCode, headers: responseHeaders, body: responseBody, } = await dispatcher.request(requestOptions);
|
|
115
|
+
// Transform undici headers (Record<string, string | string[]>) to HeaderBag (Record<string, string>)
|
|
116
|
+
const transformedHeaders = {};
|
|
117
|
+
for (const key in responseHeaders) {
|
|
118
|
+
const value = responseHeaders[key];
|
|
119
|
+
if (value !== undefined) {
|
|
120
|
+
transformedHeaders[key] = Array.isArray(value)
|
|
121
|
+
? value.join(", ")
|
|
122
|
+
: value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const httpResponse = new HttpResponse({
|
|
126
|
+
statusCode,
|
|
127
|
+
headers: transformedHeaders,
|
|
128
|
+
body: responseBody,
|
|
129
|
+
});
|
|
130
|
+
return { response: httpResponse };
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (err?.name === "AbortError" || err?.code === "UND_ERR_ABORTED") {
|
|
134
|
+
throw buildAbortError();
|
|
135
|
+
}
|
|
136
|
+
if (err?.code === "UND_ERR_HEADERS_TIMEOUT" ||
|
|
137
|
+
err?.code === "UND_ERR_BODY_TIMEOUT" ||
|
|
138
|
+
err?.code === "UND_ERR_CONNECT_TIMEOUT") {
|
|
139
|
+
throw Object.assign(new Error(`Request timeout: ${err.message}`), {
|
|
140
|
+
name: "TimeoutError",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
updateHttpClientConfig(key, value) {
|
|
147
|
+
this.config = undefined;
|
|
148
|
+
this.configProvider = this.configProvider.then((config) => ({
|
|
149
|
+
...config,
|
|
150
|
+
[key]: value,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
httpHandlerConfigs() {
|
|
154
|
+
return this.config ?? {};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function buildAbortError() {
|
|
158
|
+
return Object.assign(new Error("Request aborted"), {
|
|
159
|
+
name: "AbortError",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=undici-http-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undici-http-handler.js","sourceRoot":"","sources":["../../src/undici-http-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { HttpRequest } from "@smithy/protocol-http";
|
|
2
|
+
import { createServer, } from "node:http";
|
|
3
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it, vi, } from "vitest";
|
|
4
|
+
import { UndiciHttpHandler } from "./undici-http-handler";
|
|
5
|
+
let server;
|
|
6
|
+
let port;
|
|
7
|
+
function createMockRequest(overrides = {}) {
|
|
8
|
+
return Object.assign(new HttpRequest({
|
|
9
|
+
protocol: "http:",
|
|
10
|
+
hostname: "localhost",
|
|
11
|
+
port,
|
|
12
|
+
method: "GET",
|
|
13
|
+
path: "/",
|
|
14
|
+
headers: {},
|
|
15
|
+
}), overrides);
|
|
16
|
+
}
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
server = createServer((req, res) => {
|
|
19
|
+
const url = new URL(req.url, `http://localhost`);
|
|
20
|
+
if (url.pathname === "/delay") {
|
|
21
|
+
const ms = parseInt(url.searchParams.get("ms") ?? "1000", 10);
|
|
22
|
+
setTimeout(() => {
|
|
23
|
+
res.writeHead(200, { "content-type": "text/plain" });
|
|
24
|
+
res.end("delayed");
|
|
25
|
+
}, ms);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (url.pathname === "/echo") {
|
|
29
|
+
const chunks = [];
|
|
30
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
31
|
+
req.on("end", () => {
|
|
32
|
+
res.writeHead(200, {
|
|
33
|
+
"content-type": "application/octet-stream",
|
|
34
|
+
"x-method": req.method,
|
|
35
|
+
"x-url": req.url,
|
|
36
|
+
});
|
|
37
|
+
res.end(Buffer.concat(chunks));
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (url.pathname === "/multi-header") {
|
|
42
|
+
// Manually write raw response with duplicate headers
|
|
43
|
+
res.writeHead(200, [
|
|
44
|
+
["set-cookie", "a=1"],
|
|
45
|
+
["set-cookie", "b=2"],
|
|
46
|
+
]);
|
|
47
|
+
res.end("ok");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
res.writeHead(200, { "content-type": "text/plain" });
|
|
51
|
+
res.end("ok");
|
|
52
|
+
});
|
|
53
|
+
await new Promise((resolve) => {
|
|
54
|
+
server.listen(0, "127.0.0.1", () => {
|
|
55
|
+
port = server.address().port;
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
afterAll(async () => {
|
|
61
|
+
await new Promise((resolve, reject) => {
|
|
62
|
+
server.close((err) => (err ? reject(err) : resolve()));
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe("UndiciHttpHandler", () => {
|
|
66
|
+
let handler;
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
handler?.destroy();
|
|
69
|
+
});
|
|
70
|
+
describe("constructor and create", () => {
|
|
71
|
+
it("creates a new instance with no options", () => {
|
|
72
|
+
handler = new UndiciHttpHandler();
|
|
73
|
+
expect(handler.metadata).toEqual({ handlerProtocol: "http/1.1" });
|
|
74
|
+
});
|
|
75
|
+
it("creates a new instance with options", () => {
|
|
76
|
+
handler = new UndiciHttpHandler({ requestTimeout: 5000 });
|
|
77
|
+
expect(handler.metadata).toEqual({ handlerProtocol: "http/1.1" });
|
|
78
|
+
});
|
|
79
|
+
it("creates a new instance with a provider function", async () => {
|
|
80
|
+
handler = new UndiciHttpHandler(async () => ({ requestTimeout: 5000 }));
|
|
81
|
+
const { response } = await handler.handle(createMockRequest());
|
|
82
|
+
expect(response.statusCode).toBe(200);
|
|
83
|
+
});
|
|
84
|
+
it("static create returns existing HttpHandler instance", () => {
|
|
85
|
+
handler = new UndiciHttpHandler();
|
|
86
|
+
const result = UndiciHttpHandler.create(handler);
|
|
87
|
+
expect(result).toBe(handler);
|
|
88
|
+
});
|
|
89
|
+
it("static create instantiates from options", () => {
|
|
90
|
+
const result = UndiciHttpHandler.create({ requestTimeout: 1000 });
|
|
91
|
+
expect(result).toBeInstanceOf(UndiciHttpHandler);
|
|
92
|
+
handler = result;
|
|
93
|
+
});
|
|
94
|
+
it("static create instantiates with no arguments", () => {
|
|
95
|
+
const result = UndiciHttpHandler.create();
|
|
96
|
+
expect(result).toBeInstanceOf(UndiciHttpHandler);
|
|
97
|
+
handler = result;
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe("handle", () => {
|
|
101
|
+
it("makes a basic GET request", async () => {
|
|
102
|
+
handler = new UndiciHttpHandler();
|
|
103
|
+
const { response } = await handler.handle(createMockRequest());
|
|
104
|
+
expect(response.statusCode).toBe(200);
|
|
105
|
+
expect(response.headers["content-type"]).toBe("text/plain");
|
|
106
|
+
});
|
|
107
|
+
it("sends request body on POST", async () => {
|
|
108
|
+
handler = new UndiciHttpHandler();
|
|
109
|
+
const body = "hello world";
|
|
110
|
+
const { response } = await handler.handle(createMockRequest({
|
|
111
|
+
method: "POST",
|
|
112
|
+
path: "/echo",
|
|
113
|
+
body,
|
|
114
|
+
headers: { "content-type": "text/plain" },
|
|
115
|
+
}));
|
|
116
|
+
expect(response.statusCode).toBe(200);
|
|
117
|
+
expect(response.headers["x-method"]).toBe("POST");
|
|
118
|
+
const text = await new Response(response.body).text();
|
|
119
|
+
expect(text).toBe("hello world");
|
|
120
|
+
});
|
|
121
|
+
it("sends Buffer body", async () => {
|
|
122
|
+
handler = new UndiciHttpHandler();
|
|
123
|
+
const body = Buffer.from("buffer body");
|
|
124
|
+
const { response } = await handler.handle(createMockRequest({
|
|
125
|
+
method: "POST",
|
|
126
|
+
path: "/echo",
|
|
127
|
+
headers: { "content-type": "application/octet-stream" },
|
|
128
|
+
body,
|
|
129
|
+
}));
|
|
130
|
+
expect(response.statusCode).toBe(200);
|
|
131
|
+
const text = await new Response(response.body).text();
|
|
132
|
+
expect(text).toBe("buffer body");
|
|
133
|
+
});
|
|
134
|
+
it("appends query string to path", async () => {
|
|
135
|
+
handler = new UndiciHttpHandler();
|
|
136
|
+
const { response } = await handler.handle(createMockRequest({
|
|
137
|
+
path: "/echo",
|
|
138
|
+
query: { foo: "bar", baz: "qux" },
|
|
139
|
+
}));
|
|
140
|
+
expect(response.statusCode).toBe(200);
|
|
141
|
+
expect(response.headers["x-url"]).toContain("foo=bar");
|
|
142
|
+
expect(response.headers["x-url"]).toContain("baz=qux");
|
|
143
|
+
});
|
|
144
|
+
it("joins multi-value response headers with comma", async () => {
|
|
145
|
+
handler = new UndiciHttpHandler();
|
|
146
|
+
const { response } = await handler.handle(createMockRequest({ path: "/multi-header" }));
|
|
147
|
+
expect(response.statusCode).toBe(200);
|
|
148
|
+
expect(response.headers["set-cookie"]).toBe("a=1, b=2");
|
|
149
|
+
});
|
|
150
|
+
it("handles fragment in path", async () => {
|
|
151
|
+
handler = new UndiciHttpHandler();
|
|
152
|
+
const { response } = await handler.handle(createMockRequest({
|
|
153
|
+
path: "/echo",
|
|
154
|
+
fragment: "section1",
|
|
155
|
+
}));
|
|
156
|
+
expect(response.statusCode).toBe(200);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe("abort signal", () => {
|
|
160
|
+
it("throws AbortError if signal is already aborted", async () => {
|
|
161
|
+
handler = new UndiciHttpHandler();
|
|
162
|
+
const controller = new AbortController();
|
|
163
|
+
controller.abort();
|
|
164
|
+
await expect(handler.handle(createMockRequest(), {
|
|
165
|
+
abortSignal: controller.signal,
|
|
166
|
+
})).rejects.toThrow("Request aborted");
|
|
167
|
+
});
|
|
168
|
+
it("throws AbortError when signal is aborted during request", async () => {
|
|
169
|
+
handler = new UndiciHttpHandler();
|
|
170
|
+
const controller = new AbortController();
|
|
171
|
+
setTimeout(() => controller.abort(), 10);
|
|
172
|
+
await expect(handler.handle(createMockRequest({ path: "/delay?ms=5000" }), {
|
|
173
|
+
abortSignal: controller.signal,
|
|
174
|
+
})).rejects.toThrow();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
describe("timeouts", () => {
|
|
178
|
+
it("uses requestTimeout from options", async () => {
|
|
179
|
+
handler = new UndiciHttpHandler({ requestTimeout: 50 });
|
|
180
|
+
await expect(handler.handle(createMockRequest({ path: "/delay?ms=5000" }))).rejects.toThrow();
|
|
181
|
+
});
|
|
182
|
+
it("uses requestTimeout from handle options", async () => {
|
|
183
|
+
handler = new UndiciHttpHandler();
|
|
184
|
+
await expect(handler.handle(createMockRequest({ path: "/delay?ms=5000" }), {
|
|
185
|
+
requestTimeout: 50,
|
|
186
|
+
})).rejects.toThrow();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
describe("external dispatcher", () => {
|
|
190
|
+
it("uses provided dispatcher", async () => {
|
|
191
|
+
const mockDispatcher = {
|
|
192
|
+
request: vi.fn().mockResolvedValue({
|
|
193
|
+
statusCode: 201,
|
|
194
|
+
headers: { "x-custom": "value" },
|
|
195
|
+
body: null,
|
|
196
|
+
}),
|
|
197
|
+
destroy: vi.fn(),
|
|
198
|
+
};
|
|
199
|
+
handler = new UndiciHttpHandler({ dispatcher: mockDispatcher });
|
|
200
|
+
const { response } = await handler.handle(createMockRequest());
|
|
201
|
+
expect(response.statusCode).toBe(201);
|
|
202
|
+
expect(response.headers["x-custom"]).toBe("value");
|
|
203
|
+
expect(mockDispatcher.request).toHaveBeenCalledOnce();
|
|
204
|
+
});
|
|
205
|
+
it("does not destroy external dispatcher on handler destroy", () => {
|
|
206
|
+
const mockDispatcher = {
|
|
207
|
+
destroy: vi.fn(),
|
|
208
|
+
};
|
|
209
|
+
handler = new UndiciHttpHandler({ dispatcher: mockDispatcher });
|
|
210
|
+
handler.destroy();
|
|
211
|
+
expect(mockDispatcher.destroy).not.toHaveBeenCalled();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe("destroy", () => {
|
|
215
|
+
it("destroys internal dispatcher", async () => {
|
|
216
|
+
handler = new UndiciHttpHandler();
|
|
217
|
+
// Trigger dispatcher creation
|
|
218
|
+
await handler.handle(createMockRequest());
|
|
219
|
+
// Should not throw
|
|
220
|
+
handler.destroy();
|
|
221
|
+
});
|
|
222
|
+
it("is safe to call multiple times", () => {
|
|
223
|
+
handler = new UndiciHttpHandler();
|
|
224
|
+
handler.destroy();
|
|
225
|
+
handler.destroy();
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
describe("updateHttpClientConfig / httpHandlerConfigs", () => {
|
|
229
|
+
it("returns empty object before first request", () => {
|
|
230
|
+
handler = new UndiciHttpHandler({ requestTimeout: 1000 });
|
|
231
|
+
expect(handler.httpHandlerConfigs()).toEqual({});
|
|
232
|
+
});
|
|
233
|
+
it("returns config after first request", async () => {
|
|
234
|
+
handler = new UndiciHttpHandler({ requestTimeout: 1000 });
|
|
235
|
+
await handler.handle(createMockRequest());
|
|
236
|
+
const configs = handler.httpHandlerConfigs();
|
|
237
|
+
expect(configs.requestTimeout).toBe(1000);
|
|
238
|
+
});
|
|
239
|
+
it("updates config", async () => {
|
|
240
|
+
handler = new UndiciHttpHandler({ requestTimeout: 1000 });
|
|
241
|
+
await handler.handle(createMockRequest());
|
|
242
|
+
handler.updateHttpClientConfig("requestTimeout", 2000);
|
|
243
|
+
// Config is reset, need another request to resolve
|
|
244
|
+
await handler.handle(createMockRequest());
|
|
245
|
+
expect(handler.httpHandlerConfigs().requestTimeout).toBe(2000);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
//# sourceMappingURL=undici-http-handler.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undici-http-handler.spec.js","sourceRoot":"","sources":["../../src/undici-http-handler.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { HttpHandler, HttpRequest } from "@smithy/protocol-http";
|
|
2
|
+
import { HttpResponse } from "@smithy/protocol-http";
|
|
3
|
+
import type { HttpHandlerOptions, Logger, Provider } from "@smithy/types";
|
|
4
|
+
import { Dispatcher } from "undici";
|
|
5
|
+
/**
|
|
6
|
+
* Options for the UndiciHttpHandler.
|
|
7
|
+
*/
|
|
8
|
+
export interface UndiciHttpHandlerOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The maximum time in milliseconds that the connection phase of a request
|
|
11
|
+
* may take before the connection attempt is abandoned.
|
|
12
|
+
*
|
|
13
|
+
* Mapped to undici's `connect.timeout`.
|
|
14
|
+
*/
|
|
15
|
+
connectionTimeout?: number;
|
|
16
|
+
/**
|
|
17
|
+
* The maximum time in milliseconds that a request may take.
|
|
18
|
+
* Mapped to undici's `headersTimeout` + `bodyTimeout`.
|
|
19
|
+
*/
|
|
20
|
+
requestTimeout?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum number of connections per origin.
|
|
23
|
+
* Defaults to 50 (matching NodeHttpHandler's default maxSockets).
|
|
24
|
+
*/
|
|
25
|
+
maxConnectionsPerOrigin?: number;
|
|
26
|
+
/**
|
|
27
|
+
* An existing undici Dispatcher (Agent, Pool, Client, etc.) to use.
|
|
28
|
+
* When provided, connectionTimeout, requestTimeout, and maxConnectionsPerOrigin
|
|
29
|
+
* are ignored since the dispatcher is externally managed.
|
|
30
|
+
*/
|
|
31
|
+
dispatcher?: Dispatcher;
|
|
32
|
+
/**
|
|
33
|
+
* Optional logger.
|
|
34
|
+
*/
|
|
35
|
+
logger?: Logger;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* An HTTP handler that uses undici instead of Node.js native http/https modules.
|
|
39
|
+
* Drop-in replacement for `NodeHttpHandler` from `@smithy/node-http-handler`.
|
|
40
|
+
*/
|
|
41
|
+
export declare class UndiciHttpHandler implements HttpHandler<UndiciHttpHandlerOptions> {
|
|
42
|
+
private config?;
|
|
43
|
+
private configProvider;
|
|
44
|
+
private dispatcher?;
|
|
45
|
+
private externalDispatcher;
|
|
46
|
+
readonly metadata: {
|
|
47
|
+
handlerProtocol: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Returns the input if it is an HttpHandler of any class,
|
|
51
|
+
* or instantiates a new instance of this handler.
|
|
52
|
+
*/
|
|
53
|
+
static create(instanceOrOptions?: HttpHandler<any> | UndiciHttpHandlerOptions | Provider<UndiciHttpHandlerOptions | void>): UndiciHttpHandler | HttpHandler<any>;
|
|
54
|
+
constructor(options?: UndiciHttpHandlerOptions | Provider<UndiciHttpHandlerOptions | void>);
|
|
55
|
+
private resolveConfig;
|
|
56
|
+
private getOrCreateDispatcher;
|
|
57
|
+
destroy(): void;
|
|
58
|
+
handle(request: HttpRequest, { abortSignal, requestTimeout }?: HttpHandlerOptions): Promise<{
|
|
59
|
+
response: HttpResponse;
|
|
60
|
+
}>;
|
|
61
|
+
updateHttpClientConfig(key: keyof UndiciHttpHandlerOptions, value: UndiciHttpHandlerOptions[typeof key]): void;
|
|
62
|
+
httpHandlerConfigs(): UndiciHttpHandlerOptions;
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trivikr-test/undici-http-handler",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Smithy-compatible HTTP handler using undici instead of Node.js native http",
|
|
5
|
+
"main": "./dist/cjs/index.js",
|
|
6
|
+
"module": "./dist/es/index.js",
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
|
|
10
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
11
|
+
"build:es": "tsc -p tsconfig.es.json",
|
|
12
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"clean": "rm -rf dist"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"smithy",
|
|
18
|
+
"undici",
|
|
19
|
+
"http",
|
|
20
|
+
"handler",
|
|
21
|
+
"aws-sdk"
|
|
22
|
+
],
|
|
23
|
+
"license": "Apache-2.0",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@smithy/protocol-http": "^5.0.0",
|
|
26
|
+
"@smithy/querystring-builder": "^4.0.0",
|
|
27
|
+
"@smithy/types": "^4.0.0",
|
|
28
|
+
"tslib": "^2.6.2",
|
|
29
|
+
"undici": "^7.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^20.0.0",
|
|
33
|
+
"concurrently": "^9.0.0",
|
|
34
|
+
"typescript": "~5.7.0",
|
|
35
|
+
"vitest": "^4.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=20.0.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist/**"
|
|
42
|
+
],
|
|
43
|
+
"packageManager": "yarn@4.14.1"
|
|
44
|
+
}
|