urllib 3.25.0 → 3.26.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/README.md +27 -12
- package/dist/commonjs/HttpAgent.d.ts +1 -1
- package/dist/commonjs/HttpAgent.js +1 -1
- package/dist/commonjs/HttpClient.d.ts +2 -3
- package/dist/commonjs/HttpClient.js +9 -1
- package/dist/commonjs/IncomingHttpHeaders.d.ts +0 -1
- package/dist/commonjs/Request.d.ts +0 -4
- package/dist/commonjs/Response.d.ts +0 -1
- package/dist/commonjs/diagnosticsChannel.js +10 -5
- package/dist/commonjs/index.js +4 -4
- package/dist/commonjs/utils.js +6 -7
- package/dist/esm/HttpAgent.d.ts +1 -1
- package/dist/esm/HttpAgent.js +1 -1
- package/dist/esm/HttpClient.d.ts +2 -3
- package/dist/esm/HttpClient.js +9 -1
- package/dist/esm/IncomingHttpHeaders.d.ts +0 -1
- package/dist/esm/Request.d.ts +0 -4
- package/dist/esm/Response.d.ts +0 -1
- package/dist/esm/diagnosticsChannel.js +9 -3
- package/package.json +7 -4
- package/src/HttpAgent.ts +2 -1
- package/src/HttpClient.ts +9 -0
- package/src/diagnosticsChannel.ts +12 -5
package/README.md
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
# urllib
|
1
|
+
# urllib@3
|
2
2
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
4
|
-
[](https://github.com/node-modules/urllib/actions/workflows/nodejs-3.x.yml)
|
5
5
|
[![Test coverage][codecov-image]][codecov-url]
|
6
6
|
[![Known Vulnerabilities][snyk-image]][snyk-url]
|
7
7
|
[![npm download][download-image]][download-url]
|
8
8
|
|
9
|
-
[npm-image]: https://img.shields.io/npm/v/urllib.svg?style=flat-square
|
10
|
-
[npm-url]: https://npmjs.org/package/urllib
|
11
|
-
[codecov-image]: https://codecov.io/gh/node-modules/urllib/branch/
|
12
|
-
[codecov-url]: https://codecov.io/gh/node-modules/urllib
|
9
|
+
[npm-image]: https://img.shields.io/npm/v/urllib/release-3.x.svg?style=flat-square
|
10
|
+
[npm-url]: https://npmjs.org/package/urllib/v/release-3.x
|
11
|
+
[codecov-image]: https://codecov.io/gh/node-modules/urllib/branch/3.x/graph/badge.svg
|
12
|
+
[codecov-url]: https://app.codecov.io/gh/node-modules/urllib/tree/3.x
|
13
13
|
[snyk-image]: https://snyk.io/test/npm/urllib/badge.svg?style=flat-square
|
14
14
|
[snyk-url]: https://snyk.io/test/npm/urllib
|
15
15
|
[download-image]: https://img.shields.io/npm/dm/urllib.svg?style=flat-square
|
16
|
-
[download-url]: https://npmjs.org/package/urllib
|
16
|
+
[download-url]: https://npmjs.org/package/urllib/v/release-3.x
|
17
17
|
|
18
18
|
Request HTTP URLs in a complex world — basic
|
19
19
|
and digest authentication, redirections, timeout and more.
|
@@ -21,7 +21,7 @@ and digest authentication, redirections, timeout and more.
|
|
21
21
|
## Install
|
22
22
|
|
23
23
|
```bash
|
24
|
-
npm install urllib
|
24
|
+
npm install urllib@3
|
25
25
|
```
|
26
26
|
|
27
27
|
## Usage
|
@@ -209,6 +209,22 @@ Response is normal object, it contains:
|
|
209
209
|
NODE_DEBUG=urllib:* npm test
|
210
210
|
```
|
211
211
|
|
212
|
+
## Request with HTTP2
|
213
|
+
|
214
|
+
Create a HttpClient with `options.allowH2 = true`
|
215
|
+
|
216
|
+
```ts
|
217
|
+
import { HttpClient } from 'urllib';
|
218
|
+
|
219
|
+
const httpClient = new HttpClient({
|
220
|
+
allowH2: true,
|
221
|
+
});
|
222
|
+
|
223
|
+
const response = await httpClient.request('https://node.js.org');
|
224
|
+
console.log(response.status);
|
225
|
+
console.log(response.headers);
|
226
|
+
```
|
227
|
+
|
212
228
|
## Mocking Request
|
213
229
|
|
214
230
|
export from [undici](https://undici.nodejs.org/#/docs/best-practices/mocking-request)
|
@@ -283,6 +299,9 @@ Fork [undici benchmarks script](https://github.com/fengmk2/undici/blob/urllib-be
|
|
283
299
|
| undici - stream | 45 | 12523.45 req/sec | ± 2.97 % | + 754.61 % |
|
284
300
|
| undici - dispatch | 51 | 12970.18 req/sec | ± 3.15 % | + 785.10 % |
|
285
301
|
|
302
|
+
## License
|
303
|
+
|
304
|
+
[MIT](LICENSE)
|
286
305
|
|
287
306
|
<!-- GITCONTRIBUTOR_START -->
|
288
307
|
|
@@ -301,7 +320,3 @@ Fork [undici benchmarks script](https://github.com/fengmk2/undici/blob/urllib-be
|
|
301
320
|
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Mon Dec 04 2023 00:13:39 GMT+0800`.
|
302
321
|
|
303
322
|
<!-- GITCONTRIBUTOR_END -->
|
304
|
-
|
305
|
-
## License
|
306
|
-
|
307
|
-
[MIT](LICENSE)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
1
|
import { LookupFunction } from 'node:net';
|
3
2
|
import { Agent, Dispatcher, buildConnector } from 'undici';
|
4
3
|
export type CheckAddressFunction = (ip: string, family: number | string) => boolean;
|
@@ -6,6 +5,7 @@ export type HttpAgentOptions = {
|
|
6
5
|
lookup?: LookupFunction;
|
7
6
|
checkAddress?: CheckAddressFunction;
|
8
7
|
connect?: buildConnector.BuildOptions;
|
8
|
+
allowH2?: boolean;
|
9
9
|
};
|
10
10
|
export declare class HttpAgent extends Agent {
|
11
11
|
#private;
|
@@ -1,6 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
|
-
/// <reference types="node" />
|
3
|
-
/// <reference types="node" />
|
4
1
|
import { EventEmitter } from 'node:events';
|
5
2
|
import { LookupFunction } from 'node:net';
|
6
3
|
import { Dispatcher } from 'undici';
|
@@ -9,6 +6,8 @@ import { RequestURL, RequestOptions, RequestMeta } from './Request.js';
|
|
9
6
|
import { RawResponseWithMeta, HttpClientResponse } from './Response.js';
|
10
7
|
export type ClientOptions = {
|
11
8
|
defaultArgs?: RequestOptions;
|
9
|
+
/** Allow to use HTTP2 first. Default is `false` */
|
10
|
+
allowH2?: boolean;
|
12
11
|
/**
|
13
12
|
* Custom DNS lookup function, default is `dns.lookup`.
|
14
13
|
*/
|
@@ -68,7 +68,7 @@ class BlobFromStream {
|
|
68
68
|
return 'Blob';
|
69
69
|
}
|
70
70
|
}
|
71
|
-
exports.HEADER_USER_AGENT = (0, default_user_agent_1.default)('node-urllib', '3.
|
71
|
+
exports.HEADER_USER_AGENT = (0, default_user_agent_1.default)('node-urllib', '3.26.0');
|
72
72
|
function getFileName(stream) {
|
73
73
|
const filePath = stream.path;
|
74
74
|
if (filePath) {
|
@@ -94,11 +94,19 @@ class HttpClient extends node_events_1.EventEmitter {
|
|
94
94
|
lookup: clientOptions.lookup,
|
95
95
|
checkAddress: clientOptions.checkAddress,
|
96
96
|
connect: clientOptions.connect,
|
97
|
+
allowH2: clientOptions.allowH2,
|
97
98
|
});
|
98
99
|
}
|
99
100
|
else if (clientOptions?.connect) {
|
100
101
|
this.#dispatcher = new undici_1.Agent({
|
101
102
|
connect: clientOptions.connect,
|
103
|
+
allowH2: clientOptions.allowH2,
|
104
|
+
});
|
105
|
+
}
|
106
|
+
else if (clientOptions?.allowH2) {
|
107
|
+
// Support HTTP2
|
108
|
+
this.#dispatcher = new undici_1.Agent({
|
109
|
+
allowH2: clientOptions.allowH2,
|
102
110
|
});
|
103
111
|
}
|
104
112
|
(0, diagnosticsChannel_js_1.initDiagnosticsChannel)();
|
@@ -1,7 +1,3 @@
|
|
1
|
-
/// <reference types="node" />
|
2
|
-
/// <reference types="node" />
|
3
|
-
/// <reference types="node" />
|
4
|
-
/// <reference types="node" />
|
5
1
|
import type { Readable, Writable } from 'node:stream';
|
6
2
|
import type { EventEmitter } from 'node:events';
|
7
3
|
import type { Dispatcher } from 'undici';
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.initDiagnosticsChannel =
|
6
|
+
exports.initDiagnosticsChannel = initDiagnosticsChannel;
|
7
7
|
const node_diagnostics_channel_1 = __importDefault(require("node:diagnostics_channel"));
|
8
8
|
const node_perf_hooks_1 = require("node:perf_hooks");
|
9
9
|
const node_util_1 = require("node:util");
|
@@ -179,8 +179,13 @@ function initDiagnosticsChannel() {
|
|
179
179
|
return;
|
180
180
|
// get socket from opaque
|
181
181
|
const socket = opaque[symbols_js_1.default.kRequestSocket];
|
182
|
-
socket
|
183
|
-
|
182
|
+
if (socket) {
|
183
|
+
socket[symbols_js_1.default.kHandledResponses]++;
|
184
|
+
debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses, sock: %o)', name, opaque[symbols_js_1.default.kRequestId], response.statusCode, socket[symbols_js_1.default.kSocketId], socket[symbols_js_1.default.kHandledResponses], formatSocket(socket));
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
debug('[%s] Request#%d get %s response headers on Unknown Socket', name, opaque[symbols_js_1.default.kRequestId], response.statusCode);
|
188
|
+
}
|
184
189
|
if (!opaque[symbols_js_1.default.kEnableRequestTiming])
|
185
190
|
return;
|
186
191
|
opaque[symbols_js_1.default.kRequestTiming].waiting = (0, utils_js_1.performanceTime)(opaque[symbols_js_1.default.kRequestStartTime]);
|
@@ -189,8 +194,9 @@ function initDiagnosticsChannel() {
|
|
189
194
|
subscribe('undici:request:trailers', (message, name) => {
|
190
195
|
const { request } = message;
|
191
196
|
const opaque = getRequestOpaque(request, kHandler);
|
192
|
-
if (!opaque || !opaque[symbols_js_1.default.kRequestId])
|
197
|
+
if (!opaque || !opaque[symbols_js_1.default.kRequestId]) {
|
193
198
|
return;
|
199
|
+
}
|
194
200
|
debug('[%s] Request#%d get response body and trailers', name, opaque[symbols_js_1.default.kRequestId]);
|
195
201
|
if (!opaque[symbols_js_1.default.kEnableRequestTiming])
|
196
202
|
return;
|
@@ -207,4 +213,3 @@ function initDiagnosticsChannel() {
|
|
207
213
|
// formatSocket(socket), error);
|
208
214
|
// });
|
209
215
|
}
|
210
|
-
exports.initDiagnosticsChannel = initDiagnosticsChannel;
|
package/dist/commonjs/index.js
CHANGED
@@ -17,7 +17,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
18
18
|
};
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
20
|
-
exports.USER_AGENT = exports.HttpClient2 = exports.HttpClient = exports.getGlobalDispatcher = exports.setGlobalDispatcher = exports.Dispatcher = exports.Agent = exports.ProxyAgent = exports.MockAgent =
|
20
|
+
exports.USER_AGENT = exports.HttpClient2 = exports.HttpClient = exports.getGlobalDispatcher = exports.setGlobalDispatcher = exports.Dispatcher = exports.Agent = exports.ProxyAgent = exports.MockAgent = void 0;
|
21
|
+
exports.getDefaultHttpClient = getDefaultHttpClient;
|
22
|
+
exports.request = request;
|
23
|
+
exports.curl = curl;
|
21
24
|
const ylru_1 = __importDefault(require("ylru"));
|
22
25
|
const HttpClient_js_1 = require("./HttpClient.js");
|
23
26
|
let httpClient;
|
@@ -28,7 +31,6 @@ function getDefaultHttpClient() {
|
|
28
31
|
}
|
29
32
|
return httpClient;
|
30
33
|
}
|
31
|
-
exports.getDefaultHttpClient = getDefaultHttpClient;
|
32
34
|
async function request(url, options) {
|
33
35
|
if (options?.socketPath) {
|
34
36
|
let domainSocketHttpclient = domainSocketHttpClients.get(options.socketPath);
|
@@ -42,7 +44,6 @@ async function request(url, options) {
|
|
42
44
|
}
|
43
45
|
return await getDefaultHttpClient().request(url, options);
|
44
46
|
}
|
45
|
-
exports.request = request;
|
46
47
|
// export curl method is keep compatible with urllib.curl()
|
47
48
|
// ```ts
|
48
49
|
// import * as urllib from 'urllib';
|
@@ -51,7 +52,6 @@ exports.request = request;
|
|
51
52
|
async function curl(url, options) {
|
52
53
|
return await request(url, options);
|
53
54
|
}
|
54
|
-
exports.curl = curl;
|
55
55
|
var undici_1 = require("undici");
|
56
56
|
Object.defineProperty(exports, "MockAgent", { enumerable: true, get: function () { return undici_1.MockAgent; } });
|
57
57
|
Object.defineProperty(exports, "ProxyAgent", { enumerable: true, get: function () { return undici_1.ProxyAgent; } });
|
package/dist/commonjs/utils.js
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.parseJSON = parseJSON;
|
4
|
+
exports.sleep = sleep;
|
5
|
+
exports.digestAuthHeader = digestAuthHeader;
|
6
|
+
exports.globalId = globalId;
|
7
|
+
exports.performanceTime = performanceTime;
|
8
|
+
exports.isReadable = isReadable;
|
4
9
|
const node_crypto_1 = require("node:crypto");
|
5
10
|
const node_stream_1 = require("node:stream");
|
6
11
|
const node_perf_hooks_1 = require("node:perf_hooks");
|
@@ -49,13 +54,11 @@ function parseJSON(data, fixJSONCtlChars) {
|
|
49
54
|
}
|
50
55
|
return data;
|
51
56
|
}
|
52
|
-
exports.parseJSON = parseJSON;
|
53
57
|
function sleep(ms) {
|
54
58
|
return new Promise(resolve => {
|
55
59
|
setTimeout(resolve, ms);
|
56
60
|
});
|
57
61
|
}
|
58
|
-
exports.sleep = sleep;
|
59
62
|
function md5(s) {
|
60
63
|
const sum = (0, node_crypto_1.createHash)('md5');
|
61
64
|
sum.update(s, 'utf8');
|
@@ -123,7 +126,6 @@ function digestAuthHeader(method, uri, wwwAuthenticate, userpass) {
|
|
123
126
|
}
|
124
127
|
return authstring;
|
125
128
|
}
|
126
|
-
exports.digestAuthHeader = digestAuthHeader;
|
127
129
|
const MAX_ID_VALUE = Math.pow(2, 31) - 10;
|
128
130
|
const globalIds = {};
|
129
131
|
function globalId(category) {
|
@@ -132,11 +134,9 @@ function globalId(category) {
|
|
132
134
|
}
|
133
135
|
return ++globalIds[category];
|
134
136
|
}
|
135
|
-
exports.globalId = globalId;
|
136
137
|
function performanceTime(startTime, now) {
|
137
138
|
return Math.floor(((now ?? node_perf_hooks_1.performance.now()) - startTime) * 1000) / 1000;
|
138
139
|
}
|
139
|
-
exports.performanceTime = performanceTime;
|
140
140
|
function isReadable(stream) {
|
141
141
|
if (typeof node_stream_1.Readable.isReadable === 'function')
|
142
142
|
return node_stream_1.Readable.isReadable(stream);
|
@@ -150,4 +150,3 @@ function isReadable(stream) {
|
|
150
150
|
&& typeof stream._read === 'function'
|
151
151
|
&& typeof stream._readableState === 'object';
|
152
152
|
}
|
153
|
-
exports.isReadable = isReadable;
|
package/dist/esm/HttpAgent.d.ts
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
2
1
|
import { LookupFunction } from 'node:net';
|
3
2
|
import { Agent, Dispatcher, buildConnector } from 'undici';
|
4
3
|
export type CheckAddressFunction = (ip: string, family: number | string) => boolean;
|
@@ -6,6 +5,7 @@ export type HttpAgentOptions = {
|
|
6
5
|
lookup?: LookupFunction;
|
7
6
|
checkAddress?: CheckAddressFunction;
|
8
7
|
connect?: buildConnector.BuildOptions;
|
8
|
+
allowH2?: boolean;
|
9
9
|
};
|
10
10
|
export declare class HttpAgent extends Agent {
|
11
11
|
#private;
|
package/dist/esm/HttpAgent.js
CHANGED
package/dist/esm/HttpClient.d.ts
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
3
|
-
/// <reference types="node" resolution-mode="require"/>
|
4
1
|
import { EventEmitter } from 'node:events';
|
5
2
|
import { LookupFunction } from 'node:net';
|
6
3
|
import { Dispatcher } from 'undici';
|
@@ -9,6 +6,8 @@ import { RequestURL, RequestOptions, RequestMeta } from './Request.js';
|
|
9
6
|
import { RawResponseWithMeta, HttpClientResponse } from './Response.js';
|
10
7
|
export type ClientOptions = {
|
11
8
|
defaultArgs?: RequestOptions;
|
9
|
+
/** Allow to use HTTP2 first. Default is `false` */
|
10
|
+
allowH2?: boolean;
|
12
11
|
/**
|
13
12
|
* Custom DNS lookup function, default is `dns.lookup`.
|
14
13
|
*/
|
package/dist/esm/HttpClient.js
CHANGED
@@ -62,7 +62,7 @@ class BlobFromStream {
|
|
62
62
|
return 'Blob';
|
63
63
|
}
|
64
64
|
}
|
65
|
-
export const HEADER_USER_AGENT = createUserAgent('node-urllib', '3.
|
65
|
+
export const HEADER_USER_AGENT = createUserAgent('node-urllib', '3.26.0');
|
66
66
|
function getFileName(stream) {
|
67
67
|
const filePath = stream.path;
|
68
68
|
if (filePath) {
|
@@ -88,11 +88,19 @@ export class HttpClient extends EventEmitter {
|
|
88
88
|
lookup: clientOptions.lookup,
|
89
89
|
checkAddress: clientOptions.checkAddress,
|
90
90
|
connect: clientOptions.connect,
|
91
|
+
allowH2: clientOptions.allowH2,
|
91
92
|
});
|
92
93
|
}
|
93
94
|
else if (clientOptions?.connect) {
|
94
95
|
this.#dispatcher = new Agent({
|
95
96
|
connect: clientOptions.connect,
|
97
|
+
allowH2: clientOptions.allowH2,
|
98
|
+
});
|
99
|
+
}
|
100
|
+
else if (clientOptions?.allowH2) {
|
101
|
+
// Support HTTP2
|
102
|
+
this.#dispatcher = new Agent({
|
103
|
+
allowH2: clientOptions.allowH2,
|
96
104
|
});
|
97
105
|
}
|
98
106
|
initDiagnosticsChannel();
|
@@ -1,4 +1,3 @@
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
2
1
|
import type { Except } from 'type-fest';
|
3
2
|
import type { IncomingHttpHeaders as HTTPIncomingHttpHeaders } from 'node:http';
|
4
3
|
export interface IncomingHttpHeaders extends Except<HTTPIncomingHttpHeaders, 'set-cookie'> {
|
package/dist/esm/Request.d.ts
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
2
|
-
/// <reference types="node" resolution-mode="require"/>
|
3
|
-
/// <reference types="node" resolution-mode="require"/>
|
4
|
-
/// <reference types="node" resolution-mode="require"/>
|
5
1
|
import type { Readable, Writable } from 'node:stream';
|
6
2
|
import type { EventEmitter } from 'node:events';
|
7
3
|
import type { Dispatcher } from 'undici';
|
package/dist/esm/Response.d.ts
CHANGED
@@ -173,8 +173,13 @@ export function initDiagnosticsChannel() {
|
|
173
173
|
return;
|
174
174
|
// get socket from opaque
|
175
175
|
const socket = opaque[symbols.kRequestSocket];
|
176
|
-
socket
|
177
|
-
|
176
|
+
if (socket) {
|
177
|
+
socket[symbols.kHandledResponses]++;
|
178
|
+
debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses, sock: %o)', name, opaque[symbols.kRequestId], response.statusCode, socket[symbols.kSocketId], socket[symbols.kHandledResponses], formatSocket(socket));
|
179
|
+
}
|
180
|
+
else {
|
181
|
+
debug('[%s] Request#%d get %s response headers on Unknown Socket', name, opaque[symbols.kRequestId], response.statusCode);
|
182
|
+
}
|
178
183
|
if (!opaque[symbols.kEnableRequestTiming])
|
179
184
|
return;
|
180
185
|
opaque[symbols.kRequestTiming].waiting = performanceTime(opaque[symbols.kRequestStartTime]);
|
@@ -183,8 +188,9 @@ export function initDiagnosticsChannel() {
|
|
183
188
|
subscribe('undici:request:trailers', (message, name) => {
|
184
189
|
const { request } = message;
|
185
190
|
const opaque = getRequestOpaque(request, kHandler);
|
186
|
-
if (!opaque || !opaque[symbols.kRequestId])
|
191
|
+
if (!opaque || !opaque[symbols.kRequestId]) {
|
187
192
|
return;
|
193
|
+
}
|
188
194
|
debug('[%s] Request#%d get response body and trailers', name, opaque[symbols.kRequestId]);
|
189
195
|
if (!opaque[symbols.kEnableRequestTiming])
|
190
196
|
return;
|
package/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "urllib",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.26.0",
|
4
4
|
"publishConfig": {
|
5
|
-
"
|
5
|
+
"access": "public"
|
6
6
|
},
|
7
|
-
"description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections,
|
7
|
+
"description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, timeout and more. Base undici API.",
|
8
8
|
"keywords": [
|
9
9
|
"urllib",
|
10
10
|
"http",
|
@@ -40,7 +40,7 @@
|
|
40
40
|
"test-keepalive": "cross-env TEST_KEEPALIVE_COUNT=50 vitest run --test-timeout 180000 keep-alive-header.test.ts",
|
41
41
|
"cov": "vitest run --coverage",
|
42
42
|
"preci": "node scripts/pre_test.js",
|
43
|
-
"ci": "npm run lint && npm run cov && node scripts/build_test.js",
|
43
|
+
"ci": "npm run lint && npm run cov && node scripts/build_test.js && attw --pack --ignore-rules no-resolution",
|
44
44
|
"contributor": "git-contributor",
|
45
45
|
"clean": "rm -rf dist",
|
46
46
|
"prepublishOnly": "npm run build"
|
@@ -59,6 +59,7 @@
|
|
59
59
|
"ylru": "^1.3.2"
|
60
60
|
},
|
61
61
|
"devDependencies": {
|
62
|
+
"@arethetypeswrong/cli": "^0.15.3",
|
62
63
|
"@tsconfig/node18": "^18.2.1",
|
63
64
|
"@tsconfig/strictest": "^2.0.2",
|
64
65
|
"@types/busboy": "^1.5.0",
|
@@ -98,10 +99,12 @@
|
|
98
99
|
"exports": {
|
99
100
|
".": {
|
100
101
|
"import": {
|
102
|
+
"source": "./src/index.ts",
|
101
103
|
"types": "./dist/esm/index.d.ts",
|
102
104
|
"default": "./dist/esm/index.js"
|
103
105
|
},
|
104
106
|
"require": {
|
107
|
+
"source": "./src/index.ts",
|
105
108
|
"types": "./dist/commonjs/index.d.ts",
|
106
109
|
"default": "./dist/commonjs/index.js"
|
107
110
|
}
|
package/src/HttpAgent.ts
CHANGED
@@ -12,6 +12,7 @@ export type HttpAgentOptions = {
|
|
12
12
|
lookup?: LookupFunction;
|
13
13
|
checkAddress?: CheckAddressFunction;
|
14
14
|
connect?: buildConnector.BuildOptions,
|
15
|
+
allowH2?: boolean;
|
15
16
|
};
|
16
17
|
|
17
18
|
class IllegalAddressError extends Error {
|
@@ -62,7 +63,7 @@ export class HttpAgent extends Agent {
|
|
62
63
|
});
|
63
64
|
};
|
64
65
|
super({
|
65
|
-
connect: { ...options.connect, lookup },
|
66
|
+
connect: { ...options.connect, lookup, allowH2: options.allowH2 },
|
66
67
|
});
|
67
68
|
this.#checkAddress = options.checkAddress;
|
68
69
|
}
|
package/src/HttpClient.ts
CHANGED
@@ -70,6 +70,8 @@ const isNode14Or16 = /v1[46]\./.test(process.version);
|
|
70
70
|
|
71
71
|
export type ClientOptions = {
|
72
72
|
defaultArgs?: RequestOptions;
|
73
|
+
/** Allow to use HTTP2 first. Default is `false` */
|
74
|
+
allowH2?: boolean;
|
73
75
|
/**
|
74
76
|
* Custom DNS lookup function, default is `dns.lookup`.
|
75
77
|
*/
|
@@ -187,10 +189,17 @@ export class HttpClient extends EventEmitter {
|
|
187
189
|
lookup: clientOptions.lookup,
|
188
190
|
checkAddress: clientOptions.checkAddress,
|
189
191
|
connect: clientOptions.connect,
|
192
|
+
allowH2: clientOptions.allowH2,
|
190
193
|
});
|
191
194
|
} else if (clientOptions?.connect) {
|
192
195
|
this.#dispatcher = new Agent({
|
193
196
|
connect: clientOptions.connect,
|
197
|
+
allowH2: clientOptions.allowH2,
|
198
|
+
});
|
199
|
+
} else if (clientOptions?.allowH2) {
|
200
|
+
// Support HTTP2
|
201
|
+
this.#dispatcher = new Agent({
|
202
|
+
allowH2: clientOptions.allowH2,
|
194
203
|
});
|
195
204
|
}
|
196
205
|
initDiagnosticsChannel();
|
@@ -184,10 +184,15 @@ export function initDiagnosticsChannel() {
|
|
184
184
|
|
185
185
|
// get socket from opaque
|
186
186
|
const socket = opaque[symbols.kRequestSocket];
|
187
|
-
socket
|
188
|
-
|
189
|
-
|
190
|
-
|
187
|
+
if (socket) {
|
188
|
+
socket[symbols.kHandledResponses]++;
|
189
|
+
debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses, sock: %o)',
|
190
|
+
name, opaque[symbols.kRequestId], response.statusCode, socket[symbols.kSocketId], socket[symbols.kHandledResponses],
|
191
|
+
formatSocket(socket));
|
192
|
+
} else {
|
193
|
+
debug('[%s] Request#%d get %s response headers on Unknown Socket',
|
194
|
+
name, opaque[symbols.kRequestId], response.statusCode);
|
195
|
+
}
|
191
196
|
|
192
197
|
if (!opaque[symbols.kEnableRequestTiming]) return;
|
193
198
|
opaque[symbols.kRequestTiming].waiting = performanceTime(opaque[symbols.kRequestStartTime]);
|
@@ -197,7 +202,9 @@ export function initDiagnosticsChannel() {
|
|
197
202
|
subscribe('undici:request:trailers', (message, name) => {
|
198
203
|
const { request } = message as DiagnosticsChannel.RequestTrailersMessage;
|
199
204
|
const opaque = getRequestOpaque(request, kHandler);
|
200
|
-
if (!opaque || !opaque[symbols.kRequestId])
|
205
|
+
if (!opaque || !opaque[symbols.kRequestId]) {
|
206
|
+
return;
|
207
|
+
}
|
201
208
|
|
202
209
|
debug('[%s] Request#%d get response body and trailers', name, opaque[symbols.kRequestId]);
|
203
210
|
|