urllib 4.6.4 → 4.6.6

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.
@@ -89,7 +89,9 @@ export function initDiagnosticsChannel() {
89
89
  const opaque = getRequestOpaque(request, kHandler);
90
90
  // ignore non HttpClient Request
91
91
  if (!opaque || !opaque[symbols.kRequestId]) return;
92
- debug('[%s] Request#%d %s %s, path: %s, headers: %o',
92
+
93
+ Reflect.set(request, symbols.kRequestInternalOpaque, opaque);
94
+ debug('[%s] Request#%d %s %s, path: %s, headers: %j',
93
95
  name, opaque[symbols.kRequestId], request.method, request.origin, request.path, request.headers);
94
96
  if (!opaque[symbols.kEnableRequestTiming]) return;
95
97
  opaque[symbols.kRequestTiming].queuing = performanceTime(opaque[symbols.kRequestStartTime]);
@@ -114,10 +116,10 @@ export function initDiagnosticsChannel() {
114
116
  sock[symbols.kSocketConnectProtocol] = connectParams.protocol;
115
117
  sock[symbols.kSocketConnectHost] = connectParams.host;
116
118
  sock[symbols.kSocketConnectPort] = connectParams.port;
117
- debug('[%s] Socket#%d connectError, connectParams: %o, error: %s, (sock: %o)',
119
+ debug('[%s] Socket#%d connectError, connectParams: %j, error: %s, (sock: %j)',
118
120
  name, sock[symbols.kSocketId], connectParams, (error as Error).message, formatSocket(sock));
119
121
  } else {
120
- debug('[%s] connectError, connectParams: %o, error: %o',
122
+ debug('[%s] connectError, connectParams: %j, error: %o',
121
123
  name, connectParams, error);
122
124
  }
123
125
  });
@@ -136,13 +138,13 @@ export function initDiagnosticsChannel() {
136
138
  socket[symbols.kSocketConnectProtocol] = connectParams.protocol;
137
139
  socket[symbols.kSocketConnectHost] = connectParams.host;
138
140
  socket[symbols.kSocketConnectPort] = connectParams.port;
139
- debug('[%s] Socket#%d connected (sock: %o)', name, socket[symbols.kSocketId], formatSocket(socket));
141
+ debug('[%s] Socket#%d connected (sock: %j)', name, socket[symbols.kSocketId], formatSocket(socket));
140
142
  });
141
143
 
142
144
  // This message is published right before the first byte of the request is written to the socket.
143
145
  subscribe('undici:client:sendHeaders', (message, name) => {
144
146
  const { request, socket } = message as DiagnosticsChannel.ClientSendHeadersMessage & { socket: SocketExtend };
145
- const opaque = getRequestOpaque(request, kHandler);
147
+ const opaque = Reflect.get(request, symbols.kRequestInternalOpaque);
146
148
  if (!opaque || !opaque[symbols.kRequestId]) {
147
149
  debug('[%s] opaque not found', name);
148
150
  return;
@@ -151,7 +153,7 @@ export function initDiagnosticsChannel() {
151
153
  (socket[symbols.kHandledRequests] as number)++;
152
154
  // attach socket to opaque
153
155
  opaque[symbols.kRequestSocket] = socket;
154
- debug('[%s] Request#%d send headers on Socket#%d (handled %d requests, sock: %o)',
156
+ debug('[%s] Request#%d send headers on Socket#%d (handled %d requests, sock: %j)',
155
157
  name, opaque[symbols.kRequestId], socket[symbols.kSocketId], socket[symbols.kHandledRequests],
156
158
  formatSocket(socket));
157
159
 
@@ -167,7 +169,7 @@ export function initDiagnosticsChannel() {
167
169
 
168
170
  subscribe('undici:request:bodySent', (message, name) => {
169
171
  const { request } = message as DiagnosticsChannel.RequestBodySentMessage;
170
- const opaque = getRequestOpaque(request, kHandler);
172
+ const opaque = Reflect.get(request, symbols.kRequestInternalOpaque);
171
173
  if (!opaque || !opaque[symbols.kRequestId]) {
172
174
  debug('[%s] opaque not found', name);
173
175
  return;
@@ -181,7 +183,7 @@ export function initDiagnosticsChannel() {
181
183
  // This message is published after the response headers have been received, i.e. the response has been completed.
182
184
  subscribe('undici:request:headers', (message, name) => {
183
185
  const { request, response } = message as DiagnosticsChannel.RequestHeadersMessage;
184
- const opaque = getRequestOpaque(request, kHandler);
186
+ const opaque = Reflect.get(request, symbols.kRequestInternalOpaque);
185
187
  if (!opaque || !opaque[symbols.kRequestId]) {
186
188
  debug('[%s] opaque not found', name);
187
189
  return;
@@ -191,7 +193,7 @@ export function initDiagnosticsChannel() {
191
193
  const socket = opaque[symbols.kRequestSocket];
192
194
  if (socket) {
193
195
  socket[symbols.kHandledResponses]++;
194
- debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses, sock: %o)',
196
+ debug('[%s] Request#%d get %s response headers on Socket#%d (handled %d responses, sock: %j)',
195
197
  name, opaque[symbols.kRequestId], response.statusCode, socket[symbols.kSocketId], socket[symbols.kHandledResponses],
196
198
  formatSocket(socket));
197
199
  } else {
@@ -206,7 +208,7 @@ export function initDiagnosticsChannel() {
206
208
  // This message is published after the response body and trailers have been received, i.e. the response has been completed.
207
209
  subscribe('undici:request:trailers', (message, name) => {
208
210
  const { request } = message as DiagnosticsChannel.RequestTrailersMessage;
209
- const opaque = getRequestOpaque(request, kHandler);
211
+ const opaque = Reflect.get(request, symbols.kRequestInternalOpaque);
210
212
  if (!opaque || !opaque[symbols.kRequestId]) {
211
213
  debug('[%s] opaque not found', name);
212
214
  return;
package/src/fetch.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { debuglog } from 'node:util';
2
3
  import {
3
4
  fetch as UndiciFetch,
4
5
  RequestInfo,
@@ -41,6 +42,8 @@ import { RawResponseWithMeta, SocketInfo } from './Response.js';
41
42
  import { IncomingHttpHeaders } from './IncomingHttpHeaders.js';
42
43
  import { BaseAgent, BaseAgentOptions } from './BaseAgent.js';
43
44
 
45
+ const debug = debuglog('urllib:fetch');
46
+
44
47
  export interface UrllibRequestInit extends RequestInit {
45
48
  // default is true
46
49
  timing?: boolean;
@@ -137,7 +140,7 @@ export class FetchFactory {
137
140
  // socket assigned
138
141
  queuing: 0,
139
142
  // dns lookup time
140
- // dnslookup: 0,
143
+ dnslookup: 0,
141
144
  // socket connected
142
145
  connected: 0,
143
146
  // request headers sent
@@ -218,8 +221,9 @@ export class FetchFactory {
218
221
  res = await UndiciFetch(input, init);
219
222
  });
220
223
  } catch (e: any) {
221
- updateSocketInfo(socketInfo, internalOpaque /* , rawError */);
224
+ updateSocketInfo(socketInfo, internalOpaque, e);
222
225
  urllibResponse.rt = performanceTime(requestStartTime);
226
+ debug('Request#%d throw error: %s', requestId, e);
223
227
  channels.fetchResponse.publish({
224
228
  fetch: fetchMeta,
225
229
  error: e,
@@ -234,7 +238,7 @@ export class FetchFactory {
234
238
 
235
239
  // get undici internal response
236
240
  const state = getResponseState(res!);
237
- updateSocketInfo(socketInfo, internalOpaque /* , rawError */);
241
+ updateSocketInfo(socketInfo, internalOpaque);
238
242
 
239
243
  urllibResponse.headers = convertHeader(res!.headers);
240
244
  urllibResponse.status = urllibResponse.statusCode = res!.status;
@@ -243,7 +247,8 @@ export class FetchFactory {
243
247
  urllibResponse.size = parseInt(urllibResponse.headers['content-length']);
244
248
  }
245
249
  urllibResponse.rt = performanceTime(requestStartTime);
246
-
250
+ debug('Request#%d got response, status: %s, headers: %j, timing: %j, socket: %j',
251
+ requestId, urllibResponse.status, urllibResponse.headers, timing, urllibResponse.socket);
247
252
  channels.fetchResponse.publish({
248
253
  fetch: fetchMeta,
249
254
  timingInfo: state.timingInfo,
package/src/index.ts CHANGED
@@ -7,16 +7,62 @@ import { HttpClient, HEADER_USER_AGENT } from './HttpClient.js';
7
7
  import { RequestOptions, RequestURL } from './Request.js';
8
8
 
9
9
  let httpClient: HttpClient;
10
+ let allowH2HttpClient: HttpClient;
11
+ let allowUnauthorizedHttpClient: HttpClient;
12
+ let allowH2AndUnauthorizedHttpClient: HttpClient;
10
13
  const domainSocketHttpClients = new LRU(50);
11
14
 
12
- export function getDefaultHttpClient(): HttpClient {
15
+ export function getDefaultHttpClient(rejectUnauthorized?: boolean, allowH2?: boolean): HttpClient {
16
+ if (rejectUnauthorized === false) {
17
+ if (allowH2) {
18
+ if (!allowH2AndUnauthorizedHttpClient) {
19
+ allowH2AndUnauthorizedHttpClient = new HttpClient({
20
+ allowH2,
21
+ connect: {
22
+ rejectUnauthorized,
23
+ },
24
+ });
25
+ }
26
+ return allowH2AndUnauthorizedHttpClient;
27
+ }
28
+
29
+ if (!allowUnauthorizedHttpClient) {
30
+ allowUnauthorizedHttpClient = new HttpClient({
31
+ connect: {
32
+ rejectUnauthorized,
33
+ },
34
+ });
35
+ }
36
+ return allowUnauthorizedHttpClient;
37
+ }
38
+
39
+ if (allowH2) {
40
+ if (!allowH2HttpClient) {
41
+ allowH2HttpClient = new HttpClient({
42
+ allowH2,
43
+ });
44
+ }
45
+ return allowH2HttpClient;
46
+ }
47
+
13
48
  if (!httpClient) {
14
49
  httpClient = new HttpClient();
15
50
  }
16
51
  return httpClient;
17
52
  }
18
53
 
19
- export async function request<T = any>(url: RequestURL, options?: RequestOptions) {
54
+ interface UrllibRequestOptions extends RequestOptions {
55
+ /**
56
+ * If `true`, the server certificate is verified against the list of supplied CAs.
57
+ * An 'error' event is emitted if verification fails.
58
+ * Default: `true`
59
+ */
60
+ rejectUnauthorized?: boolean;
61
+ /** Allow to use HTTP2 first. Default is `false` */
62
+ allowH2?: boolean;
63
+ }
64
+
65
+ export async function request<T = any>(url: RequestURL, options?: UrllibRequestOptions) {
20
66
  if (options?.socketPath) {
21
67
  let domainSocketHttpclient = domainSocketHttpClients.get<HttpClient>(options.socketPath);
22
68
  if (!domainSocketHttpclient) {
@@ -28,7 +74,7 @@ export async function request<T = any>(url: RequestURL, options?: RequestOptions
28
74
  return await domainSocketHttpclient.request<T>(url, options);
29
75
  }
30
76
 
31
- return await getDefaultHttpClient().request<T>(url, options);
77
+ return await getDefaultHttpClient(options?.rejectUnauthorized, options?.allowH2).request<T>(url, options);
32
78
  }
33
79
 
34
80
  // export curl method is keep compatible with urllib.curl()
@@ -36,7 +82,7 @@ export async function request<T = any>(url: RequestURL, options?: RequestOptions
36
82
  // import * as urllib from 'urllib';
37
83
  // urllib.curl(url);
38
84
  // ```
39
- export async function curl<T = any>(url: RequestURL, options?: RequestOptions) {
85
+ export async function curl<T = any>(url: RequestURL, options?: UrllibRequestOptions) {
40
86
  return await request<T>(url, options);
41
87
  }
42
88
 
package/src/symbols.ts CHANGED
@@ -17,5 +17,6 @@ export default {
17
17
  kEnableRequestTiming: Symbol('enable request timing or not'),
18
18
  kRequestTiming: Symbol('request timing'),
19
19
  kRequestOriginalOpaque: Symbol('request original opaque'),
20
+ kRequestInternalOpaque: Symbol('request internal opaque'),
20
21
  kErrorSocket: Symbol('socket of error'),
21
22
  };