@wiajs/request 3.0.5 → 3.0.7

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/dist/request.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * wia request v3.0.0
2
+ * wia request v3.0.7
3
3
  * (c) 2022-2024 Sibyl Yu and contributors
4
4
  * Released under the MIT License.
5
5
  */
@@ -14,6 +14,7 @@ const stream = require('node:stream');
14
14
  const zlib = require('node:zlib');
15
15
  const mime = require('mime-types');
16
16
 
17
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
17
18
  class ZlibTransform extends stream.Transform {
18
19
  __transform(chunk, encoding, callback) {
19
20
  this.push(chunk);
@@ -42,12 +43,12 @@ class ZlibTransform extends stream.Transform {
42
43
  * utils for request
43
44
  */
44
45
 
45
- const {URL} = url;
46
+ const {URL: URL$1} = url;
46
47
 
47
48
  // Whether to use the native URL object or the legacy url module
48
49
  let useNativeURL = false;
49
50
  try {
50
- assert(new URL(''));
51
+ assert(new URL$1(''));
51
52
  } catch (error) {
52
53
  useNativeURL = error.code === 'ERR_INVALID_URL';
53
54
  }
@@ -193,7 +194,7 @@ const noop = () => {};
193
194
  * @returns
194
195
  */
195
196
  function isURL(value) {
196
- return URL && value instanceof URL
197
+ return URL$1 && value instanceof URL$1
197
198
  }
198
199
 
199
200
  function isReadStream(rs) {
@@ -235,7 +236,7 @@ function parseUrl(input) {
235
236
  let parsed;
236
237
  // istanbul ignore else
237
238
  if (useNativeURL) {
238
- parsed = new URL(input);
239
+ parsed = new URL$1(input);
239
240
  } else {
240
241
  // Ensure the URL is valid and absolute
241
242
  parsed = validateUrl(url.parse(input));
@@ -269,7 +270,7 @@ function validateUrl(input) {
269
270
  */
270
271
  function resolveUrl(relative, base) {
271
272
  // istanbul ignore next
272
- return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative))
273
+ return useNativeURL ? new URL$1(relative, base) : parseUrl(url.resolve(base, relative))
273
274
  }
274
275
 
275
276
  /**
@@ -405,7 +406,7 @@ class Caseless {
405
406
  * https://github.com/follow-redirects/follow-redirects
406
407
  */
407
408
 
408
- const log$1 = log$2.log({env: `wia:req:${log$2.name(__filename)}`});
409
+ const log$1 = log$2.log({env: `wia:req:${log$2.name((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('request.cjs', document.baseURI).href)))}`}); // __filename
409
410
 
410
411
  const httpModules = {'http:': http, 'https:': https};
411
412
 
@@ -444,7 +445,7 @@ const writeEventEmit = Object.create(null);
444
445
  for (const ev of writeEvents)
445
446
  writeEventEmit[ev] = function (...args) {
446
447
  const m = this; // 事件回调,this === clientRequest 实例
447
- log$1.debug('req event', {ev});
448
+ log$1('req event', {ev});
448
449
  m.redirectReq.emit(ev, ...args); // req 事情映射到 redirectReq 上触发
449
450
  };
450
451
 
@@ -455,7 +456,7 @@ const readEventEmit = Object.create(null);
455
456
  for (const ev of readEvents)
456
457
  readEventEmit[ev] = function (...args) {
457
458
  const m = this; // 事件回调,this === clientRequest 实例
458
- log$1.debug('res event', {ev});
459
+ log$1('res event', {ev});
459
460
  m.redirectReq.emit(ev, ...args); // 向上触发事件
460
461
  };
461
462
 
@@ -499,22 +500,25 @@ class Request extends stream.Duplex {
499
500
  pipesrc = null // 被 pipe 时的 src stream
500
501
  /** @type {stream.Writable[]} */
501
502
  pipedests = [] // pipe dest
503
+ /** @type {*} */
504
+ startTimer = null
502
505
 
503
506
  /**
504
507
  * responseCallback 原消息处理回调
505
- * @param {*} options
508
+ * @param {*} opts
506
509
  * @param {*} resCallback
507
510
  */
508
- constructor(options, resCallback) {
511
+ constructor(opts, resCallback) {
509
512
  super();
510
513
  const m = this;
511
514
 
512
515
  // log({options}, 'constructor');
513
516
 
514
517
  // Initialize the request
515
- m._sanitizeOptions(options);
516
- m._options = options;
517
- m.headers = options.headers;
518
+ m.sanitizeOptions(opts);
519
+ m.opt = opts;
520
+ m.headers = opts.headers;
521
+ // log({opts}, 'constructor')
518
522
  m._ended = false;
519
523
  m._ending = false;
520
524
  m._redirectCount = 0;
@@ -528,35 +532,16 @@ class Request extends stream.Duplex {
528
532
  m.resCallback = resCallback;
529
533
  // React to responses of native requests
530
534
  // 接管 response 事件,非重定向,触发 response 事件
531
- m._onResponse = response => {
535
+ m._onResponse = res => {
532
536
  try {
533
- m.processResponse(response);
537
+ m.processResponse(res);
534
538
  } catch (cause) {
535
539
  m.emit('error', cause instanceof RedirectionError ? cause : new RedirectionError({cause: cause}));
536
540
  }
537
541
  };
538
542
 
539
- // Proxy all other public ClientRequest methods
540
- for (const method of ['flushHeaders', 'setNoDelay', 'setSocketKeepAlive']) {
541
- m[method] = (a, b) => {
542
- log$1.debug(method, {a, b});
543
- m._currentRequest[method](a, b);
544
- };
545
- }
546
-
547
- // Proxy all public ClientRequest properties
548
- for (const property of ['aborted', 'connection', 'socket']) {
549
- Object.defineProperty(m, property, {
550
- get() {
551
- const val = m._currentRequest[property];
552
- log$1.debug('get property', {property});
553
- return val
554
- },
555
- });
556
- }
557
-
558
543
  // 流模式
559
- if (options.stream)
544
+ if (opts.stream) {
560
545
  // 被 pipe 作为目标时触发,拷贝 src headers
561
546
  m.on(
562
547
  'pipe',
@@ -581,12 +566,11 @@ class Request extends stream.Duplex {
581
566
  }
582
567
  }
583
568
 
584
- // if (src.method && !self.explicitMethod) {
585
- // m.method = src.method
586
- // }
569
+ if (src.opt.method && !m.opt.method) m.opt.method = src.opt.method;
587
570
  }
588
571
  }
589
572
  );
573
+ }
590
574
 
591
575
  // Perform the first request
592
576
  // m.request(); // 写入数据时执行,否则 pipe时无法写入header
@@ -598,10 +582,11 @@ class Request extends stream.Duplex {
598
582
  */
599
583
  request() {
600
584
  let R = null;
585
+ const m = this;
586
+ const {opt} = m;
601
587
 
602
588
  try {
603
- const m = this;
604
- // read stream
589
+ // reset read stream
605
590
  m.response = null;
606
591
  m.responseStarted = false;
607
592
  m.responseStream = null;
@@ -614,35 +599,53 @@ class Request extends stream.Duplex {
614
599
  // m.httpModule = httpModules[protocol];
615
600
 
616
601
  // Load the native protocol
617
- let {protocol} = m._options;
618
- const {agents} = m._options;
602
+ let {protocol} = opt;
603
+ const {agents} = opt;
619
604
 
620
605
  // 代理以目的网址协议为准
621
606
  // If specified, use the agent corresponding to the protocol
622
607
  // (HTTP and HTTPS use different types of agents)
623
608
  if (agents) {
624
609
  const scheme = protocol.slice(0, -1);
625
- m._options.agent = agents[scheme];
626
- }
610
+ opt.agent = agents[scheme];
627
611
 
628
- // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
629
- // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
630
- if (protocol === 'http:' && agents.http) {
631
- protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
612
+ // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
613
+ // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
614
+ if (protocol === 'http:' && agents.http) {
615
+ protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
616
+ }
632
617
  }
633
618
 
634
619
  const httpModule = httpModules[protocol];
635
620
  if (!httpModule) throw TypeError(`Unsupported protocol: ${protocol}`)
636
621
 
637
- log$1.debug('request', {options: m._options, protocol});
638
-
639
- debugger
640
-
622
+ log$1({opt, protocol}, 'request');
641
623
  // Create the native request and set up its event handlers
642
- const req = httpModule.request(m._options, m._onResponse);
624
+ const req = httpModule.request(opt, m._onResponse);
643
625
  m._currentRequest = req;
644
-
645
626
  req.redirectReq = m;
627
+
628
+ // Proxy all other public ClientRequest methods
629
+ for (const method of ['flushHeaders', 'setNoDelay', 'setSocketKeepAlive']) {
630
+ m[method] = (a, b) => {
631
+ log$1.debug(method, {a, b});
632
+ m._currentRequest[method](a, b);
633
+ };
634
+ }
635
+
636
+ // Proxy all public ClientRequest properties
637
+ for (const property of ['aborted', 'connection', 'socket']) {
638
+ Object.defineProperty(m, property, {
639
+ get() {
640
+ const val = m._currentRequest[property];
641
+ log$1.debug('get property', {property});
642
+ return val
643
+ },
644
+ });
645
+ }
646
+
647
+ m._currentRequest.once('socket', m.startTimer);
648
+
646
649
  // 接收req事件,转发 到 redirectReq 发射
647
650
  for (const ev of writeEvents) req.on(ev, writeEventEmit[ev]);
648
651
 
@@ -650,7 +653,7 @@ class Request extends stream.Duplex {
650
653
  // a client MUST send only the absolute path […] as the request-target.
651
654
  // When making a request to a proxy, […]
652
655
  // a client MUST send the target URI in absolute-form […].
653
- m._currentUrl = /^\//.test(m._options.path) ? url.format(m._options) : m._options.path;
656
+ m._currentUrl = /^\//.test(opt.path) ? url.format(opt) : opt.path;
654
657
 
655
658
  // End a redirected request
656
659
  // (The first request must be ended explicitly with RedirectableRequest#end)
@@ -745,7 +748,7 @@ class Request extends stream.Duplex {
745
748
  }
746
749
 
747
750
  // Only write when we don't exceed the maximum body length
748
- if (m._requestBodyLength + chunk.length <= m._options.maxBodyLength) {
751
+ if (m._requestBodyLength + chunk.length <= m.opt.maxBodyLength) {
749
752
  m._requestBodyLength += chunk.length;
750
753
  m._requestBodyBuffers.push({data: chunk, encoding});
751
754
  m._currentRequest.write(chunk, encoding, cb);
@@ -801,7 +804,7 @@ class Request extends stream.Duplex {
801
804
  * @returns
802
805
  */
803
806
  hasHeader(name) {
804
- return this._options.headers.includes(name)
807
+ return this.opt.headers.includes(name)
805
808
  }
806
809
 
807
810
  /**
@@ -810,7 +813,7 @@ class Request extends stream.Duplex {
810
813
  * @returns {string}
811
814
  */
812
815
  getHeader(name) {
813
- return this._options.headers[name]
816
+ return this.opt.headers[name]
814
817
  }
815
818
 
816
819
  /**
@@ -818,7 +821,7 @@ class Request extends stream.Duplex {
818
821
  * @param {string} name
819
822
  */
820
823
  setHeader(name, value) {
821
- this._options.headers[name] = value;
824
+ this.opt.headers[name] = value;
822
825
  this._currentRequest?.setHeader(name, value);
823
826
  }
824
827
 
@@ -827,7 +830,7 @@ class Request extends stream.Duplex {
827
830
  * @param {string} name
828
831
  */
829
832
  removeHeader(name) {
830
- delete this._options.headers[name];
833
+ delete this.opt.headers[name];
831
834
  this._currentRequest?.removeHeader(name);
832
835
  }
833
836
 
@@ -839,9 +842,8 @@ class Request extends stream.Duplex {
839
842
  return this._currentRequest?.headersSent
840
843
  }
841
844
 
842
- // Global timeout for all underlying requests
843
845
  /**
844
- *
846
+ * Global timeout for all underlying requests
845
847
  * @param {*} msecs
846
848
  * @param {*} callback
847
849
  * @returns
@@ -849,9 +851,8 @@ class Request extends stream.Duplex {
849
851
  setTimeout(msecs, callback) {
850
852
  const m = this;
851
853
 
852
- // Destroys the socket on timeout
853
854
  /**
854
- *
855
+ * Destroys the socket on timeout
855
856
  * @param {*} socket
856
857
  */
857
858
  function destroyOnTimeout(socket) {
@@ -860,19 +861,18 @@ class Request extends stream.Duplex {
860
861
  socket.addListener('timeout', socket.destroy);
861
862
  }
862
863
 
863
- // Sets up a timer to trigger a timeout event
864
864
  /**
865
- *
865
+ * Sets up a timer to trigger a timeout event
866
866
  * @param {*} socket
867
867
  */
868
868
  function startTimer(socket) {
869
- if (m._timeout) {
870
- clearTimeout(m._timeout);
871
- }
869
+ if (m._timeout) clearTimeout(m._timeout);
870
+
872
871
  m._timeout = setTimeout(() => {
873
872
  m.emit('timeout');
874
873
  clearTimer();
875
874
  }, msecs);
875
+
876
876
  destroyOnTimeout(socket);
877
877
  }
878
878
 
@@ -903,7 +903,7 @@ class Request extends stream.Duplex {
903
903
 
904
904
  // Start the timer if or when the socket is opened
905
905
  if (m.socket) startTimer(m.socket);
906
- else m._currentRequest.once('socket', startTimer);
906
+ else m.startTimer = startTimer; // 未连接,先登记
907
907
 
908
908
  // Clean up on events
909
909
  m.on('socket', destroyOnTimeout);
@@ -914,7 +914,7 @@ class Request extends stream.Duplex {
914
914
  return m
915
915
  }
916
916
 
917
- _sanitizeOptions(options) {
917
+ sanitizeOptions(options) {
918
918
  // Ensure headers are always present
919
919
  if (!options.headers) options.headers = {};
920
920
 
@@ -951,7 +951,7 @@ class Request extends stream.Duplex {
951
951
 
952
952
  // Store the redirected response
953
953
  const {statusCode} = response;
954
- if (m._options.trackRedirects) {
954
+ if (m.opt.trackRedirects) {
955
955
  m._redirects.push({
956
956
  url: m._currentUrl,
957
957
  headers: response.headers,
@@ -971,7 +971,7 @@ class Request extends stream.Duplex {
971
971
 
972
972
  log$1('processResponse', {statusCode, headers: response.headers});
973
973
 
974
- if (!location || m._options.followRedirects === false || statusCode < 300 || statusCode >= 400) {
974
+ if (!location || m.opt.followRedirects === false || statusCode < 300 || statusCode >= 400) {
975
975
  // 非重定向,返回给原始回调处理
976
976
  response.responseUrl = m._currentUrl;
977
977
  response.redirects = m._redirects;
@@ -1010,16 +1010,16 @@ class Request extends stream.Duplex {
1010
1010
 
1011
1011
  // RFC7231§6.4: A client SHOULD detect and intervene
1012
1012
  // in cyclical redirections (i.e., "infinite" redirection loops).
1013
- if (++m._redirectCount > m._options.maxRedirects) throw new TooManyRedirectsError()
1013
+ if (++m._redirectCount > m.opt.maxRedirects) throw new TooManyRedirectsError()
1014
1014
 
1015
1015
  // Store the request headers if applicable
1016
1016
  let requestHeaders;
1017
- const {beforeRedirect} = m._options;
1017
+ const {beforeRedirect} = m.opt;
1018
1018
  if (beforeRedirect) {
1019
1019
  requestHeaders = {
1020
1020
  // The Host header was set by nativeProtocol.request
1021
1021
  Host: response.req.getHeader('host'),
1022
- ...m._options.headers,
1022
+ ...m.opt.headers,
1023
1023
  };
1024
1024
  }
1025
1025
 
@@ -1027,23 +1027,23 @@ class Request extends stream.Duplex {
1027
1027
  // care for methods not known to be safe, […]
1028
1028
  // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change
1029
1029
  // the request method from POST to GET for the subsequent request.
1030
- const {method} = m._options;
1030
+ const {method} = m.opt;
1031
1031
  if (
1032
- ((statusCode === 301 || statusCode === 302) && m._options.method === 'POST') ||
1032
+ ((statusCode === 301 || statusCode === 302) && m.opt.method === 'POST') ||
1033
1033
  // RFC7231§6.4.4: The 303 (See Other) status code indicates that
1034
1034
  // the server is redirecting the user agent to a different resource […]
1035
1035
  // A user agent can perform a retrieval request targeting that URI
1036
1036
  // (a GET or HEAD request if using HTTP) […]
1037
- (statusCode === 303 && !/^(?:GET|HEAD)$/.test(m._options.method))
1037
+ (statusCode === 303 && !/^(?:GET|HEAD)$/.test(m.opt.method))
1038
1038
  ) {
1039
- m._options.method = 'GET';
1039
+ m.opt.method = 'GET';
1040
1040
  // Drop a possible entity and headers related to it
1041
1041
  m._requestBodyBuffers = [];
1042
- removeMatchingHeaders(/^content-/i, m._options.headers);
1042
+ removeMatchingHeaders(/^content-/i, m.opt.headers);
1043
1043
  }
1044
1044
 
1045
1045
  // Drop the Host header, as the redirect might lead to a different host
1046
- const currentHostHeader = removeMatchingHeaders(/^host$/i, m._options.headers);
1046
+ const currentHostHeader = removeMatchingHeaders(/^host$/i, m.opt.headers);
1047
1047
 
1048
1048
  // If the redirect is relative, carry over the host of the last request
1049
1049
  const currentUrlParts = utils.parseUrl(m._currentUrl);
@@ -1057,7 +1057,7 @@ class Request extends stream.Duplex {
1057
1057
  log$1({redirectUrl}, 'redirecting to');
1058
1058
  m._isRedirect = true;
1059
1059
  // 覆盖原 url 解析部分,包括 protocol、hostname、port等
1060
- utils.spreadUrlObject(redirectUrl, m._options);
1060
+ utils.spreadUrlObject(redirectUrl, m.opt);
1061
1061
 
1062
1062
  // Drop confidential headers when redirecting to a less secure protocol
1063
1063
  // or to a different domain that is not a superdomain
@@ -1065,7 +1065,7 @@ class Request extends stream.Duplex {
1065
1065
  (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== 'https:') ||
1066
1066
  (redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost))
1067
1067
  ) {
1068
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
1068
+ removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this.opt.headers);
1069
1069
  }
1070
1070
 
1071
1071
  // Evaluate the beforeRedirect callback
@@ -1080,8 +1080,8 @@ class Request extends stream.Duplex {
1080
1080
  headers: requestHeaders,
1081
1081
  };
1082
1082
 
1083
- beforeRedirect(m._options, responseDetails, requestDetails);
1084
- m._sanitizeOptions(m._options);
1083
+ beforeRedirect(m.opt, responseDetails, requestDetails);
1084
+ m.sanitizeOptions(m.opt);
1085
1085
  }
1086
1086
 
1087
1087
  // Perform the redirected request
@@ -1095,7 +1095,7 @@ class Request extends stream.Duplex {
1095
1095
  */
1096
1096
  processStream(res) {
1097
1097
  const m = this;
1098
- const {_options: opts} = m;
1098
+ const {opt: opts} = m;
1099
1099
 
1100
1100
  const streams = [res];
1101
1101
 
@@ -1260,7 +1260,7 @@ class Request extends stream.Duplex {
1260
1260
  */
1261
1261
  pipeDest(dest) {
1262
1262
  const m = this;
1263
- const {response, _options} = m;
1263
+ const {response} = m;
1264
1264
 
1265
1265
  // Called after the response is received
1266
1266
  if (response?.headers && dest.headers && !dest.headersSent) {
@@ -1291,9 +1291,9 @@ class Request extends stream.Duplex {
1291
1291
  dest.statusCode = response.statusCode;
1292
1292
  }
1293
1293
 
1294
- // if (m.pipefilter) {
1295
- // m.pipefilter(response, dest)
1296
- // }
1294
+ if (m.pipefilter) {
1295
+ m.pipefilter(response, dest);
1296
+ }
1297
1297
  }
1298
1298
 
1299
1299
  /**
@@ -1362,16 +1362,16 @@ function isSubdomain(subdomain, domain) {
1362
1362
  */
1363
1363
 
1364
1364
 
1365
- const log = log$2.log({env: `wia:req:${log$2.name(__filename)}`})
1365
+ const log = log$2.log({env: `wia:req:${log$2.name((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('request.cjs', document.baseURI).href)))}`}) // __filename
1366
1366
 
1367
1367
  // Preventive platform detection
1368
- // istanbul ignore next
1368
+ // istanbul ignore
1369
1369
  ;(function detectUnsupportedEnvironment() {
1370
1370
  const looksLikeNode = typeof process !== 'undefined';
1371
1371
  const looksLikeBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
1372
1372
  const looksLikeV8 = utils.isFunction(Error.captureStackTrace);
1373
1373
  if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {
1374
- log.warn('The follow-redirects package should be excluded from browser builds.');
1374
+ console.warn('The follow-redirects package should be excluded from browser builds.');
1375
1375
  }
1376
1376
  })();
1377
1377
 
@@ -1389,6 +1389,7 @@ const log = log$2.log({env: `wia:req:${log$2.name(__filename)}`})
1389
1389
  * @returns
1390
1390
  */
1391
1391
  function init(uri, options, callback) {
1392
+ let R;
1392
1393
  try {
1393
1394
  // Parse parameters, ensuring that input is an object
1394
1395
  if (utils.isURL(uri)) uri = utils.spreadUrlObject(uri);
@@ -1413,6 +1414,7 @@ function init(uri, options, callback) {
1413
1414
  if (!utils.isString(options.host) && !utils.isString(options.hostname)) options.hostname = '::1';
1414
1415
 
1415
1416
  R = {opts: options, cb: callback};
1417
+ // log({R}, 'init')
1416
1418
  } catch (e) {
1417
1419
  log.err(e, 'init');
1418
1420
  }
@@ -1435,8 +1437,9 @@ function request(uri, options, callback) {
1435
1437
  let R = null;
1436
1438
 
1437
1439
  try {
1440
+ log({uri, options}, 'request');
1441
+
1438
1442
  const {opts, cb} = init(uri, options, callback);
1439
- // log.debug('request', {options})
1440
1443
  R = new Request(opts, cb);
1441
1444
  } catch (e) {
1442
1445
  log.err(e, 'request');
@@ -1454,6 +1457,8 @@ function request(uri, options, callback) {
1454
1457
  */
1455
1458
  function fn(verb) {
1456
1459
  const method = verb.toUpperCase();
1460
+
1461
+ // @ts-ignore
1457
1462
  return (uri, options, callback) => {
1458
1463
  const {opts, cb} = init(uri, options, callback);
1459
1464
  opts.method = method;
package/dist/request.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * wia request v3.0.0
2
+ * wia request v3.0.7
3
3
  * (c) 2022-2024 Sibyl Yu and contributors
4
4
  * Released under the MIT License.
5
5
  */
@@ -403,7 +403,7 @@ class Caseless {
403
403
  * https://github.com/follow-redirects/follow-redirects
404
404
  */
405
405
 
406
- const log$1 = log$2({env: `wia:req:${name(__filename)}`});
406
+ const log$1 = log$2({env: `wia:req:${name(import.meta.url)}`}); // __filename
407
407
 
408
408
  const httpModules = {'http:': http, 'https:': https};
409
409
 
@@ -442,7 +442,7 @@ const writeEventEmit = Object.create(null);
442
442
  for (const ev of writeEvents)
443
443
  writeEventEmit[ev] = function (...args) {
444
444
  const m = this; // 事件回调,this === clientRequest 实例
445
- log$1.debug('req event', {ev});
445
+ log$1('req event', {ev});
446
446
  m.redirectReq.emit(ev, ...args); // req 事情映射到 redirectReq 上触发
447
447
  };
448
448
 
@@ -453,7 +453,7 @@ const readEventEmit = Object.create(null);
453
453
  for (const ev of readEvents)
454
454
  readEventEmit[ev] = function (...args) {
455
455
  const m = this; // 事件回调,this === clientRequest 实例
456
- log$1.debug('res event', {ev});
456
+ log$1('res event', {ev});
457
457
  m.redirectReq.emit(ev, ...args); // 向上触发事件
458
458
  };
459
459
 
@@ -497,22 +497,25 @@ class Request extends Duplex {
497
497
  pipesrc = null // 被 pipe 时的 src stream
498
498
  /** @type {stream.Writable[]} */
499
499
  pipedests = [] // pipe dest
500
+ /** @type {*} */
501
+ startTimer = null
500
502
 
501
503
  /**
502
504
  * responseCallback 原消息处理回调
503
- * @param {*} options
505
+ * @param {*} opts
504
506
  * @param {*} resCallback
505
507
  */
506
- constructor(options, resCallback) {
508
+ constructor(opts, resCallback) {
507
509
  super();
508
510
  const m = this;
509
511
 
510
512
  // log({options}, 'constructor');
511
513
 
512
514
  // Initialize the request
513
- m._sanitizeOptions(options);
514
- m._options = options;
515
- m.headers = options.headers;
515
+ m.sanitizeOptions(opts);
516
+ m.opt = opts;
517
+ m.headers = opts.headers;
518
+ // log({opts}, 'constructor')
516
519
  m._ended = false;
517
520
  m._ending = false;
518
521
  m._redirectCount = 0;
@@ -526,35 +529,16 @@ class Request extends Duplex {
526
529
  m.resCallback = resCallback;
527
530
  // React to responses of native requests
528
531
  // 接管 response 事件,非重定向,触发 response 事件
529
- m._onResponse = response => {
532
+ m._onResponse = res => {
530
533
  try {
531
- m.processResponse(response);
534
+ m.processResponse(res);
532
535
  } catch (cause) {
533
536
  m.emit('error', cause instanceof RedirectionError ? cause : new RedirectionError({cause: cause}));
534
537
  }
535
538
  };
536
539
 
537
- // Proxy all other public ClientRequest methods
538
- for (const method of ['flushHeaders', 'setNoDelay', 'setSocketKeepAlive']) {
539
- m[method] = (a, b) => {
540
- log$1.debug(method, {a, b});
541
- m._currentRequest[method](a, b);
542
- };
543
- }
544
-
545
- // Proxy all public ClientRequest properties
546
- for (const property of ['aborted', 'connection', 'socket']) {
547
- Object.defineProperty(m, property, {
548
- get() {
549
- const val = m._currentRequest[property];
550
- log$1.debug('get property', {property});
551
- return val
552
- },
553
- });
554
- }
555
-
556
540
  // 流模式
557
- if (options.stream)
541
+ if (opts.stream) {
558
542
  // 被 pipe 作为目标时触发,拷贝 src headers
559
543
  m.on(
560
544
  'pipe',
@@ -579,12 +563,11 @@ class Request extends Duplex {
579
563
  }
580
564
  }
581
565
 
582
- // if (src.method && !self.explicitMethod) {
583
- // m.method = src.method
584
- // }
566
+ if (src.opt.method && !m.opt.method) m.opt.method = src.opt.method;
585
567
  }
586
568
  }
587
569
  );
570
+ }
588
571
 
589
572
  // Perform the first request
590
573
  // m.request(); // 写入数据时执行,否则 pipe时无法写入header
@@ -596,10 +579,11 @@ class Request extends Duplex {
596
579
  */
597
580
  request() {
598
581
  let R = null;
582
+ const m = this;
583
+ const {opt} = m;
599
584
 
600
585
  try {
601
- const m = this;
602
- // read stream
586
+ // reset read stream
603
587
  m.response = null;
604
588
  m.responseStarted = false;
605
589
  m.responseStream = null;
@@ -612,35 +596,53 @@ class Request extends Duplex {
612
596
  // m.httpModule = httpModules[protocol];
613
597
 
614
598
  // Load the native protocol
615
- let {protocol} = m._options;
616
- const {agents} = m._options;
599
+ let {protocol} = opt;
600
+ const {agents} = opt;
617
601
 
618
602
  // 代理以目的网址协议为准
619
603
  // If specified, use the agent corresponding to the protocol
620
604
  // (HTTP and HTTPS use different types of agents)
621
605
  if (agents) {
622
606
  const scheme = protocol.slice(0, -1);
623
- m._options.agent = agents[scheme];
624
- }
607
+ opt.agent = agents[scheme];
625
608
 
626
- // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
627
- // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
628
- if (protocol === 'http:' && agents.http) {
629
- protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
609
+ // http 非隧道代理模式,模块以代理主机为准,其他以目的网址为准
610
+ // 代理内部会根据代理协议选择 http(s) 发起请求创建连接
611
+ if (protocol === 'http:' && agents.http) {
612
+ protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
613
+ }
630
614
  }
631
615
 
632
616
  const httpModule = httpModules[protocol];
633
617
  if (!httpModule) throw TypeError(`Unsupported protocol: ${protocol}`)
634
618
 
635
- log$1.debug('request', {options: m._options, protocol});
636
-
637
- debugger
638
-
619
+ log$1({opt, protocol}, 'request');
639
620
  // Create the native request and set up its event handlers
640
- const req = httpModule.request(m._options, m._onResponse);
621
+ const req = httpModule.request(opt, m._onResponse);
641
622
  m._currentRequest = req;
642
-
643
623
  req.redirectReq = m;
624
+
625
+ // Proxy all other public ClientRequest methods
626
+ for (const method of ['flushHeaders', 'setNoDelay', 'setSocketKeepAlive']) {
627
+ m[method] = (a, b) => {
628
+ log$1.debug(method, {a, b});
629
+ m._currentRequest[method](a, b);
630
+ };
631
+ }
632
+
633
+ // Proxy all public ClientRequest properties
634
+ for (const property of ['aborted', 'connection', 'socket']) {
635
+ Object.defineProperty(m, property, {
636
+ get() {
637
+ const val = m._currentRequest[property];
638
+ log$1.debug('get property', {property});
639
+ return val
640
+ },
641
+ });
642
+ }
643
+
644
+ m._currentRequest.once('socket', m.startTimer);
645
+
644
646
  // 接收req事件,转发 到 redirectReq 发射
645
647
  for (const ev of writeEvents) req.on(ev, writeEventEmit[ev]);
646
648
 
@@ -648,7 +650,7 @@ class Request extends Duplex {
648
650
  // a client MUST send only the absolute path […] as the request-target.
649
651
  // When making a request to a proxy, […]
650
652
  // a client MUST send the target URI in absolute-form […].
651
- m._currentUrl = /^\//.test(m._options.path) ? url.format(m._options) : m._options.path;
653
+ m._currentUrl = /^\//.test(opt.path) ? url.format(opt) : opt.path;
652
654
 
653
655
  // End a redirected request
654
656
  // (The first request must be ended explicitly with RedirectableRequest#end)
@@ -743,7 +745,7 @@ class Request extends Duplex {
743
745
  }
744
746
 
745
747
  // Only write when we don't exceed the maximum body length
746
- if (m._requestBodyLength + chunk.length <= m._options.maxBodyLength) {
748
+ if (m._requestBodyLength + chunk.length <= m.opt.maxBodyLength) {
747
749
  m._requestBodyLength += chunk.length;
748
750
  m._requestBodyBuffers.push({data: chunk, encoding});
749
751
  m._currentRequest.write(chunk, encoding, cb);
@@ -799,7 +801,7 @@ class Request extends Duplex {
799
801
  * @returns
800
802
  */
801
803
  hasHeader(name) {
802
- return this._options.headers.includes(name)
804
+ return this.opt.headers.includes(name)
803
805
  }
804
806
 
805
807
  /**
@@ -808,7 +810,7 @@ class Request extends Duplex {
808
810
  * @returns {string}
809
811
  */
810
812
  getHeader(name) {
811
- return this._options.headers[name]
813
+ return this.opt.headers[name]
812
814
  }
813
815
 
814
816
  /**
@@ -816,7 +818,7 @@ class Request extends Duplex {
816
818
  * @param {string} name
817
819
  */
818
820
  setHeader(name, value) {
819
- this._options.headers[name] = value;
821
+ this.opt.headers[name] = value;
820
822
  this._currentRequest?.setHeader(name, value);
821
823
  }
822
824
 
@@ -825,7 +827,7 @@ class Request extends Duplex {
825
827
  * @param {string} name
826
828
  */
827
829
  removeHeader(name) {
828
- delete this._options.headers[name];
830
+ delete this.opt.headers[name];
829
831
  this._currentRequest?.removeHeader(name);
830
832
  }
831
833
 
@@ -837,9 +839,8 @@ class Request extends Duplex {
837
839
  return this._currentRequest?.headersSent
838
840
  }
839
841
 
840
- // Global timeout for all underlying requests
841
842
  /**
842
- *
843
+ * Global timeout for all underlying requests
843
844
  * @param {*} msecs
844
845
  * @param {*} callback
845
846
  * @returns
@@ -847,9 +848,8 @@ class Request extends Duplex {
847
848
  setTimeout(msecs, callback) {
848
849
  const m = this;
849
850
 
850
- // Destroys the socket on timeout
851
851
  /**
852
- *
852
+ * Destroys the socket on timeout
853
853
  * @param {*} socket
854
854
  */
855
855
  function destroyOnTimeout(socket) {
@@ -858,19 +858,18 @@ class Request extends Duplex {
858
858
  socket.addListener('timeout', socket.destroy);
859
859
  }
860
860
 
861
- // Sets up a timer to trigger a timeout event
862
861
  /**
863
- *
862
+ * Sets up a timer to trigger a timeout event
864
863
  * @param {*} socket
865
864
  */
866
865
  function startTimer(socket) {
867
- if (m._timeout) {
868
- clearTimeout(m._timeout);
869
- }
866
+ if (m._timeout) clearTimeout(m._timeout);
867
+
870
868
  m._timeout = setTimeout(() => {
871
869
  m.emit('timeout');
872
870
  clearTimer();
873
871
  }, msecs);
872
+
874
873
  destroyOnTimeout(socket);
875
874
  }
876
875
 
@@ -901,7 +900,7 @@ class Request extends Duplex {
901
900
 
902
901
  // Start the timer if or when the socket is opened
903
902
  if (m.socket) startTimer(m.socket);
904
- else m._currentRequest.once('socket', startTimer);
903
+ else m.startTimer = startTimer; // 未连接,先登记
905
904
 
906
905
  // Clean up on events
907
906
  m.on('socket', destroyOnTimeout);
@@ -912,7 +911,7 @@ class Request extends Duplex {
912
911
  return m
913
912
  }
914
913
 
915
- _sanitizeOptions(options) {
914
+ sanitizeOptions(options) {
916
915
  // Ensure headers are always present
917
916
  if (!options.headers) options.headers = {};
918
917
 
@@ -949,7 +948,7 @@ class Request extends Duplex {
949
948
 
950
949
  // Store the redirected response
951
950
  const {statusCode} = response;
952
- if (m._options.trackRedirects) {
951
+ if (m.opt.trackRedirects) {
953
952
  m._redirects.push({
954
953
  url: m._currentUrl,
955
954
  headers: response.headers,
@@ -969,7 +968,7 @@ class Request extends Duplex {
969
968
 
970
969
  log$1('processResponse', {statusCode, headers: response.headers});
971
970
 
972
- if (!location || m._options.followRedirects === false || statusCode < 300 || statusCode >= 400) {
971
+ if (!location || m.opt.followRedirects === false || statusCode < 300 || statusCode >= 400) {
973
972
  // 非重定向,返回给原始回调处理
974
973
  response.responseUrl = m._currentUrl;
975
974
  response.redirects = m._redirects;
@@ -1008,16 +1007,16 @@ class Request extends Duplex {
1008
1007
 
1009
1008
  // RFC7231§6.4: A client SHOULD detect and intervene
1010
1009
  // in cyclical redirections (i.e., "infinite" redirection loops).
1011
- if (++m._redirectCount > m._options.maxRedirects) throw new TooManyRedirectsError()
1010
+ if (++m._redirectCount > m.opt.maxRedirects) throw new TooManyRedirectsError()
1012
1011
 
1013
1012
  // Store the request headers if applicable
1014
1013
  let requestHeaders;
1015
- const {beforeRedirect} = m._options;
1014
+ const {beforeRedirect} = m.opt;
1016
1015
  if (beforeRedirect) {
1017
1016
  requestHeaders = {
1018
1017
  // The Host header was set by nativeProtocol.request
1019
1018
  Host: response.req.getHeader('host'),
1020
- ...m._options.headers,
1019
+ ...m.opt.headers,
1021
1020
  };
1022
1021
  }
1023
1022
 
@@ -1025,23 +1024,23 @@ class Request extends Duplex {
1025
1024
  // care for methods not known to be safe, […]
1026
1025
  // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change
1027
1026
  // the request method from POST to GET for the subsequent request.
1028
- const {method} = m._options;
1027
+ const {method} = m.opt;
1029
1028
  if (
1030
- ((statusCode === 301 || statusCode === 302) && m._options.method === 'POST') ||
1029
+ ((statusCode === 301 || statusCode === 302) && m.opt.method === 'POST') ||
1031
1030
  // RFC7231§6.4.4: The 303 (See Other) status code indicates that
1032
1031
  // the server is redirecting the user agent to a different resource […]
1033
1032
  // A user agent can perform a retrieval request targeting that URI
1034
1033
  // (a GET or HEAD request if using HTTP) […]
1035
- (statusCode === 303 && !/^(?:GET|HEAD)$/.test(m._options.method))
1034
+ (statusCode === 303 && !/^(?:GET|HEAD)$/.test(m.opt.method))
1036
1035
  ) {
1037
- m._options.method = 'GET';
1036
+ m.opt.method = 'GET';
1038
1037
  // Drop a possible entity and headers related to it
1039
1038
  m._requestBodyBuffers = [];
1040
- removeMatchingHeaders(/^content-/i, m._options.headers);
1039
+ removeMatchingHeaders(/^content-/i, m.opt.headers);
1041
1040
  }
1042
1041
 
1043
1042
  // Drop the Host header, as the redirect might lead to a different host
1044
- const currentHostHeader = removeMatchingHeaders(/^host$/i, m._options.headers);
1043
+ const currentHostHeader = removeMatchingHeaders(/^host$/i, m.opt.headers);
1045
1044
 
1046
1045
  // If the redirect is relative, carry over the host of the last request
1047
1046
  const currentUrlParts = utils.parseUrl(m._currentUrl);
@@ -1055,7 +1054,7 @@ class Request extends Duplex {
1055
1054
  log$1({redirectUrl}, 'redirecting to');
1056
1055
  m._isRedirect = true;
1057
1056
  // 覆盖原 url 解析部分,包括 protocol、hostname、port等
1058
- utils.spreadUrlObject(redirectUrl, m._options);
1057
+ utils.spreadUrlObject(redirectUrl, m.opt);
1059
1058
 
1060
1059
  // Drop confidential headers when redirecting to a less secure protocol
1061
1060
  // or to a different domain that is not a superdomain
@@ -1063,7 +1062,7 @@ class Request extends Duplex {
1063
1062
  (redirectUrl.protocol !== currentUrlParts.protocol && redirectUrl.protocol !== 'https:') ||
1064
1063
  (redirectUrl.host !== currentHost && !isSubdomain(redirectUrl.host, currentHost))
1065
1064
  ) {
1066
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
1065
+ removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this.opt.headers);
1067
1066
  }
1068
1067
 
1069
1068
  // Evaluate the beforeRedirect callback
@@ -1078,8 +1077,8 @@ class Request extends Duplex {
1078
1077
  headers: requestHeaders,
1079
1078
  };
1080
1079
 
1081
- beforeRedirect(m._options, responseDetails, requestDetails);
1082
- m._sanitizeOptions(m._options);
1080
+ beforeRedirect(m.opt, responseDetails, requestDetails);
1081
+ m.sanitizeOptions(m.opt);
1083
1082
  }
1084
1083
 
1085
1084
  // Perform the redirected request
@@ -1093,7 +1092,7 @@ class Request extends Duplex {
1093
1092
  */
1094
1093
  processStream(res) {
1095
1094
  const m = this;
1096
- const {_options: opts} = m;
1095
+ const {opt: opts} = m;
1097
1096
 
1098
1097
  const streams = [res];
1099
1098
 
@@ -1258,7 +1257,7 @@ class Request extends Duplex {
1258
1257
  */
1259
1258
  pipeDest(dest) {
1260
1259
  const m = this;
1261
- const {response, _options} = m;
1260
+ const {response} = m;
1262
1261
 
1263
1262
  // Called after the response is received
1264
1263
  if (response?.headers && dest.headers && !dest.headersSent) {
@@ -1289,9 +1288,9 @@ class Request extends Duplex {
1289
1288
  dest.statusCode = response.statusCode;
1290
1289
  }
1291
1290
 
1292
- // if (m.pipefilter) {
1293
- // m.pipefilter(response, dest)
1294
- // }
1291
+ if (m.pipefilter) {
1292
+ m.pipefilter(response, dest);
1293
+ }
1295
1294
  }
1296
1295
 
1297
1296
  /**
@@ -1360,16 +1359,16 @@ function isSubdomain(subdomain, domain) {
1360
1359
  */
1361
1360
 
1362
1361
 
1363
- const log = log$2({env: `wia:req:${name(__filename)}`})
1362
+ const log = log$2({env: `wia:req:${name(import.meta.url)}`}) // __filename
1364
1363
 
1365
1364
  // Preventive platform detection
1366
- // istanbul ignore next
1365
+ // istanbul ignore
1367
1366
  ;(function detectUnsupportedEnvironment() {
1368
1367
  const looksLikeNode = typeof process !== 'undefined';
1369
1368
  const looksLikeBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
1370
1369
  const looksLikeV8 = utils.isFunction(Error.captureStackTrace);
1371
1370
  if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) {
1372
- log.warn('The follow-redirects package should be excluded from browser builds.');
1371
+ console.warn('The follow-redirects package should be excluded from browser builds.');
1373
1372
  }
1374
1373
  })();
1375
1374
 
@@ -1387,6 +1386,7 @@ const log = log$2({env: `wia:req:${name(__filename)}`})
1387
1386
  * @returns
1388
1387
  */
1389
1388
  function init(uri, options, callback) {
1389
+ let R;
1390
1390
  try {
1391
1391
  // Parse parameters, ensuring that input is an object
1392
1392
  if (utils.isURL(uri)) uri = utils.spreadUrlObject(uri);
@@ -1411,6 +1411,7 @@ function init(uri, options, callback) {
1411
1411
  if (!utils.isString(options.host) && !utils.isString(options.hostname)) options.hostname = '::1';
1412
1412
 
1413
1413
  R = {opts: options, cb: callback};
1414
+ // log({R}, 'init')
1414
1415
  } catch (e) {
1415
1416
  log.err(e, 'init');
1416
1417
  }
@@ -1433,8 +1434,9 @@ function request(uri, options, callback) {
1433
1434
  let R = null;
1434
1435
 
1435
1436
  try {
1437
+ log({uri, options}, 'request');
1438
+
1436
1439
  const {opts, cb} = init(uri, options, callback);
1437
- // log.debug('request', {options})
1438
1440
  R = new Request(opts, cb);
1439
1441
  } catch (e) {
1440
1442
  log.err(e, 'request');
@@ -1452,6 +1454,8 @@ function request(uri, options, callback) {
1452
1454
  */
1453
1455
  function fn(verb) {
1454
1456
  const method = verb.toUpperCase();
1457
+
1458
+ // @ts-ignore
1455
1459
  return (uri, options, callback) => {
1456
1460
  const {opts, cb} = init(uri, options, callback);
1457
1461
  opts.method = method;
package/lib/index.js CHANGED
@@ -71,6 +71,10 @@ const log = Log({
71
71
  */ function request(uri, options, callback) {
72
72
  let R = null;
73
73
  try {
74
+ log({
75
+ uri,
76
+ options
77
+ }, 'request');
74
78
  const { opts, cb } = init(uri, options, callback);
75
79
  R = new Request(opts, cb);
76
80
  } catch (e) {
package/lib/request.js CHANGED
@@ -94,7 +94,7 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
94
94
  */ constructor(opts, resCallback){
95
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
96
96
  , /** @type {stream.Writable[]} */ this.pipedests = [] // pipe dest
97
- ;
97
+ , /** @type {*} */ this.startTimer = null;
98
98
  const m = this;
99
99
  // log({options}, 'constructor');
100
100
  // Initialize the request
@@ -121,36 +121,6 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
121
121
  }));
122
122
  }
123
123
  };
124
- // Proxy all other public ClientRequest methods
125
- for (const method of [
126
- 'flushHeaders',
127
- 'setNoDelay',
128
- 'setSocketKeepAlive'
129
- ]){
130
- m[method] = (a, b)=>{
131
- log.debug(method, {
132
- a,
133
- b
134
- });
135
- m._currentRequest[method](a, b);
136
- };
137
- }
138
- // Proxy all public ClientRequest properties
139
- for (const property of [
140
- 'aborted',
141
- 'connection',
142
- 'socket'
143
- ]){
144
- Object.defineProperty(m, property, {
145
- get () {
146
- const val = m._currentRequest[property];
147
- log.debug('get property', {
148
- property
149
- });
150
- return val;
151
- }
152
- });
153
- }
154
124
  // 流模式
155
125
  if (opts.stream) {
156
126
  // 被 pipe 作为目标时触发,拷贝 src headers
@@ -222,6 +192,37 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
222
192
  const req = httpModule.request(opt, m._onResponse);
223
193
  m._currentRequest = req;
224
194
  req.redirectReq = m;
195
+ // Proxy all other public ClientRequest methods
196
+ for (const method of [
197
+ 'flushHeaders',
198
+ 'setNoDelay',
199
+ 'setSocketKeepAlive'
200
+ ]){
201
+ m[method] = (a, b)=>{
202
+ log.debug(method, {
203
+ a,
204
+ b
205
+ });
206
+ m._currentRequest[method](a, b);
207
+ };
208
+ }
209
+ // Proxy all public ClientRequest properties
210
+ for (const property of [
211
+ 'aborted',
212
+ 'connection',
213
+ 'socket'
214
+ ]){
215
+ Object.defineProperty(m, property, {
216
+ get () {
217
+ const val = m._currentRequest[property];
218
+ log.debug('get property', {
219
+ property
220
+ });
221
+ return val;
222
+ }
223
+ });
224
+ }
225
+ m._currentRequest.once('socket', m.startTimer);
225
226
  // 接收req事件,转发 到 redirectReq 发射
226
227
  for (const ev of writeEvents)req.on(ev, writeEventEmit[ev]);
227
228
  // RFC7230§5.3.1: When making a request directly to an origin server, […]
@@ -382,31 +383,26 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
382
383
  */ get headersSent() {
383
384
  return this._currentRequest?.headersSent;
384
385
  }
385
- // Global timeout for all underlying requests
386
386
  /**
387
- *
387
+ * Global timeout for all underlying requests
388
388
  * @param {*} msecs
389
389
  * @param {*} callback
390
390
  * @returns
391
391
  */ setTimeout(msecs, callback) {
392
392
  const m = this;
393
- // Destroys the socket on timeout
394
393
  /**
395
- *
394
+ * Destroys the socket on timeout
396
395
  * @param {*} socket
397
396
  */ function destroyOnTimeout(socket) {
398
397
  socket.setTimeout(msecs);
399
398
  socket.removeListener('timeout', socket.destroy);
400
399
  socket.addListener('timeout', socket.destroy);
401
400
  }
402
- // Sets up a timer to trigger a timeout event
403
401
  /**
404
- *
402
+ * Sets up a timer to trigger a timeout event
405
403
  * @param {*} socket
406
404
  */ function startTimer(socket) {
407
- if (m._timeout) {
408
- clearTimeout(m._timeout);
409
- }
405
+ if (m._timeout) clearTimeout(m._timeout);
410
406
  m._timeout = setTimeout(()=>{
411
407
  m.emit('timeout');
412
408
  clearTimer();
@@ -436,7 +432,8 @@ const WriteAfterEndError = utils.createErrorType('ERR_STREAM_WRITE_AFTER_END', '
436
432
  if (callback) m.on('timeout', callback);
437
433
  // Start the timer if or when the socket is opened
438
434
  if (m.socket) startTimer(m.socket);
439
- else m._currentRequest.once('socket', startTimer);
435
+ else m.startTimer = startTimer // 未连接,先登记
436
+ ;
440
437
  // Clean up on events
441
438
  m.on('socket', destroyOnTimeout);
442
439
  m.on('abort', clearTimer);
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.5",
5
+ "version": "3.0.7",
6
6
  "type": "module",
7
7
  "main": "index.js",
8
8
  "exports": {