urllib 3.19.2 → 3.20.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 CHANGED
@@ -16,7 +16,7 @@
16
16
  [download-url]: https://npmjs.org/package/urllib
17
17
 
18
18
  Request HTTP URLs in a complex world — basic
19
- and digest authentication, redirections, cookies, timeout and more.
19
+ and digest authentication, redirections, timeout and more.
20
20
 
21
21
  ## Install
22
22
 
@@ -290,14 +290,15 @@ Fork [undici benchmarks script](https://github.com/fengmk2/undici/blob/urllib-be
290
290
 
291
291
  |[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/32174276?v=4" width="100px;"/><br/><sub><b>semantic-release-bot</b></sub>](https://github.com/semantic-release-bot)<br/>|[<img src="https://avatars.githubusercontent.com/u/288288?v=4" width="100px;"/><br/><sub><b>xingrz</b></sub>](https://github.com/xingrz)<br/>|[<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/>|[<img src="https://avatars.githubusercontent.com/u/327019?v=4" width="100px;"/><br/><sub><b>JacksonTian</b></sub>](https://github.com/JacksonTian)<br/>|
292
292
  | :---: | :---: | :---: | :---: | :---: | :---: |
293
- |[<img src="https://avatars.githubusercontent.com/u/543405?v=4" width="100px;"/><br/><sub><b>ibigbug</b></sub>](https://github.com/ibigbug)<br/>|[<img src="https://avatars.githubusercontent.com/u/14790466?v=4" width="100px;"/><br/><sub><b>greenkeeperio-bot</b></sub>](https://github.com/greenkeeperio-bot)<br/>|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/6897780?v=4" width="100px;"/><br/><sub><b>killagu</b></sub>](https://github.com/killagu)<br/>|[<img src="https://avatars.githubusercontent.com/u/5381764?v=4" width="100px;"/><br/><sub><b>paambaati</b></sub>](https://github.com/paambaati)<br/>|[<img src="https://avatars.githubusercontent.com/u/1433247?v=4" width="100px;"/><br/><sub><b>denghongcai</b></sub>](https://github.com/denghongcai)<br/>|
294
- |[<img src="https://avatars.githubusercontent.com/u/4635838?v=4" width="100px;"/><br/><sub><b>gemwuu</b></sub>](https://github.com/gemwuu)<br/>|[<img src="https://avatars.githubusercontent.com/u/2842176?v=4" width="100px;"/><br/><sub><b>XadillaX</b></sub>](https://github.com/XadillaX)<br/>|[<img src="https://avatars.githubusercontent.com/u/1147375?v=4" width="100px;"/><br/><sub><b>alsotang</b></sub>](https://github.com/alsotang)<br/>|[<img src="https://avatars.githubusercontent.com/u/546535?v=4" width="100px;"/><br/><sub><b>leoner</b></sub>](https://github.com/leoner)<br/>|[<img src="https://avatars.githubusercontent.com/u/19908330?v=4" width="100px;"/><br/><sub><b>hyj1991</b></sub>](https://github.com/hyj1991)<br/>|[<img src="https://avatars.githubusercontent.com/u/1747852?v=4" width="100px;"/><br/><sub><b>isayme</b></sub>](https://github.com/isayme)<br/>|
295
- |[<img src="https://avatars.githubusercontent.com/u/252317?v=4" width="100px;"/><br/><sub><b>cyjake</b></sub>](https://github.com/cyjake)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>|[<img src="https://avatars.githubusercontent.com/u/309219?v=4" width="100px;"/><br/><sub><b>chadxz</b></sub>](https://github.com/chadxz)<br/>|[<img src="https://avatars.githubusercontent.com/u/2055702?v=4" width="100px;"/><br/><sub><b>adapt0</b></sub>](https://github.com/adapt0)<br/>|[<img src="https://avatars.githubusercontent.com/u/5139554?v=4" width="100px;"/><br/><sub><b>danielwpz</b></sub>](https://github.com/danielwpz)<br/>|[<img src="https://avatars.githubusercontent.com/u/5127897?v=4" width="100px;"/><br/><sub><b>danielsss</b></sub>](https://github.com/danielsss)<br/>|
296
- |[<img src="https://avatars.githubusercontent.com/u/3367820?v=4" width="100px;"/><br/><sub><b>Jeff-Tian</b></sub>](https://github.com/Jeff-Tian)<br/>|[<img src="https://avatars.githubusercontent.com/u/17075261?v=4" width="100px;"/><br/><sub><b>nick-ng</b></sub>](https://github.com/nick-ng)<br/>|[<img src="https://avatars.githubusercontent.com/u/1706595?v=4" width="100px;"/><br/><sub><b>rishavsharan</b></sub>](https://github.com/rishavsharan)<br/>|[<img src="https://avatars.githubusercontent.com/u/1886161?v=4" width="100px;"/><br/><sub><b>willizm</b></sub>](https://github.com/willizm)<br/>|[<img src="https://avatars.githubusercontent.com/u/7227589?v=4" width="100px;"/><br/><sub><b>davidkhala</b></sub>](https://github.com/davidkhala)<br/>|[<img src="https://avatars.githubusercontent.com/u/535479?v=4" width="100px;"/><br/><sub><b>aleafs</b></sub>](https://github.com/aleafs)<br/>|
297
- |[<img src="https://avatars.githubusercontent.com/u/3689968?v=4" width="100px;"/><br/><sub><b>Amunu</b></sub>](https://github.com/Amunu)<br/>|[<img src="https://avatars.githubusercontent.com/in/9426?v=4" width="100px;"/><br/><sub><b>azure-pipelines[bot]</b></sub>](https://github.com/apps/azure-pipelines)<br/>|[<img src="https://avatars.githubusercontent.com/u/108602490?v=4" width="100px;"/><br/><sub><b>capsice</b></sub>](https://github.com/capsice)<br/>|[<img src="https://avatars.githubusercontent.com/u/1281323?v=4" width="100px;"/><br/><sub><b>changzhiwin</b></sub>](https://github.com/changzhiwin)<br/>|[<img src="https://avatars.githubusercontent.com/u/929503?v=4" width="100px;"/><br/><sub><b>yuzhigang33</b></sub>](https://github.com/yuzhigang33)<br/>|[<img src="https://avatars.githubusercontent.com/u/5574625?v=4" width="100px;"/><br/><sub><b>elrrrrrrr</b></sub>](https://github.com/elrrrrrrr)<br/>|
298
- [<img src="https://avatars.githubusercontent.com/u/981128?v=4" width="100px;"/><br/><sub><b>fishbar</b></sub>](https://github.com/fishbar)<br/>|[<img src="https://avatars.githubusercontent.com/u/1207064?v=4" width="100px;"/><br/><sub><b>gxcsoccer</b></sub>](https://github.com/gxcsoccer)<br/>|[<img src="https://avatars.githubusercontent.com/u/17476119?v=4" width="100px;"/><br/><sub><b>mars-coder</b></sub>](https://github.com/mars-coder)<br/>|[<img src="https://avatars.githubusercontent.com/u/929179?v=4" width="100px;"/><br/><sub><b>rockdai</b></sub>](https://github.com/rockdai)<br/>|[<img src="https://avatars.githubusercontent.com/u/2196373?v=4" width="100px;"/><br/><sub><b>dickeylth</b></sub>](https://github.com/dickeylth)<br/>|[<img src="https://avatars.githubusercontent.com/u/13050025?v=4" width="100px;"/><br/><sub><b>aladdin-add</b></sub>](https://github.com/aladdin-add)<br/>
299
-
300
- This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Sep 16 2023 01:02:26 GMT+0800`.
293
+ |[<img src="https://avatars.githubusercontent.com/u/543405?v=4" width="100px;"/><br/><sub><b>ibigbug</b></sub>](https://github.com/ibigbug)<br/>|[<img src="https://avatars.githubusercontent.com/u/14790466?v=4" width="100px;"/><br/><sub><b>greenkeeperio-bot</b></sub>](https://github.com/greenkeeperio-bot)<br/>|[<img src="https://avatars.githubusercontent.com/u/227713?v=4" width="100px;"/><br/><sub><b>atian25</b></sub>](https://github.com/atian25)<br/>|[<img src="https://avatars.githubusercontent.com/u/6897780?v=4" width="100px;"/><br/><sub><b>killagu</b></sub>](https://github.com/killagu)<br/>|[<img src="https://avatars.githubusercontent.com/u/5381764?v=4" width="100px;"/><br/><sub><b>paambaati</b></sub>](https://github.com/paambaati)<br/>|[<img src="https://avatars.githubusercontent.com/u/199635?v=4" width="100px;"/><br/><sub><b>tremby</b></sub>](https://github.com/tremby)<br/>|
294
+ |[<img src="https://avatars.githubusercontent.com/u/1433247?v=4" width="100px;"/><br/><sub><b>denghongcai</b></sub>](https://github.com/denghongcai)<br/>|[<img src="https://avatars.githubusercontent.com/u/4635838?v=4" width="100px;"/><br/><sub><b>gemwuu</b></sub>](https://github.com/gemwuu)<br/>|[<img src="https://avatars.githubusercontent.com/u/2842176?v=4" width="100px;"/><br/><sub><b>XadillaX</b></sub>](https://github.com/XadillaX)<br/>|[<img src="https://avatars.githubusercontent.com/u/1147375?v=4" width="100px;"/><br/><sub><b>alsotang</b></sub>](https://github.com/alsotang)<br/>|[<img src="https://avatars.githubusercontent.com/u/546535?v=4" width="100px;"/><br/><sub><b>leoner</b></sub>](https://github.com/leoner)<br/>|[<img src="https://avatars.githubusercontent.com/u/19908330?v=4" width="100px;"/><br/><sub><b>hyj1991</b></sub>](https://github.com/hyj1991)<br/>|
295
+ |[<img src="https://avatars.githubusercontent.com/u/1747852?v=4" width="100px;"/><br/><sub><b>isayme</b></sub>](https://github.com/isayme)<br/>|[<img src="https://avatars.githubusercontent.com/u/252317?v=4" width="100px;"/><br/><sub><b>cyjake</b></sub>](https://github.com/cyjake)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>|[<img src="https://avatars.githubusercontent.com/u/309219?v=4" width="100px;"/><br/><sub><b>chadxz</b></sub>](https://github.com/chadxz)<br/>|[<img src="https://avatars.githubusercontent.com/u/2055702?v=4" width="100px;"/><br/><sub><b>adapt0</b></sub>](https://github.com/adapt0)<br/>|[<img src="https://avatars.githubusercontent.com/u/5139554?v=4" width="100px;"/><br/><sub><b>danielwpz</b></sub>](https://github.com/danielwpz)<br/>|
296
+ |[<img src="https://avatars.githubusercontent.com/u/5127897?v=4" width="100px;"/><br/><sub><b>danielsss</b></sub>](https://github.com/danielsss)<br/>|[<img src="https://avatars.githubusercontent.com/u/3367820?v=4" width="100px;"/><br/><sub><b>Jeff-Tian</b></sub>](https://github.com/Jeff-Tian)<br/>|[<img src="https://avatars.githubusercontent.com/u/17075261?v=4" width="100px;"/><br/><sub><b>nick-ng</b></sub>](https://github.com/nick-ng)<br/>|[<img src="https://avatars.githubusercontent.com/u/1706595?v=4" width="100px;"/><br/><sub><b>rishavsharan</b></sub>](https://github.com/rishavsharan)<br/>|[<img src="https://avatars.githubusercontent.com/u/1886161?v=4" width="100px;"/><br/><sub><b>willizm</b></sub>](https://github.com/willizm)<br/>|[<img src="https://avatars.githubusercontent.com/u/7227589?v=4" width="100px;"/><br/><sub><b>davidkhala</b></sub>](https://github.com/davidkhala)<br/>|
297
+ |[<img src="https://avatars.githubusercontent.com/u/535479?v=4" width="100px;"/><br/><sub><b>aleafs</b></sub>](https://github.com/aleafs)<br/>|[<img src="https://avatars.githubusercontent.com/u/3689968?v=4" width="100px;"/><br/><sub><b>Amunu</b></sub>](https://github.com/Amunu)<br/>|[<img src="https://avatars.githubusercontent.com/in/9426?v=4" width="100px;"/><br/><sub><b>azure-pipelines[bot]</b></sub>](https://github.com/apps/azure-pipelines)<br/>|[<img src="https://avatars.githubusercontent.com/u/108602490?v=4" width="100px;"/><br/><sub><b>capsice</b></sub>](https://github.com/capsice)<br/>|[<img src="https://avatars.githubusercontent.com/u/1281323?v=4" width="100px;"/><br/><sub><b>changzhiwin</b></sub>](https://github.com/changzhiwin)<br/>|[<img src="https://avatars.githubusercontent.com/u/929503?v=4" width="100px;"/><br/><sub><b>yuzhigang33</b></sub>](https://github.com/yuzhigang33)<br/>|
298
+ |[<img src="https://avatars.githubusercontent.com/u/5574625?v=4" width="100px;"/><br/><sub><b>elrrrrrrr</b></sub>](https://github.com/elrrrrrrr)<br/>|[<img src="https://avatars.githubusercontent.com/u/981128?v=4" width="100px;"/><br/><sub><b>fishbar</b></sub>](https://github.com/fishbar)<br/>|[<img src="https://avatars.githubusercontent.com/u/1207064?v=4" width="100px;"/><br/><sub><b>gxcsoccer</b></sub>](https://github.com/gxcsoccer)<br/>|[<img src="https://avatars.githubusercontent.com/u/17476119?v=4" width="100px;"/><br/><sub><b>mars-coder</b></sub>](https://github.com/mars-coder)<br/>|[<img src="https://avatars.githubusercontent.com/u/929179?v=4" width="100px;"/><br/><sub><b>rockdai</b></sub>](https://github.com/rockdai)<br/>|[<img src="https://avatars.githubusercontent.com/u/2196373?v=4" width="100px;"/><br/><sub><b>dickeylth</b></sub>](https://github.com/dickeylth)<br/>|
299
+ [<img src="https://avatars.githubusercontent.com/u/13050025?v=4" width="100px;"/><br/><sub><b>aladdin-add</b></sub>](https://github.com/aladdin-add)<br/>
300
+
301
+ 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`.
301
302
 
302
303
  <!-- GITCONTRIBUTOR_END -->
303
304
 
@@ -3,6 +3,7 @@
3
3
  /// <reference types="node" />
4
4
  import { EventEmitter } from 'node:events';
5
5
  import { LookupFunction } from 'node:net';
6
+ import { Dispatcher } from 'undici';
6
7
  import { CheckAddressFunction } from './HttpAgent.js';
7
8
  import { RequestURL, RequestOptions, RequestMeta } from './Request.js';
8
9
  import { RawResponseWithMeta, HttpClientResponse } from './Response.js';
@@ -34,6 +35,10 @@ export type ClientOptions = {
34
35
  * socketPath string | null (optional) - Default: null - An IPC endpoint, either Unix domain socket or Windows named pipe
35
36
  */
36
37
  socketPath?: string | null;
38
+ /**
39
+ * connect timeout, default is 10000ms
40
+ */
41
+ timeout?: number;
37
42
  };
38
43
  };
39
44
  export declare const HEADER_USER_AGENT: string;
@@ -48,6 +53,8 @@ export type ResponseDiagnosticsMessage = {
48
53
  export declare class HttpClient extends EventEmitter {
49
54
  #private;
50
55
  constructor(clientOptions?: ClientOptions);
56
+ getDispatcher(): Dispatcher;
57
+ setDispatcher(dispatcher: Dispatcher): void;
51
58
  request<T = any>(url: RequestURL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
52
59
  curl<T = any>(url: RequestURL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
53
60
  }
@@ -73,7 +73,7 @@ class HttpClientRequestTimeoutError extends Error {
73
73
  Error.captureStackTrace(this, this.constructor);
74
74
  }
75
75
  }
76
- exports.HEADER_USER_AGENT = (0, default_user_agent_1.default)('node-urllib', '3.19.2');
76
+ exports.HEADER_USER_AGENT = (0, default_user_agent_1.default)('node-urllib', '3.20.0');
77
77
  function getFileName(stream) {
78
78
  const filePath = stream.path;
79
79
  if (filePath) {
@@ -94,15 +94,26 @@ class HttpClient extends node_events_1.EventEmitter {
94
94
  constructor(clientOptions) {
95
95
  super();
96
96
  this.#defaultArgs = clientOptions?.defaultArgs;
97
- if (clientOptions?.lookup || clientOptions?.checkAddress || clientOptions?.connect) {
97
+ if (clientOptions?.lookup || clientOptions?.checkAddress) {
98
98
  this.#dispatcher = new HttpAgent_js_1.HttpAgent({
99
99
  lookup: clientOptions.lookup,
100
100
  checkAddress: clientOptions.checkAddress,
101
101
  connect: clientOptions.connect,
102
102
  });
103
103
  }
104
+ else if (clientOptions?.connect) {
105
+ this.#dispatcher = new undici_1.Agent({
106
+ connect: clientOptions.connect,
107
+ });
108
+ }
104
109
  (0, diagnosticsChannel_js_1.initDiagnosticsChannel)();
105
110
  }
111
+ getDispatcher() {
112
+ return this.#dispatcher ?? (0, undici_1.getGlobalDispatcher)();
113
+ }
114
+ setDispatcher(dispatcher) {
115
+ this.#dispatcher = dispatcher;
116
+ }
106
117
  async request(url, options) {
107
118
  return await this.#requestInternal(url, options);
108
119
  }
@@ -126,7 +137,8 @@ class HttpClient extends node_events_1.EventEmitter {
126
137
  requestUrl = new URL((0, node_url_1.format)(url));
127
138
  }
128
139
  else {
129
- requestUrl = url;
140
+ // or even if not, we clone to avoid mutating it
141
+ requestUrl = new URL(url.toString());
130
142
  }
131
143
  }
132
144
  const method = (options?.method ?? 'GET').toUpperCase();
@@ -25,7 +25,7 @@ async function request(url, options) {
25
25
  return await httpclient.request(url, options);
26
26
  }
27
27
  exports.request = request;
28
- // export curl method is keep compatible with urlib.curl()
28
+ // export curl method is keep compatible with urllib.curl()
29
29
  // ```ts
30
30
  // import * as urllib from 'urllib';
31
31
  // urllib.curl(url);
@@ -1 +1,3 @@
1
- {"type":"commonjs"}
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -5,12 +5,12 @@ const node_crypto_1 = require("node:crypto");
5
5
  const node_stream_1 = require("node:stream");
6
6
  const node_perf_hooks_1 = require("node:perf_hooks");
7
7
  const JSONCtlCharsMap = {
8
- '"': '\\"',
9
- '\\': '\\\\',
10
- '\b': '\\b',
11
- '\f': '\\f',
12
- '\n': '\\n',
13
- '\r': '\\r',
8
+ '"': '\\"', // \u0022
9
+ '\\': '\\\\', // \u005c
10
+ '\b': '\\b', // \u0008
11
+ '\f': '\\f', // \u000c
12
+ '\n': '\\n', // \u000a
13
+ '\r': '\\r', // \u000d
14
14
  '\t': '\\t', // \u0009
15
15
  };
16
16
  /* eslint no-control-regex: "off"*/
@@ -3,6 +3,7 @@
3
3
  /// <reference types="node" resolution-mode="require"/>
4
4
  import { EventEmitter } from 'node:events';
5
5
  import { LookupFunction } from 'node:net';
6
+ import { Dispatcher } from 'undici';
6
7
  import { CheckAddressFunction } from './HttpAgent.js';
7
8
  import { RequestURL, RequestOptions, RequestMeta } from './Request.js';
8
9
  import { RawResponseWithMeta, HttpClientResponse } from './Response.js';
@@ -34,6 +35,10 @@ export type ClientOptions = {
34
35
  * socketPath string | null (optional) - Default: null - An IPC endpoint, either Unix domain socket or Windows named pipe
35
36
  */
36
37
  socketPath?: string | null;
38
+ /**
39
+ * connect timeout, default is 10000ms
40
+ */
41
+ timeout?: number;
37
42
  };
38
43
  };
39
44
  export declare const HEADER_USER_AGENT: string;
@@ -48,6 +53,8 @@ export type ResponseDiagnosticsMessage = {
48
53
  export declare class HttpClient extends EventEmitter {
49
54
  #private;
50
55
  constructor(clientOptions?: ClientOptions);
56
+ getDispatcher(): Dispatcher;
57
+ setDispatcher(dispatcher: Dispatcher): void;
51
58
  request<T = any>(url: RequestURL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
52
59
  curl<T = any>(url: RequestURL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
53
60
  }
@@ -10,7 +10,7 @@ import { basename } from 'node:path';
10
10
  import { createReadStream } from 'node:fs';
11
11
  import { format as urlFormat } from 'node:url';
12
12
  import { performance } from 'node:perf_hooks';
13
- import { FormData as FormDataNative, request as undiciRequest, } from 'undici';
13
+ import { FormData as FormDataNative, request as undiciRequest, Agent, getGlobalDispatcher, } from 'undici';
14
14
  import { FormData as FormDataNode } from 'formdata-node';
15
15
  import { FormDataEncoder } from 'form-data-encoder';
16
16
  import createUserAgent from 'default-user-agent';
@@ -67,7 +67,7 @@ class HttpClientRequestTimeoutError extends Error {
67
67
  Error.captureStackTrace(this, this.constructor);
68
68
  }
69
69
  }
70
- export const HEADER_USER_AGENT = createUserAgent('node-urllib', '3.19.2');
70
+ export const HEADER_USER_AGENT = createUserAgent('node-urllib', '3.20.0');
71
71
  function getFileName(stream) {
72
72
  const filePath = stream.path;
73
73
  if (filePath) {
@@ -88,15 +88,26 @@ export class HttpClient extends EventEmitter {
88
88
  constructor(clientOptions) {
89
89
  super();
90
90
  this.#defaultArgs = clientOptions?.defaultArgs;
91
- if (clientOptions?.lookup || clientOptions?.checkAddress || clientOptions?.connect) {
91
+ if (clientOptions?.lookup || clientOptions?.checkAddress) {
92
92
  this.#dispatcher = new HttpAgent({
93
93
  lookup: clientOptions.lookup,
94
94
  checkAddress: clientOptions.checkAddress,
95
95
  connect: clientOptions.connect,
96
96
  });
97
97
  }
98
+ else if (clientOptions?.connect) {
99
+ this.#dispatcher = new Agent({
100
+ connect: clientOptions.connect,
101
+ });
102
+ }
98
103
  initDiagnosticsChannel();
99
104
  }
105
+ getDispatcher() {
106
+ return this.#dispatcher ?? getGlobalDispatcher();
107
+ }
108
+ setDispatcher(dispatcher) {
109
+ this.#dispatcher = dispatcher;
110
+ }
100
111
  async request(url, options) {
101
112
  return await this.#requestInternal(url, options);
102
113
  }
@@ -120,7 +131,8 @@ export class HttpClient extends EventEmitter {
120
131
  requestUrl = new URL(urlFormat(url));
121
132
  }
122
133
  else {
123
- requestUrl = url;
134
+ // or even if not, we clone to avoid mutating it
135
+ requestUrl = new URL(url.toString());
124
136
  }
125
137
  }
126
138
  const method = (options?.method ?? 'GET').toUpperCase();
package/dist/esm/index.js CHANGED
@@ -18,7 +18,7 @@ export async function request(url, options) {
18
18
  }
19
19
  return await httpclient.request(url, options);
20
20
  }
21
- // export curl method is keep compatible with urlib.curl()
21
+ // export curl method is keep compatible with urllib.curl()
22
22
  // ```ts
23
23
  // import * as urllib from 'urllib';
24
24
  // urllib.curl(url);
@@ -1 +1,3 @@
1
- {"type":"module"}
1
+ {
2
+ "type": "module"
3
+ }
package/dist/esm/utils.js CHANGED
@@ -2,12 +2,12 @@ import { randomBytes, createHash } from 'node:crypto';
2
2
  import { Readable } from 'node:stream';
3
3
  import { performance } from 'node:perf_hooks';
4
4
  const JSONCtlCharsMap = {
5
- '"': '\\"',
6
- '\\': '\\\\',
7
- '\b': '\\b',
8
- '\f': '\\f',
9
- '\n': '\\n',
10
- '\r': '\\r',
5
+ '"': '\\"', // \u0022
6
+ '\\': '\\\\', // \u005c
7
+ '\b': '\\b', // \u0008
8
+ '\f': '\\f', // \u000c
9
+ '\n': '\\n', // \u000a
10
+ '\r': '\\r', // \u000d
11
11
  '\t': '\\t', // \u0009
12
12
  };
13
13
  /* eslint no-control-regex: "off"*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "urllib",
3
- "version": "3.19.2",
3
+ "version": "3.20.0",
4
4
  "publishConfig": {
5
5
  "tag": "latest"
6
6
  },
@@ -18,30 +18,6 @@
18
18
  ],
19
19
  "author": "fengmk2 <fengmk2@gmail.com> (https://github.com/fengmk2)",
20
20
  "homepage": "https://github.com/node-modules/urllib",
21
- "type": "module",
22
- "tshy": {
23
- "exports": {
24
- ".": "./src/index.ts",
25
- "./package.json": "./package.json"
26
- }
27
- },
28
- "exports": {
29
- ".": {
30
- "import": {
31
- "types": "./dist/esm/index.d.ts",
32
- "default": "./dist/esm/index.js"
33
- },
34
- "require": {
35
- "types": "./dist/commonjs/index.d.ts",
36
- "default": "./dist/commonjs/index.js"
37
- }
38
- },
39
- "./package.json": "./package.json"
40
- },
41
- "files": [
42
- "dist",
43
- "src"
44
- ],
45
21
  "repository": {
46
22
  "type": "git",
47
23
  "url": "git://github.com/node-modules/urllib.git"
@@ -62,6 +38,7 @@
62
38
  "test": "npm run lint && vitest run",
63
39
  "test-keepalive": "cross-env TEST_KEEPALIVE_COUNT=50 vitest run --test-timeout 180000 keep-alive-header.test.ts",
64
40
  "cov": "vitest run --coverage",
41
+ "preci": "node scripts/pre_test.js",
65
42
  "ci": "npm run lint && npm run cov && node scripts/build_test.js",
66
43
  "contributor": "git-contributor",
67
44
  "clean": "rm -rf dist",
@@ -91,7 +68,7 @@
91
68
  "@types/qs": "^6.9.7",
92
69
  "@types/selfsigned": "^2.0.1",
93
70
  "@types/tar-stream": "^2.2.2",
94
- "@vitest/coverage-v8": "^0.32.0",
71
+ "@vitest/coverage-v8": "beta",
95
72
  "busboy": "^1.6.0",
96
73
  "cross-env": "^7.0.3",
97
74
  "eslint": "^8.25.0",
@@ -101,14 +78,39 @@
101
78
  "proxy": "^1.0.2",
102
79
  "selfsigned": "^2.0.1",
103
80
  "tar-stream": "^2.2.0",
104
- "tshy": "^1.0.0-3",
81
+ "tshy": "^1.0.0",
105
82
  "tshy-after": "^1.0.0",
106
83
  "typescript": "^5.0.4",
107
- "vitest": "^0.32.0"
84
+ "vitest": "beta"
108
85
  },
109
86
  "engines": {
110
87
  "node": ">= 14.19.3"
111
88
  },
112
89
  "license": "MIT",
113
- "types": "./dist/commonjs/index.d.ts"
90
+ "type": "module",
91
+ "tshy": {
92
+ "exports": {
93
+ ".": "./src/index.ts",
94
+ "./package.json": "./package.json"
95
+ }
96
+ },
97
+ "exports": {
98
+ ".": {
99
+ "import": {
100
+ "types": "./dist/esm/index.d.ts",
101
+ "default": "./dist/esm/index.js"
102
+ },
103
+ "require": {
104
+ "types": "./dist/commonjs/index.d.ts",
105
+ "default": "./dist/commonjs/index.js"
106
+ }
107
+ },
108
+ "./package.json": "./package.json"
109
+ },
110
+ "files": [
111
+ "dist",
112
+ "src"
113
+ ],
114
+ "types": "./dist/commonjs/index.d.ts",
115
+ "main": "./dist/commonjs/index.js"
114
116
  }
package/src/HttpClient.ts CHANGED
@@ -20,6 +20,8 @@ import {
20
20
  FormData as FormDataNative,
21
21
  request as undiciRequest,
22
22
  Dispatcher,
23
+ Agent,
24
+ getGlobalDispatcher,
23
25
  } from 'undici';
24
26
  import { FormData as FormDataNode } from 'formdata-node';
25
27
  import { FormDataEncoder } from 'form-data-encoder';
@@ -86,11 +88,14 @@ export type ClientOptions = {
86
88
  * An 'error' event is emitted if verification fails.Default: true.
87
89
  */
88
90
  rejectUnauthorized?: boolean;
89
-
90
91
  /**
91
92
  * socketPath string | null (optional) - Default: null - An IPC endpoint, either Unix domain socket or Windows named pipe
92
93
  */
93
94
  socketPath?: string | null;
95
+ /**
96
+ * connect timeout, default is 10000ms
97
+ */
98
+ timeout?: number;
94
99
  },
95
100
  };
96
101
 
@@ -168,16 +173,28 @@ export class HttpClient extends EventEmitter {
168
173
  constructor(clientOptions?: ClientOptions) {
169
174
  super();
170
175
  this.#defaultArgs = clientOptions?.defaultArgs;
171
- if (clientOptions?.lookup || clientOptions?.checkAddress || clientOptions?.connect) {
176
+ if (clientOptions?.lookup || clientOptions?.checkAddress) {
172
177
  this.#dispatcher = new HttpAgent({
173
178
  lookup: clientOptions.lookup,
174
179
  checkAddress: clientOptions.checkAddress,
175
180
  connect: clientOptions.connect,
176
181
  });
182
+ } else if (clientOptions?.connect) {
183
+ this.#dispatcher = new Agent({
184
+ connect: clientOptions.connect,
185
+ });
177
186
  }
178
187
  initDiagnosticsChannel();
179
188
  }
180
189
 
190
+ getDispatcher() {
191
+ return this.#dispatcher ?? getGlobalDispatcher();
192
+ }
193
+
194
+ setDispatcher(dispatcher: Dispatcher) {
195
+ this.#dispatcher = dispatcher;
196
+ }
197
+
181
198
  async request<T = any>(url: RequestURL, options?: RequestOptions) {
182
199
  return await this.#requestInternal<T>(url, options);
183
200
  }
@@ -201,7 +218,8 @@ export class HttpClient extends EventEmitter {
201
218
  // url maybe url.parse(url) object in urllib2
202
219
  requestUrl = new URL(urlFormat(url));
203
220
  } else {
204
- requestUrl = url;
221
+ // or even if not, we clone to avoid mutating it
222
+ requestUrl = new URL(url.toString());
205
223
  }
206
224
  }
207
225
 
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ import { RequestOptions, RequestURL } from './Request.js';
4
4
 
5
5
  let httpclient: HttpClient;
6
6
  const domainSocketHttpclients = new LRU(50);
7
+
7
8
  export async function request<T = any>(url: RequestURL, options?: RequestOptions) {
8
9
  if (options?.socketPath) {
9
10
  let domainSocketHttpclient = domainSocketHttpclients.get<HttpClient>(options.socketPath);
@@ -22,7 +23,7 @@ export async function request<T = any>(url: RequestURL, options?: RequestOptions
22
23
  return await httpclient.request<T>(url, options);
23
24
  }
24
25
 
25
- // export curl method is keep compatible with urlib.curl()
26
+ // export curl method is keep compatible with urllib.curl()
26
27
  // ```ts
27
28
  // import * as urllib from 'urllib';
28
29
  // urllib.curl(url);
@@ -53,7 +54,6 @@ export {
53
54
  IncomingHttpHeaders,
54
55
  } from './IncomingHttpHeaders.js';
55
56
 
56
-
57
57
  export default {
58
58
  request,
59
59
  curl,