@wiajs/request 3.0.32 → 3.0.35
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 +129 -122
- package/dist/request.mjs +129 -122
- package/lib/index.js +22 -21
- package/lib/request.js +14 -10
- package/package.json +1 -1
- package/types/index.d.ts +2 -1
- package/types/request.d.ts +1 -3
package/dist/request.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* wia request v3.0.
|
|
3
|
-
* (c) 2022-
|
|
2
|
+
* wia request v3.0.35
|
|
3
|
+
* (c) 2022-2025 Sibyl Yu and contributors
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const stream = require('node:stream');
|
|
9
9
|
const log$2 = require('@wiajs/log');
|
|
10
|
+
const mime = require('mime-types');
|
|
11
|
+
const assert = require('node:assert');
|
|
10
12
|
const http = require('node:http');
|
|
11
13
|
const https = require('node:https');
|
|
12
|
-
const assert = require('node:assert');
|
|
13
14
|
const url = require('node:url');
|
|
14
15
|
const zlib = require('node:zlib');
|
|
15
|
-
const mime = require('mime-types');
|
|
16
16
|
|
|
17
17
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
18
18
|
class ZlibTransform extends stream.Transform {
|
|
@@ -51,6 +51,100 @@ class ZlibTransform extends stream.Transform {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
class Caseless {
|
|
55
|
+
/**
|
|
56
|
+
* @param {*} dict
|
|
57
|
+
*/
|
|
58
|
+
constructor(dict) {
|
|
59
|
+
this.dict = dict || {};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {*} name
|
|
65
|
+
* @param {*} value
|
|
66
|
+
* @param {*} clobber
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
set(name, value, clobber) {
|
|
70
|
+
if (typeof name === 'object') {
|
|
71
|
+
for (const n of name) {
|
|
72
|
+
this.set(n, name[n], value);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
if (typeof clobber === 'undefined') clobber = true;
|
|
76
|
+
const has = this.has(name);
|
|
77
|
+
|
|
78
|
+
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value;
|
|
79
|
+
else this.dict[has || name] = value;
|
|
80
|
+
return has
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param {string} name
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
89
|
+
has(name) {
|
|
90
|
+
const keys = Object.keys(this.dict);
|
|
91
|
+
name = name.toLowerCase();
|
|
92
|
+
for (let i = 0; i < keys.length; i++) {
|
|
93
|
+
if (keys[i].toLowerCase() === name) return keys[i]
|
|
94
|
+
}
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
* @param {string} name
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
get(name) {
|
|
104
|
+
name = name.toLowerCase();
|
|
105
|
+
let result;
|
|
106
|
+
let _key;
|
|
107
|
+
const headers = this.dict;
|
|
108
|
+
for (const key of Object.keys(headers)) {
|
|
109
|
+
_key = key.toLowerCase();
|
|
110
|
+
if (name === _key) result = headers[key];
|
|
111
|
+
}
|
|
112
|
+
return result
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
* @param {string} name
|
|
118
|
+
* @returns
|
|
119
|
+
*/
|
|
120
|
+
swap(name) {
|
|
121
|
+
const has = this.has(name);
|
|
122
|
+
if (has === name) return
|
|
123
|
+
if (!has) throw new Error('There is no header than matches "' + name + '"')
|
|
124
|
+
this.dict[name] = this.dict[has];
|
|
125
|
+
delete this.dict[has];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
* @param {string} name
|
|
131
|
+
* @returns
|
|
132
|
+
*/
|
|
133
|
+
del(name) {
|
|
134
|
+
name = String(name).toLowerCase();
|
|
135
|
+
let deleted = false;
|
|
136
|
+
let changed = 0;
|
|
137
|
+
const dict = this.dict;
|
|
138
|
+
for (const key of Object.keys(this.dict)) {
|
|
139
|
+
if (name === String(key).toLowerCase()) {
|
|
140
|
+
deleted = delete dict[key];
|
|
141
|
+
changed += 1;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return changed === 0 ? true : deleted
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
54
148
|
/**
|
|
55
149
|
* utils for request
|
|
56
150
|
*/
|
|
@@ -350,100 +444,6 @@ const utils = {
|
|
|
350
444
|
noBody,
|
|
351
445
|
};
|
|
352
446
|
|
|
353
|
-
class Caseless {
|
|
354
|
-
/**
|
|
355
|
-
* @param {*} dict
|
|
356
|
-
*/
|
|
357
|
-
constructor(dict) {
|
|
358
|
-
this.dict = dict || {};
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
*
|
|
363
|
-
* @param {*} name
|
|
364
|
-
* @param {*} value
|
|
365
|
-
* @param {*} clobber
|
|
366
|
-
* @returns
|
|
367
|
-
*/
|
|
368
|
-
set(name, value, clobber) {
|
|
369
|
-
if (typeof name === 'object') {
|
|
370
|
-
for (const n of name) {
|
|
371
|
-
this.set(n, name[n], value);
|
|
372
|
-
}
|
|
373
|
-
} else {
|
|
374
|
-
if (typeof clobber === 'undefined') clobber = true;
|
|
375
|
-
const has = this.has(name);
|
|
376
|
-
|
|
377
|
-
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value;
|
|
378
|
-
else this.dict[has || name] = value;
|
|
379
|
-
return has
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
*
|
|
385
|
-
* @param {string} name
|
|
386
|
-
* @returns
|
|
387
|
-
*/
|
|
388
|
-
has(name) {
|
|
389
|
-
const keys = Object.keys(this.dict);
|
|
390
|
-
name = name.toLowerCase();
|
|
391
|
-
for (let i = 0; i < keys.length; i++) {
|
|
392
|
-
if (keys[i].toLowerCase() === name) return keys[i]
|
|
393
|
-
}
|
|
394
|
-
return false
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
*
|
|
399
|
-
* @param {string} name
|
|
400
|
-
* @returns
|
|
401
|
-
*/
|
|
402
|
-
get(name) {
|
|
403
|
-
name = name.toLowerCase();
|
|
404
|
-
let result;
|
|
405
|
-
let _key;
|
|
406
|
-
const headers = this.dict;
|
|
407
|
-
for (const key of Object.keys(headers)) {
|
|
408
|
-
_key = key.toLowerCase();
|
|
409
|
-
if (name === _key) result = headers[key];
|
|
410
|
-
}
|
|
411
|
-
return result
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
*
|
|
416
|
-
* @param {string} name
|
|
417
|
-
* @returns
|
|
418
|
-
*/
|
|
419
|
-
swap(name) {
|
|
420
|
-
const has = this.has(name);
|
|
421
|
-
if (has === name) return
|
|
422
|
-
if (!has) throw new Error('There is no header than matches "' + name + '"')
|
|
423
|
-
this.dict[name] = this.dict[has];
|
|
424
|
-
delete this.dict[has];
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
*
|
|
429
|
-
* @param {string} name
|
|
430
|
-
* @returns
|
|
431
|
-
*/
|
|
432
|
-
del(name) {
|
|
433
|
-
name = String(name).toLowerCase();
|
|
434
|
-
let deleted = false;
|
|
435
|
-
let changed = 0;
|
|
436
|
-
const dict = this.dict;
|
|
437
|
-
for (const key of Object.keys(this.dict)) {
|
|
438
|
-
if (name === String(key).toLowerCase()) {
|
|
439
|
-
deleted = delete dict[key];
|
|
440
|
-
changed += 1;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
return changed === 0 ? true : deleted
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
447
|
/**
|
|
448
448
|
* fork from follow-redirects
|
|
449
449
|
* https://github.com/follow-redirects/follow-redirects
|
|
@@ -636,7 +636,7 @@ class Request extends stream.Duplex {
|
|
|
636
636
|
super();
|
|
637
637
|
const m = this;
|
|
638
638
|
|
|
639
|
-
// log({opts}, '
|
|
639
|
+
// log({opts}, 'new Request')
|
|
640
640
|
|
|
641
641
|
// Initialize the request
|
|
642
642
|
m.sanitizeOptions(opts);
|
|
@@ -776,6 +776,8 @@ class Request extends stream.Duplex {
|
|
|
776
776
|
protocol =
|
|
777
777
|
agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
|
|
778
778
|
}
|
|
779
|
+
|
|
780
|
+
// log({scheme, agents, protocol}, 'request')
|
|
779
781
|
}
|
|
780
782
|
|
|
781
783
|
const httpModule = httpModules[protocol];
|
|
@@ -784,6 +786,8 @@ class Request extends stream.Duplex {
|
|
|
784
786
|
// log({opt, protocol}, 'request')
|
|
785
787
|
// Create the native request and set up its event handlers
|
|
786
788
|
// @ts-ignore
|
|
789
|
+
|
|
790
|
+
log$1({httpModule, opt}, 'request');
|
|
787
791
|
const req = httpModule.request(opt, m._onResponse);
|
|
788
792
|
m._currentRequest = req;
|
|
789
793
|
// @ts-ignore
|
|
@@ -1451,8 +1455,8 @@ class Request extends stream.Duplex {
|
|
|
1451
1455
|
* @override - 重写父类方法
|
|
1452
1456
|
* @template T - 需要模板
|
|
1453
1457
|
* @param {T & stream.Writable} dest - The writable stream to which data is written.
|
|
1454
|
-
* @param {Object} [
|
|
1455
|
-
* @param {boolean} [
|
|
1458
|
+
* @param {Object} [opt] - Optional configuration object.
|
|
1459
|
+
* @param {boolean} [opt.end=true] - Whether to end the writable stream when the readable stream ends.
|
|
1456
1460
|
* @returns {T} The destination stream.
|
|
1457
1461
|
*/
|
|
1458
1462
|
pipe(dest, opts = {}) {
|
|
@@ -1645,6 +1649,7 @@ const log = log$2.log({env: `wia:req:${log$2.name((typeof document === 'undefine
|
|
|
1645
1649
|
* @prop {string} [url]
|
|
1646
1650
|
* @prop {'http:' | 'https:'} [protocol]
|
|
1647
1651
|
* @prop {string} [host]
|
|
1652
|
+
* @prop {string} [hostname]
|
|
1648
1653
|
* @prop {string} [family]
|
|
1649
1654
|
* @prop {string} [path]
|
|
1650
1655
|
* @prop {string} [method]
|
|
@@ -1691,7 +1696,7 @@ utils.createErrorType(
|
|
|
1691
1696
|
* @param {string | Opts} uri/opts
|
|
1692
1697
|
* @param {Opts | Cb} [opts] /cb
|
|
1693
1698
|
* @param {Cb} [cb]
|
|
1694
|
-
* @returns {{
|
|
1699
|
+
* @returns {{opt: Opts, cb: Cb}}
|
|
1695
1700
|
*/
|
|
1696
1701
|
function init(uri, opts, cb) {
|
|
1697
1702
|
let R;
|
|
@@ -1727,26 +1732,28 @@ function init(uri, opts, cb) {
|
|
|
1727
1732
|
}
|
|
1728
1733
|
|
|
1729
1734
|
// copy options
|
|
1730
|
-
|
|
1735
|
+
/** @type {Opts} */
|
|
1736
|
+
const opt = {
|
|
1731
1737
|
// @ts-ignore
|
|
1732
1738
|
...uri,
|
|
1733
1739
|
...opts,
|
|
1734
1740
|
};
|
|
1735
1741
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
// @ts-ignore
|
|
1739
|
-
opts.method = (opts.method ?? 'get').toUpperCase();
|
|
1742
|
+
if (!utils.isString(opt.host) && !utils.isString(opt.hostname)) opt.hostname = '::1';
|
|
1743
|
+
opt.method = (opt.method ?? 'get').toUpperCase();
|
|
1740
1744
|
|
|
1741
|
-
// @ts-ignore
|
|
1742
1745
|
// follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1746
|
+
opt.maxBodyLength = opt.maxBodyLength ?? Number.POSITIVE_INFINITY;
|
|
1747
|
+
opt.maxRedirects = opt.maxRedirects ?? 21;
|
|
1748
|
+
if (opt.maxRedirects === 0) opt.followRedirects = false;
|
|
1749
|
+
opt.headers = opt.headers ?? {
|
|
1750
|
+
Accept: 'application/json, text/plain, */*',
|
|
1751
|
+
'User-Agent':
|
|
1752
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35',
|
|
1753
|
+
'Accept-Encoding': 'gzip, compress, deflate, br',
|
|
1754
|
+
};
|
|
1748
1755
|
|
|
1749
|
-
R = {
|
|
1756
|
+
R = {opt, cb};
|
|
1750
1757
|
// log({R}, 'init')
|
|
1751
1758
|
} catch (e) {
|
|
1752
1759
|
log.err(e, 'init');
|
|
@@ -1764,24 +1771,24 @@ function init(uri, opts, cb) {
|
|
|
1764
1771
|
maxRedirects: _.maxRedirects,
|
|
1765
1772
|
maxBodyLength: _.maxBodyLength,
|
|
1766
1773
|
* @param {string | Opts} uri /options
|
|
1767
|
-
* @param {Opts | Cb} [
|
|
1774
|
+
* @param {Opts | Cb} [opts] /callback
|
|
1768
1775
|
* @param {Cb} [callback] /null
|
|
1769
1776
|
* @returns {Request}
|
|
1770
1777
|
*/
|
|
1771
|
-
function request(uri,
|
|
1778
|
+
function request(uri, opts, callback) {
|
|
1772
1779
|
let R = null;
|
|
1773
1780
|
|
|
1774
1781
|
try {
|
|
1775
1782
|
// @ts-ignore
|
|
1776
|
-
const {
|
|
1777
|
-
// log
|
|
1783
|
+
const {opt, cb} = init(uri, opts, callback);
|
|
1784
|
+
// log({uri, opt, opts}, 'request')
|
|
1778
1785
|
|
|
1779
|
-
const {data, stream} =
|
|
1786
|
+
const {data, stream} = opt;
|
|
1780
1787
|
// data 在本函数完成处理,不传递到 request
|
|
1781
|
-
|
|
1788
|
+
opt.data = undefined;
|
|
1782
1789
|
|
|
1783
1790
|
// @ts-ignore
|
|
1784
|
-
const req = new Request(
|
|
1791
|
+
const req = new Request(opt, cb);
|
|
1785
1792
|
|
|
1786
1793
|
// 非流模式,自动发送请求,流模式通过流写入发送
|
|
1787
1794
|
if (!stream) {
|
|
@@ -1826,7 +1833,7 @@ function request(uri, options, callback) {
|
|
|
1826
1833
|
}
|
|
1827
1834
|
|
|
1828
1835
|
/**
|
|
1829
|
-
* 执行简单的数据(支持
|
|
1836
|
+
* 执行简单的数据(支持stream)请求
|
|
1830
1837
|
* 非流模式,直接写入数据流,流模式,由管道触发,或手动调用 end() data.pipe 写入数据
|
|
1831
1838
|
* 复杂数据,请使用 @wiajs/req库(fork from axios),该库封装了当前库,提供了更多功能
|
|
1832
1839
|
* organize params for patch, post, put, head, del
|
package/dist/request.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* wia request v3.0.
|
|
3
|
-
* (c) 2022-
|
|
2
|
+
* wia request v3.0.35
|
|
3
|
+
* (c) 2022-2025 Sibyl Yu and contributors
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
import stream, { Duplex } from 'node:stream';
|
|
7
7
|
import { log as log$2, name } from '@wiajs/log';
|
|
8
|
+
import mime from 'mime-types';
|
|
9
|
+
import assert from 'node:assert';
|
|
8
10
|
import http from 'node:http';
|
|
9
11
|
import https from 'node:https';
|
|
10
|
-
import assert from 'node:assert';
|
|
11
12
|
import url from 'node:url';
|
|
12
13
|
import zlib from 'node:zlib';
|
|
13
|
-
import mime from 'mime-types';
|
|
14
14
|
|
|
15
15
|
class ZlibTransform extends stream.Transform {
|
|
16
16
|
/**
|
|
@@ -48,6 +48,100 @@ class ZlibTransform extends stream.Transform {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
class Caseless {
|
|
52
|
+
/**
|
|
53
|
+
* @param {*} dict
|
|
54
|
+
*/
|
|
55
|
+
constructor(dict) {
|
|
56
|
+
this.dict = dict || {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @param {*} name
|
|
62
|
+
* @param {*} value
|
|
63
|
+
* @param {*} clobber
|
|
64
|
+
* @returns
|
|
65
|
+
*/
|
|
66
|
+
set(name, value, clobber) {
|
|
67
|
+
if (typeof name === 'object') {
|
|
68
|
+
for (const n of name) {
|
|
69
|
+
this.set(n, name[n], value);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
if (typeof clobber === 'undefined') clobber = true;
|
|
73
|
+
const has = this.has(name);
|
|
74
|
+
|
|
75
|
+
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value;
|
|
76
|
+
else this.dict[has || name] = value;
|
|
77
|
+
return has
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* @param {string} name
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
has(name) {
|
|
87
|
+
const keys = Object.keys(this.dict);
|
|
88
|
+
name = name.toLowerCase();
|
|
89
|
+
for (let i = 0; i < keys.length; i++) {
|
|
90
|
+
if (keys[i].toLowerCase() === name) return keys[i]
|
|
91
|
+
}
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @param {string} name
|
|
98
|
+
* @returns
|
|
99
|
+
*/
|
|
100
|
+
get(name) {
|
|
101
|
+
name = name.toLowerCase();
|
|
102
|
+
let result;
|
|
103
|
+
let _key;
|
|
104
|
+
const headers = this.dict;
|
|
105
|
+
for (const key of Object.keys(headers)) {
|
|
106
|
+
_key = key.toLowerCase();
|
|
107
|
+
if (name === _key) result = headers[key];
|
|
108
|
+
}
|
|
109
|
+
return result
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @param {string} name
|
|
115
|
+
* @returns
|
|
116
|
+
*/
|
|
117
|
+
swap(name) {
|
|
118
|
+
const has = this.has(name);
|
|
119
|
+
if (has === name) return
|
|
120
|
+
if (!has) throw new Error('There is no header than matches "' + name + '"')
|
|
121
|
+
this.dict[name] = this.dict[has];
|
|
122
|
+
delete this.dict[has];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @param {string} name
|
|
128
|
+
* @returns
|
|
129
|
+
*/
|
|
130
|
+
del(name) {
|
|
131
|
+
name = String(name).toLowerCase();
|
|
132
|
+
let deleted = false;
|
|
133
|
+
let changed = 0;
|
|
134
|
+
const dict = this.dict;
|
|
135
|
+
for (const key of Object.keys(this.dict)) {
|
|
136
|
+
if (name === String(key).toLowerCase()) {
|
|
137
|
+
deleted = delete dict[key];
|
|
138
|
+
changed += 1;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return changed === 0 ? true : deleted
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
51
145
|
/**
|
|
52
146
|
* utils for request
|
|
53
147
|
*/
|
|
@@ -347,100 +441,6 @@ const utils = {
|
|
|
347
441
|
noBody,
|
|
348
442
|
};
|
|
349
443
|
|
|
350
|
-
class Caseless {
|
|
351
|
-
/**
|
|
352
|
-
* @param {*} dict
|
|
353
|
-
*/
|
|
354
|
-
constructor(dict) {
|
|
355
|
-
this.dict = dict || {};
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
*
|
|
360
|
-
* @param {*} name
|
|
361
|
-
* @param {*} value
|
|
362
|
-
* @param {*} clobber
|
|
363
|
-
* @returns
|
|
364
|
-
*/
|
|
365
|
-
set(name, value, clobber) {
|
|
366
|
-
if (typeof name === 'object') {
|
|
367
|
-
for (const n of name) {
|
|
368
|
-
this.set(n, name[n], value);
|
|
369
|
-
}
|
|
370
|
-
} else {
|
|
371
|
-
if (typeof clobber === 'undefined') clobber = true;
|
|
372
|
-
const has = this.has(name);
|
|
373
|
-
|
|
374
|
-
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value;
|
|
375
|
-
else this.dict[has || name] = value;
|
|
376
|
-
return has
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
*
|
|
382
|
-
* @param {string} name
|
|
383
|
-
* @returns
|
|
384
|
-
*/
|
|
385
|
-
has(name) {
|
|
386
|
-
const keys = Object.keys(this.dict);
|
|
387
|
-
name = name.toLowerCase();
|
|
388
|
-
for (let i = 0; i < keys.length; i++) {
|
|
389
|
-
if (keys[i].toLowerCase() === name) return keys[i]
|
|
390
|
-
}
|
|
391
|
-
return false
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
*
|
|
396
|
-
* @param {string} name
|
|
397
|
-
* @returns
|
|
398
|
-
*/
|
|
399
|
-
get(name) {
|
|
400
|
-
name = name.toLowerCase();
|
|
401
|
-
let result;
|
|
402
|
-
let _key;
|
|
403
|
-
const headers = this.dict;
|
|
404
|
-
for (const key of Object.keys(headers)) {
|
|
405
|
-
_key = key.toLowerCase();
|
|
406
|
-
if (name === _key) result = headers[key];
|
|
407
|
-
}
|
|
408
|
-
return result
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
*
|
|
413
|
-
* @param {string} name
|
|
414
|
-
* @returns
|
|
415
|
-
*/
|
|
416
|
-
swap(name) {
|
|
417
|
-
const has = this.has(name);
|
|
418
|
-
if (has === name) return
|
|
419
|
-
if (!has) throw new Error('There is no header than matches "' + name + '"')
|
|
420
|
-
this.dict[name] = this.dict[has];
|
|
421
|
-
delete this.dict[has];
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
*
|
|
426
|
-
* @param {string} name
|
|
427
|
-
* @returns
|
|
428
|
-
*/
|
|
429
|
-
del(name) {
|
|
430
|
-
name = String(name).toLowerCase();
|
|
431
|
-
let deleted = false;
|
|
432
|
-
let changed = 0;
|
|
433
|
-
const dict = this.dict;
|
|
434
|
-
for (const key of Object.keys(this.dict)) {
|
|
435
|
-
if (name === String(key).toLowerCase()) {
|
|
436
|
-
deleted = delete dict[key];
|
|
437
|
-
changed += 1;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return changed === 0 ? true : deleted
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
444
|
/**
|
|
445
445
|
* fork from follow-redirects
|
|
446
446
|
* https://github.com/follow-redirects/follow-redirects
|
|
@@ -633,7 +633,7 @@ class Request extends Duplex {
|
|
|
633
633
|
super();
|
|
634
634
|
const m = this;
|
|
635
635
|
|
|
636
|
-
// log({opts}, '
|
|
636
|
+
// log({opts}, 'new Request')
|
|
637
637
|
|
|
638
638
|
// Initialize the request
|
|
639
639
|
m.sanitizeOptions(opts);
|
|
@@ -773,6 +773,8 @@ class Request extends Duplex {
|
|
|
773
773
|
protocol =
|
|
774
774
|
agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
|
|
775
775
|
}
|
|
776
|
+
|
|
777
|
+
// log({scheme, agents, protocol}, 'request')
|
|
776
778
|
}
|
|
777
779
|
|
|
778
780
|
const httpModule = httpModules[protocol];
|
|
@@ -781,6 +783,8 @@ class Request extends Duplex {
|
|
|
781
783
|
// log({opt, protocol}, 'request')
|
|
782
784
|
// Create the native request and set up its event handlers
|
|
783
785
|
// @ts-ignore
|
|
786
|
+
|
|
787
|
+
log$1({httpModule, opt}, 'request');
|
|
784
788
|
const req = httpModule.request(opt, m._onResponse);
|
|
785
789
|
m._currentRequest = req;
|
|
786
790
|
// @ts-ignore
|
|
@@ -1448,8 +1452,8 @@ class Request extends Duplex {
|
|
|
1448
1452
|
* @override - 重写父类方法
|
|
1449
1453
|
* @template T - 需要模板
|
|
1450
1454
|
* @param {T & stream.Writable} dest - The writable stream to which data is written.
|
|
1451
|
-
* @param {Object} [
|
|
1452
|
-
* @param {boolean} [
|
|
1455
|
+
* @param {Object} [opt] - Optional configuration object.
|
|
1456
|
+
* @param {boolean} [opt.end=true] - Whether to end the writable stream when the readable stream ends.
|
|
1453
1457
|
* @returns {T} The destination stream.
|
|
1454
1458
|
*/
|
|
1455
1459
|
pipe(dest, opts = {}) {
|
|
@@ -1642,6 +1646,7 @@ const log = log$2({env: `wia:req:${name(import.meta.url)}`}); // __filename
|
|
|
1642
1646
|
* @prop {string} [url]
|
|
1643
1647
|
* @prop {'http:' | 'https:'} [protocol]
|
|
1644
1648
|
* @prop {string} [host]
|
|
1649
|
+
* @prop {string} [hostname]
|
|
1645
1650
|
* @prop {string} [family]
|
|
1646
1651
|
* @prop {string} [path]
|
|
1647
1652
|
* @prop {string} [method]
|
|
@@ -1688,7 +1693,7 @@ utils.createErrorType(
|
|
|
1688
1693
|
* @param {string | Opts} uri/opts
|
|
1689
1694
|
* @param {Opts | Cb} [opts] /cb
|
|
1690
1695
|
* @param {Cb} [cb]
|
|
1691
|
-
* @returns {{
|
|
1696
|
+
* @returns {{opt: Opts, cb: Cb}}
|
|
1692
1697
|
*/
|
|
1693
1698
|
function init(uri, opts, cb) {
|
|
1694
1699
|
let R;
|
|
@@ -1724,26 +1729,28 @@ function init(uri, opts, cb) {
|
|
|
1724
1729
|
}
|
|
1725
1730
|
|
|
1726
1731
|
// copy options
|
|
1727
|
-
|
|
1732
|
+
/** @type {Opts} */
|
|
1733
|
+
const opt = {
|
|
1728
1734
|
// @ts-ignore
|
|
1729
1735
|
...uri,
|
|
1730
1736
|
...opts,
|
|
1731
1737
|
};
|
|
1732
1738
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
// @ts-ignore
|
|
1736
|
-
opts.method = (opts.method ?? 'get').toUpperCase();
|
|
1739
|
+
if (!utils.isString(opt.host) && !utils.isString(opt.hostname)) opt.hostname = '::1';
|
|
1740
|
+
opt.method = (opt.method ?? 'get').toUpperCase();
|
|
1737
1741
|
|
|
1738
|
-
// @ts-ignore
|
|
1739
1742
|
// follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1743
|
+
opt.maxBodyLength = opt.maxBodyLength ?? Number.POSITIVE_INFINITY;
|
|
1744
|
+
opt.maxRedirects = opt.maxRedirects ?? 21;
|
|
1745
|
+
if (opt.maxRedirects === 0) opt.followRedirects = false;
|
|
1746
|
+
opt.headers = opt.headers ?? {
|
|
1747
|
+
Accept: 'application/json, text/plain, */*',
|
|
1748
|
+
'User-Agent':
|
|
1749
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35',
|
|
1750
|
+
'Accept-Encoding': 'gzip, compress, deflate, br',
|
|
1751
|
+
};
|
|
1745
1752
|
|
|
1746
|
-
R = {
|
|
1753
|
+
R = {opt, cb};
|
|
1747
1754
|
// log({R}, 'init')
|
|
1748
1755
|
} catch (e) {
|
|
1749
1756
|
log.err(e, 'init');
|
|
@@ -1761,24 +1768,24 @@ function init(uri, opts, cb) {
|
|
|
1761
1768
|
maxRedirects: _.maxRedirects,
|
|
1762
1769
|
maxBodyLength: _.maxBodyLength,
|
|
1763
1770
|
* @param {string | Opts} uri /options
|
|
1764
|
-
* @param {Opts | Cb} [
|
|
1771
|
+
* @param {Opts | Cb} [opts] /callback
|
|
1765
1772
|
* @param {Cb} [callback] /null
|
|
1766
1773
|
* @returns {Request}
|
|
1767
1774
|
*/
|
|
1768
|
-
function request(uri,
|
|
1775
|
+
function request(uri, opts, callback) {
|
|
1769
1776
|
let R = null;
|
|
1770
1777
|
|
|
1771
1778
|
try {
|
|
1772
1779
|
// @ts-ignore
|
|
1773
|
-
const {
|
|
1774
|
-
// log
|
|
1780
|
+
const {opt, cb} = init(uri, opts, callback);
|
|
1781
|
+
// log({uri, opt, opts}, 'request')
|
|
1775
1782
|
|
|
1776
|
-
const {data, stream} =
|
|
1783
|
+
const {data, stream} = opt;
|
|
1777
1784
|
// data 在本函数完成处理,不传递到 request
|
|
1778
|
-
|
|
1785
|
+
opt.data = undefined;
|
|
1779
1786
|
|
|
1780
1787
|
// @ts-ignore
|
|
1781
|
-
const req = new Request(
|
|
1788
|
+
const req = new Request(opt, cb);
|
|
1782
1789
|
|
|
1783
1790
|
// 非流模式,自动发送请求,流模式通过流写入发送
|
|
1784
1791
|
if (!stream) {
|
|
@@ -1823,7 +1830,7 @@ function request(uri, options, callback) {
|
|
|
1823
1830
|
}
|
|
1824
1831
|
|
|
1825
1832
|
/**
|
|
1826
|
-
* 执行简单的数据(支持
|
|
1833
|
+
* 执行简单的数据(支持stream)请求
|
|
1827
1834
|
* 非流模式,直接写入数据流,流模式,由管道触发,或手动调用 end() data.pipe 写入数据
|
|
1828
1835
|
* 复杂数据,请使用 @wiajs/req库(fork from axios),该库封装了当前库,提供了更多功能
|
|
1829
1836
|
* organize params for patch, post, put, head, del
|
package/lib/index.js
CHANGED
|
@@ -17,6 +17,7 @@ const log = Log({
|
|
|
17
17
|
* @prop {string} [url]
|
|
18
18
|
* @prop {'http:' | 'https:'} [protocol]
|
|
19
19
|
* @prop {string} [host]
|
|
20
|
+
* @prop {string} [hostname]
|
|
20
21
|
* @prop {string} [family]
|
|
21
22
|
* @prop {string} [path]
|
|
22
23
|
* @prop {string} [method]
|
|
@@ -50,7 +51,7 @@ const log = Log({
|
|
|
50
51
|
* @param {string | Opts} uri/opts
|
|
51
52
|
* @param {Opts | Cb} [opts] /cb
|
|
52
53
|
* @param {Cb} [cb]
|
|
53
|
-
* @returns {{
|
|
54
|
+
* @returns {{opt: Opts, cb: Cb}}
|
|
54
55
|
*/ function init(uri, opts, cb) {
|
|
55
56
|
let R;
|
|
56
57
|
try {
|
|
@@ -84,24 +85,24 @@ const log = Log({
|
|
|
84
85
|
opts = {};
|
|
85
86
|
}
|
|
86
87
|
// copy options
|
|
87
|
-
|
|
88
|
+
/** @type {Opts} */ const opt = {
|
|
88
89
|
// @ts-ignore
|
|
89
90
|
...uri,
|
|
90
91
|
...opts
|
|
91
92
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// @ts-ignore
|
|
95
|
-
opts.method = (opts.method ?? 'get').toUpperCase();
|
|
96
|
-
// @ts-ignore
|
|
93
|
+
if (!utils.isString(opt.host) && !utils.isString(opt.hostname)) opt.hostname = '::1';
|
|
94
|
+
opt.method = (opt.method ?? 'get').toUpperCase();
|
|
97
95
|
// follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
opt.maxBodyLength = opt.maxBodyLength ?? Number.POSITIVE_INFINITY;
|
|
97
|
+
opt.maxRedirects = opt.maxRedirects ?? 21;
|
|
98
|
+
if (opt.maxRedirects === 0) opt.followRedirects = false;
|
|
99
|
+
opt.headers = opt.headers ?? {
|
|
100
|
+
Accept: 'application/json, text/plain, */*',
|
|
101
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.35',
|
|
102
|
+
'Accept-Encoding': 'gzip, compress, deflate, br'
|
|
103
|
+
};
|
|
103
104
|
R = {
|
|
104
|
-
|
|
105
|
+
opt,
|
|
105
106
|
cb
|
|
106
107
|
};
|
|
107
108
|
// log({R}, 'init')
|
|
@@ -119,20 +120,20 @@ const log = Log({
|
|
|
119
120
|
maxRedirects: _.maxRedirects,
|
|
120
121
|
maxBodyLength: _.maxBodyLength,
|
|
121
122
|
* @param {string | Opts} uri /options
|
|
122
|
-
* @param {Opts | Cb} [
|
|
123
|
+
* @param {Opts | Cb} [opts] /callback
|
|
123
124
|
* @param {Cb} [callback] /null
|
|
124
125
|
* @returns {Request}
|
|
125
|
-
*/ function request(uri,
|
|
126
|
+
*/ function request(uri, opts, callback) {
|
|
126
127
|
let R = null;
|
|
127
128
|
try {
|
|
128
129
|
// @ts-ignore
|
|
129
|
-
const {
|
|
130
|
-
// log
|
|
131
|
-
const { data, stream } =
|
|
130
|
+
const { opt, cb } = init(uri, opts, callback);
|
|
131
|
+
// log({uri, opt, opts}, 'request')
|
|
132
|
+
const { data, stream } = opt;
|
|
132
133
|
// data 在本函数完成处理,不传递到 request
|
|
133
|
-
|
|
134
|
+
opt.data = undefined;
|
|
134
135
|
// @ts-ignore
|
|
135
|
-
const req = new Request(
|
|
136
|
+
const req = new Request(opt, cb);
|
|
136
137
|
// 非流模式,自动发送请求,流模式通过流写入发送
|
|
137
138
|
if (!stream) {
|
|
138
139
|
// 发送数据
|
|
@@ -168,7 +169,7 @@ const log = Log({
|
|
|
168
169
|
return R;
|
|
169
170
|
}
|
|
170
171
|
/**
|
|
171
|
-
* 执行简单的数据(支持
|
|
172
|
+
* 执行简单的数据(支持stream)请求
|
|
172
173
|
* 非流模式,直接写入数据流,流模式,由管道触发,或手动调用 end() data.pipe 写入数据
|
|
173
174
|
* 复杂数据,请使用 @wiajs/req库(fork from axios),该库封装了当前库,提供了更多功能
|
|
174
175
|
* organize params for patch, post, put, head, del
|
package/lib/request.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* fork from follow-redirects
|
|
3
3
|
* https://github.com/follow-redirects/follow-redirects
|
|
4
|
-
*/ import
|
|
5
|
-
import
|
|
4
|
+
*/ import { log as Log, name } from '@wiajs/log';
|
|
5
|
+
import mime from 'mime-types';
|
|
6
6
|
import assert from 'node:assert';
|
|
7
|
+
import http from 'node:http';
|
|
8
|
+
import https from 'node:https';
|
|
9
|
+
import stream, { Duplex } from 'node:stream';
|
|
7
10
|
import url from 'node:url';
|
|
8
|
-
import stream from 'node:stream';
|
|
9
|
-
import { Duplex } from 'node:stream'; // Writable 流改为读写双工
|
|
10
11
|
import zlib from 'node:zlib';
|
|
11
|
-
import mime from 'mime-types';
|
|
12
|
-
import { log as Log, name } from '@wiajs/log';
|
|
13
12
|
import ZlibTransform from './ZlibTransform.js';
|
|
14
|
-
import utils from './utils.js';
|
|
15
13
|
import Caseless from './caseless.js';
|
|
14
|
+
import utils from './utils.js';
|
|
16
15
|
const log = Log({
|
|
17
16
|
env: `wia:req:${name(import.meta.url)}`
|
|
18
17
|
}) // __filename
|
|
@@ -149,7 +148,7 @@ const ConnResetError = utils.createErrorType('ERR_CONNRESET', '连接被重置
|
|
|
149
148
|
, /** @type {stream.Writable[]} */ this.pipedests = [] // pipe dest
|
|
150
149
|
, /** @type {*} */ this.startTimer = null;
|
|
151
150
|
const m = this;
|
|
152
|
-
// log({opts}, '
|
|
151
|
+
// log({opts}, 'new Request')
|
|
153
152
|
// Initialize the request
|
|
154
153
|
m.sanitizeOptions(opts);
|
|
155
154
|
m.opt = opts;
|
|
@@ -259,12 +258,17 @@ const ConnResetError = utils.createErrorType('ERR_CONNRESET', '连接被重置
|
|
|
259
258
|
if (protocol === 'http:' && agents.http) {
|
|
260
259
|
protocol = agents.http.proxy && !agents.http.tunnel ? agents.http.proxy.protocol : protocol;
|
|
261
260
|
}
|
|
261
|
+
// log({scheme, agents, protocol}, 'request')
|
|
262
262
|
}
|
|
263
263
|
const httpModule = httpModules[protocol];
|
|
264
264
|
if (!httpModule) throw TypeError(`Unsupported protocol: ${protocol}`);
|
|
265
265
|
// log({opt, protocol}, 'request')
|
|
266
266
|
// Create the native request and set up its event handlers
|
|
267
267
|
// @ts-ignore
|
|
268
|
+
log({
|
|
269
|
+
httpModule,
|
|
270
|
+
opt
|
|
271
|
+
}, 'request');
|
|
268
272
|
const req = httpModule.request(opt, m._onResponse);
|
|
269
273
|
m._currentRequest = req;
|
|
270
274
|
// @ts-ignore
|
|
@@ -818,8 +822,8 @@ const ConnResetError = utils.createErrorType('ERR_CONNRESET', '连接被重置
|
|
|
818
822
|
* @override - 重写父类方法
|
|
819
823
|
* @template T - 需要模板
|
|
820
824
|
* @param {T & stream.Writable} dest - The writable stream to which data is written.
|
|
821
|
-
* @param {Object} [
|
|
822
|
-
* @param {boolean} [
|
|
825
|
+
* @param {Object} [opt] - Optional configuration object.
|
|
826
|
+
* @param {boolean} [opt.end=true] - Whether to end the writable stream when the readable stream ends.
|
|
823
827
|
* @returns {T} The destination stream.
|
|
824
828
|
*/ pipe(dest, opts = {}) {
|
|
825
829
|
const m = this;
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type Opts = {
|
|
|
7
7
|
url?: string;
|
|
8
8
|
protocol?: "http:" | "https:";
|
|
9
9
|
host?: string;
|
|
10
|
+
hostname?: string;
|
|
10
11
|
family?: string;
|
|
11
12
|
path?: string;
|
|
12
13
|
method?: string;
|
|
@@ -24,7 +25,7 @@ export type Opts = {
|
|
|
24
25
|
trackRedirects?: any;
|
|
25
26
|
};
|
|
26
27
|
export type Cb = (res: Response, stream?: stream.Readable) => void;
|
|
27
|
-
declare function request(uri: string | Opts,
|
|
28
|
+
declare function request(uri: string | Opts, opts?: Opts | Cb, callback?: Cb): Request;
|
|
28
29
|
declare namespace request {
|
|
29
30
|
export let get: (url: string | Opts, opts?: Opts | Cb, cb?: Cb) => void;
|
|
30
31
|
export let head: (url: string | Opts, opts?: Opts | Cb, cb?: Cb) => void;
|
package/types/request.d.ts
CHANGED
|
@@ -44,9 +44,7 @@ export default class Request extends stream.Duplex {
|
|
|
44
44
|
processResponse(response: Response): void;
|
|
45
45
|
_isRedirect: boolean;
|
|
46
46
|
processStream(res: Response): Response | stream.Readable;
|
|
47
|
-
override pipe<T>(dest: T & stream.Writable, opts?: {
|
|
48
|
-
end?: boolean;
|
|
49
|
-
}): T;
|
|
47
|
+
override pipe<T>(dest: T & stream.Writable, opts?: {}): T;
|
|
50
48
|
unpipe(dest: stream.Writable): this;
|
|
51
49
|
pipeDest(dest: any): void;
|
|
52
50
|
pause(): this;
|