@wiajs/request 3.0.2 → 3.0.5

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/index.js CHANGED
@@ -1 +1 @@
1
- export {default} from './lib'
1
+ export {default} from './lib/index.js'
package/lib/index.js CHANGED
@@ -6,14 +6,15 @@
6
6
  import Request from './request.js';
7
7
  import utils from './utils.js';
8
8
  const log = Log({
9
- env: `wia:req:${name(__filename)}`
10
- });
9
+ env: `wia:req:${name(import.meta.url)}`
10
+ }) // __filename
11
+ ;
11
12
  (function detectUnsupportedEnvironment() {
12
13
  const looksLikeNode = typeof process !== 'undefined';
13
14
  const looksLikeBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
14
15
  const looksLikeV8 = utils.isFunction(Error.captureStackTrace);
15
16
  if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {
16
- log.warn('The follow-redirects package should be excluded from browser builds.');
17
+ console.warn('The follow-redirects package should be excluded from browser builds.');
17
18
  }
18
19
  })();
19
20
  /**
@@ -27,6 +28,7 @@ const log = Log({
27
28
  * @param {*} callback
28
29
  * @returns
29
30
  */ function init(uri, options, callback) {
31
+ let R;
30
32
  try {
31
33
  // Parse parameters, ensuring that input is an object
32
34
  if (utils.isURL(uri)) uri = utils.spreadUrlObject(uri);
@@ -50,6 +52,7 @@ const log = Log({
50
52
  opts: options,
51
53
  cb: callback
52
54
  };
55
+ // log({R}, 'init')
53
56
  } catch (e) {
54
57
  log.err(e, 'init');
55
58
  }
@@ -66,15 +69,14 @@ const log = Log({
66
69
  * @param {*} callback/null
67
70
  * @returns
68
71
  */ function request(uri, options, callback) {
69
- let R1 = null;
72
+ let R = null;
70
73
  try {
71
74
  const { opts, cb } = init(uri, options, callback);
72
- // log.debug('request', {options})
73
- R1 = new Request(opts, cb);
75
+ R = new Request(opts, cb);
74
76
  } catch (e) {
75
77
  log.err(e, 'request');
76
78
  }
77
- return R1;
79
+ return R;
78
80
  }
79
81
  /**
80
82
  * 执行简单的非stream数据请求
@@ -84,6 +86,7 @@ const log = Log({
84
86
  * @returns {Request} Duplex 流
85
87
  */ function fn(verb) {
86
88
  const method = verb.toUpperCase();
89
+ // @ts-ignore
87
90
  return (uri, options, callback)=>{
88
91
  const { opts, cb } = init(uri, options, callback);
89
92
  opts.method = method;
package/lib/request.js CHANGED
@@ -14,8 +14,9 @@ import ZlibTransform from './ZlibTransform.js';
14
14
  import utils from './utils.js';
15
15
  import Caseless from './caseless.js';
16
16
  const log = Log({
17
- env: `wia:req:${name(__filename)}`
18
- });
17
+ env: `wia:req:${name(import.meta.url)}`
18
+ }) // __filename
19
+ ;
19
20
  const httpModules = {
20
21
  'http:': http,
21
22
  'https:': https
@@ -51,7 +52,7 @@ const writeEventEmit = Object.create(null);
51
52
  for (const ev of writeEvents)writeEventEmit[ev] = function(...args) {
52
53
  const m = this // 事件回调,this === clientRequest 实例
53
54
  ;
54
- log.debug('req event', {
55
+ log('req event', {
55
56
  ev
56
57
  });
57
58
  m.redirectReq.emit(ev, ...args) // req 事情映射到 redirectReq 上触发
@@ -71,7 +72,7 @@ const readEventEmit = Object.create(null);
71
72
  for (const ev of readEvents)readEventEmit[ev] = function(...args) {
72
73
  const m = this // 事件回调,this === clientRequest 实例
73
74
  ;
74
- log.debug('res event', {
75
+ log('res event', {
75
76
  ev
76
77
  });
77
78
  m.redirectReq.emit(ev, ...args) // 向上触发事件
@@ -88,18 +89,19 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
88
89
  */ export default class Request extends Duplex {
89
90
  /**
90
91
  * responseCallback 原消息处理回调
91
- * @param {*} options
92
+ * @param {*} opts
92
93
  * @param {*} resCallback
93
- */ constructor(options, resCallback){
94
+ */ constructor(opts, resCallback){
94
95
  super(), this._timeout = 0, /** @type {*} */ this.socket = null, /** @type {http.ClientRequest} */ this._currentRequest = null, /** @type {stream.Readable} */ this.response = null, /** @type {stream.Readable} */ this.responseStream = null, this.timing = false, this.responseStarted = false, this.responseStartTime = 0, this._destdata = false, this._paused = false, this._respended = false, /** @type {stream.Readable} */ this.pipesrc = null // 被 pipe 时的 src stream
95
96
  , /** @type {stream.Writable[]} */ this.pipedests = [] // pipe dest
96
97
  ;
97
98
  const m = this;
98
99
  // log({options}, 'constructor');
99
100
  // Initialize the request
100
- m._sanitizeOptions(options);
101
- m._options = options;
102
- m.headers = options.headers;
101
+ m.sanitizeOptions(opts);
102
+ m.opt = opts;
103
+ m.headers = opts.headers;
104
+ // log({opts}, 'constructor')
103
105
  m._ended = false;
104
106
  m._ending = false;
105
107
  m._redirectCount = 0;
@@ -110,9 +112,9 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
110
112
  m.resCallback = resCallback;
111
113
  // React to responses of native requests
112
114
  // 接管 response 事件,非重定向,触发 response 事件
113
- m._onResponse = (response)=>{
115
+ m._onResponse = (res)=>{
114
116
  try {
115
- m.processResponse(response);
117
+ m.processResponse(res);
116
118
  } catch (cause) {
117
119
  m.emit('error', cause instanceof RedirectionError ? cause : new RedirectionError({
118
120
  cause: cause
@@ -150,30 +152,30 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
150
152
  });
151
153
  }
152
154
  // 流模式
153
- if (options.stream) // 被 pipe 作为目标时触发,拷贝 src headers
154
- m.on('pipe', /** @type {stream.Readable} */ (src)=>{
155
- // m.ntick &&
156
- if (m._currentRequest) {
157
- m.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.'));
158
- }
159
- m.pipesrc = src;
160
- if (utils.isReadStream(src)) {
161
- if (!m.hasHeader('content-type')) {
162
- m.setHeader('content-type', mime.lookup(src.path));
155
+ if (opts.stream) {
156
+ // pipe 作为目标时触发,拷贝 src headers
157
+ m.on('pipe', /** @type {stream.Readable} */ (src)=>{
158
+ // m.ntick &&
159
+ if (m._currentRequest) {
160
+ m.emit('error', new Error('You cannot pipe to this stream after the outbound request has started.'));
163
161
  }
164
- } else {
165
- if (src.headers) {
166
- for (const h of src.headers){
167
- if (!m.hasHeader(h)) {
168
- m.setHeader(h, src.headers[h]);
162
+ m.pipesrc = src;
163
+ if (utils.isReadStream(src)) {
164
+ if (!m.hasHeader('content-type')) {
165
+ m.setHeader('content-type', mime.lookup(src.path));
166
+ }
167
+ } else {
168
+ if (src.headers) {
169
+ for (const h of src.headers){
170
+ if (!m.hasHeader(h)) {
171
+ m.setHeader(h, src.headers[h]);
172
+ }
169
173
  }
170
174
  }
175
+ if (src.opt.method && !m.opt.method) m.opt.method = src.opt.method;
171
176
  }
172
- // if (src.method && !self.explicitMethod) {
173
- // m.method = src.method
174
- // }
175
- }
176
- });
177
+ });
178
+ }
177
179
  // Perform the first request
178
180
  // m.request(); // 写入数据时执行,否则 pipe时无法写入header
179
181
  }
@@ -182,9 +184,10 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
182
184
  * @returns http(s) 实例
183
185
  */ request() {
184
186
  let R = null;
187
+ const m = this;
188
+ const { opt } = m;
185
189
  try {
186
- const m = this;
187
- // read stream
190
+ // reset read stream
188
191
  m.response = null;
189
192
  m.responseStarted = false;
190
193
  m.responseStream = null;
@@ -195,29 +198,28 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
195
198
  m._respended = false;
196
199
  // m.httpModule = httpModules[protocol];
197
200
  // Load the native protocol
198
- let { protocol } = m._options;
199
- const { agents } = m._options;
201
+ let { protocol } = opt;
202
+ const { agents } = opt;
200
203
  // 代理以目的网址协议为准
201
204
  // If specified, use the agent corresponding to the protocol
202
205
  // (HTTP and HTTPS use different types of agents)
203
206
  if (agents) {
204
207
  const scheme = protocol.slice(0, -1);
205
- m._options.agent = agents[scheme];
206
- }
207
- // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
208
- // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
209
- if (protocol === 'http:' && agents.http) {
210
- protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
208
+ opt.agent = agents[scheme];
209
+ // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
210
+ // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
211
+ if (protocol === 'http:' && agents.http) {
212
+ protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
213
+ }
211
214
  }
212
215
  const httpModule = httpModules[protocol];
213
216
  if (!httpModule) throw TypeError(`Unsupported protocol: ${protocol}`);
214
- log.debug('request', {
215
- options: m._options,
217
+ log({
218
+ opt,
216
219
  protocol
217
- });
218
- debugger;
220
+ }, 'request');
219
221
  // Create the native request and set up its event handlers
220
- const req = httpModule.request(m._options, m._onResponse);
222
+ const req = httpModule.request(opt, m._onResponse);
221
223
  m._currentRequest = req;
222
224
  req.redirectReq = m;
223
225
  // 接收req事件,转发 到 redirectReq 发射
@@ -226,7 +228,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
226
228
  // a client MUST send only the absolute path […] as the request-target.
227
229
  // When making a request to a proxy, […]
228
230
  // a client MUST send the target URI in absolute-form […].
229
- m._currentUrl = /^\//.test(m._options.path) ? url.format(m._options) : m._options.path;
231
+ m._currentUrl = /^\//.test(opt.path) ? url.format(opt) : opt.path;
230
232
  // End a redirected request
231
233
  // (The first request must be ended explicitly with RedirectableRequest#end)
232
234
  if (m._isRedirect) {
@@ -302,7 +304,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
302
304
  return;
303
305
  }
304
306
  // Only write when we don't exceed the maximum body length
305
- if (m._requestBodyLength + chunk.length <= m._options.maxBodyLength) {
307
+ if (m._requestBodyLength + chunk.length <= m.opt.maxBodyLength) {
306
308
  m._requestBodyLength += chunk.length;
307
309
  m._requestBodyBuffers.push({
308
310
  data: chunk,
@@ -351,27 +353,27 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
351
353
  * @param {string} name
352
354
  * @returns
353
355
  */ hasHeader(name) {
354
- return this._options.headers.includes(name);
356
+ return this.opt.headers.includes(name);
355
357
  }
356
358
  /**
357
359
  *
358
360
  * @param {string} name
359
361
  * @returns {string}
360
362
  */ getHeader(name) {
361
- return this._options.headers[name];
363
+ return this.opt.headers[name];
362
364
  }
363
365
  /**
364
366
  * Sets a header value on the current native request
365
367
  * @param {string} name
366
368
  */ setHeader(name, value) {
367
- this._options.headers[name] = value;
369
+ this.opt.headers[name] = value;
368
370
  this._currentRequest?.setHeader(name, value);
369
371
  }
370
372
  /**
371
373
  * Clears a header value on the current native request
372
374
  * @param {string} name
373
375
  */ removeHeader(name) {
374
- delete this._options.headers[name];
376
+ delete this.opt.headers[name];
375
377
  this._currentRequest?.removeHeader(name);
376
378
  }
377
379
  /**
@@ -443,7 +445,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
443
445
  m.on('close', clearTimer);
444
446
  return m;
445
447
  }
446
- _sanitizeOptions(options) {
448
+ sanitizeOptions(options) {
447
449
  // Ensure headers are always present
448
450
  if (!options.headers) options.headers = {};
449
451
  // Since http.request treats host as an alias of hostname,
@@ -475,7 +477,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
475
477
  const m = this;
476
478
  // Store the redirected response
477
479
  const { statusCode } = response;
478
- if (m._options.trackRedirects) {
480
+ if (m.opt.trackRedirects) {
479
481
  m._redirects.push({
480
482
  url: m._currentUrl,
481
483
  headers: response.headers,
@@ -494,7 +496,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
494
496
  statusCode,
495
497
  headers: response.headers
496
498
  });
497
- if (!location || m._options.followRedirects === false || statusCode < 300 || statusCode >= 400) {
499
+ if (!location || m.opt.followRedirects === false || statusCode < 300 || statusCode >= 400) {
498
500
  // 非重定向,返回给原始回调处理
499
501
  response.responseUrl = m._currentUrl;
500
502
  response.redirects = m._redirects;
@@ -526,34 +528,34 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
526
528
  response.destroy();
527
529
  // RFC7231§6.4: A client SHOULD detect and intervene
528
530
  // in cyclical redirections (i.e., "infinite" redirection loops).
529
- if (++m._redirectCount > m._options.maxRedirects) throw new TooManyRedirectsError();
531
+ if (++m._redirectCount > m.opt.maxRedirects) throw new TooManyRedirectsError();
530
532
  // Store the request headers if applicable
531
533
  let requestHeaders;
532
- const { beforeRedirect } = m._options;
534
+ const { beforeRedirect } = m.opt;
533
535
  if (beforeRedirect) {
534
536
  requestHeaders = {
535
537
  // The Host header was set by nativeProtocol.request
536
538
  Host: response.req.getHeader('host'),
537
- ...m._options.headers
539
+ ...m.opt.headers
538
540
  };
539
541
  }
540
542
  // RFC7231§6.4: Automatic redirection needs to done with
541
543
  // care for methods not known to be safe, […]
542
544
  // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change
543
545
  // the request method from POST to GET for the subsequent request.
544
- const { method } = m._options;
545
- if ((statusCode === 301 || statusCode === 302) && m._options.method === 'POST' || // RFC7231§6.4.4: The 303 (See Other) status code indicates that
546
+ const { method } = m.opt;
547
+ if ((statusCode === 301 || statusCode === 302) && m.opt.method === 'POST' || // RFC7231§6.4.4: The 303 (See Other) status code indicates that
546
548
  // the server is redirecting the user agent to a different resource […]
547
549
  // A user agent can perform a retrieval request targeting that URI
548
550
  // (a GET or HEAD request if using HTTP) […]
549
- statusCode === 303 && !/^(?:GET|HEAD)$/.test(m._options.method)) {
550
- m._options.method = 'GET';
551
+ statusCode === 303 && !/^(?:GET|HEAD)$/.test(m.opt.method)) {
552
+ m.opt.method = 'GET';
551
553
  // Drop a possible entity and headers related to it
552
554
  m._requestBodyBuffers = [];
553
- removeMatchingHeaders(/^content-/i, m._options.headers);
555
+ removeMatchingHeaders(/^content-/i, m.opt.headers);
554
556
  }
555
557
  // Drop the Host header, as the redirect might lead to a different host
556
- const currentHostHeader = removeMatchingHeaders(/^host$/i, m._options.headers);
558
+ const currentHostHeader = removeMatchingHeaders(/^host$/i, m.opt.headers);
557
559
  // If the redirect is relative, carry over the host of the last request
558
560
  const currentUrlParts = utils.parseUrl(m._currentUrl);
559
561
  const currentHost = currentHostHeader || currentUrlParts.host;
@@ -567,11 +569,11 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
567
569
  }, 'redirecting to');
568
570
  m._isRedirect = true;
569
571
  // 覆盖原 url 解析部分,包括 protocol、hostname、port等
570
- utils.spreadUrlObject(redirectUrl, m._options);
572
+ utils.spreadUrlObject(redirectUrl, m.opt);
571
573
  // Drop confidential headers when redirecting to a less secure protocol
572
574
  // or to a different domain that is not a superdomain
573
575
  if (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== 'https:' || redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost)) {
574
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
576
+ removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this.opt.headers);
575
577
  }
576
578
  // Evaluate the beforeRedirect callback
577
579
  if (utils.isFunction(beforeRedirect)) {
@@ -584,8 +586,8 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
584
586
  method,
585
587
  headers: requestHeaders
586
588
  };
587
- beforeRedirect(m._options, responseDetails, requestDetails);
588
- m._sanitizeOptions(m._options);
589
+ beforeRedirect(m.opt, responseDetails, requestDetails);
590
+ m.sanitizeOptions(m.opt);
589
591
  }
590
592
  // Perform the redirected request
591
593
  m.request() // 重新执行请求
@@ -597,7 +599,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
597
599
  * @param {*} res
598
600
  */ processStream(res) {
599
601
  const m = this;
600
- const { _options: opts } = m;
602
+ const { opt: opts } = m;
601
603
  const streams = [
602
604
  res
603
605
  ];
@@ -746,7 +748,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
746
748
  * @param {*} dest
747
749
  */ pipeDest(dest) {
748
750
  const m = this;
749
- const { response, _options } = m;
751
+ const { response } = m;
750
752
  // Called after the response is received
751
753
  if (response?.headers && dest.headers && !dest.headersSent) {
752
754
  const caseless = new Caseless(response.headers);
@@ -773,9 +775,9 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
773
775
  }
774
776
  dest.statusCode = response.statusCode;
775
777
  }
776
- // if (m.pipefilter) {
777
- // m.pipefilter(response, dest)
778
- // }
778
+ if (m.pipefilter) {
779
+ m.pipefilter(response, dest);
780
+ }
779
781
  }
780
782
  /**
781
783
  * 暂停read流
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@wiajs/request",
3
3
  "description": "Stream HTTP request client.",
4
4
  "keywords": ["http", "simple", "util", "utility"],
5
- "version": "3.0.2",
5
+ "version": "3.0.5",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "exports": {