@e-mc/request 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/index.js +98 -41
- package/package.json +4 -4
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const fs = require("fs");
|
|
@@ -33,10 +33,11 @@ const kHostInfo = Symbol('hostInfo');
|
|
|
33
33
|
const kConnectDns = Symbol('connectDns');
|
|
34
34
|
const kPendingDns = Symbol('pendingDns');
|
|
35
35
|
const kConnectHttp = Symbol('connectHttp');
|
|
36
|
+
const kStatusOn = Symbol('statusOn');
|
|
36
37
|
const kHeadersOn = Symbol('headersOn');
|
|
37
38
|
const PLATFORM_WIN32 = process.platform === 'win32';
|
|
38
39
|
const SUPPORT_NODEJS20 = module_1.default.supported(20);
|
|
39
|
-
const SUPPORT_ABORTSIGNAL = module_1.default.supported(15,
|
|
40
|
+
const SUPPORT_ABORTSIGNAL = module_1.default.supported(15, 3) || module_1.default.supported(14, 17, 0, true);
|
|
40
41
|
const HTTP = {
|
|
41
42
|
HOST: {},
|
|
42
43
|
HEADERS: {},
|
|
@@ -104,17 +105,18 @@ function getBaseHeaders(uri, headers) {
|
|
|
104
105
|
return result[0][1];
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
|
-
function setDnsCache(hostname, value) {
|
|
108
|
-
|
|
108
|
+
function setDnsCache(hostname, value, expires) {
|
|
109
|
+
expires ?? (expires = DNS.EXPIRES);
|
|
110
|
+
if (expires > 0 && !DNS.CACHE[hostname]) {
|
|
109
111
|
DNS.CACHE[hostname] = value;
|
|
110
|
-
if (
|
|
112
|
+
if (expires !== Infinity) {
|
|
111
113
|
const timeout = setTimeout(() => {
|
|
112
114
|
const index = DNS.TIMEOUT.findIndex(item => item === timeout);
|
|
113
115
|
if (index !== -1) {
|
|
114
116
|
DNS.TIMEOUT.splice(index, 1);
|
|
115
117
|
}
|
|
116
118
|
DNS.CACHE[hostname] = undefined;
|
|
117
|
-
},
|
|
119
|
+
}, expires);
|
|
118
120
|
DNS.TIMEOUT.push(timeout);
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -259,6 +261,15 @@ function validateCerts(certs) {
|
|
|
259
261
|
}
|
|
260
262
|
return [text, file];
|
|
261
263
|
}
|
|
264
|
+
function abortHeaders(href, request, options) {
|
|
265
|
+
const reason = (0, types_1.errorValue)("Aborted by client" /* ERR_MESSAGE.ABORTED_CLIENT */, href);
|
|
266
|
+
const outAbort = options.outAbort;
|
|
267
|
+
if (outAbort) {
|
|
268
|
+
outAbort.abort(reason);
|
|
269
|
+
this[kDownloading].delete(outAbort);
|
|
270
|
+
}
|
|
271
|
+
request.destroy(reason);
|
|
272
|
+
}
|
|
262
273
|
class Request extends module_1.default {
|
|
263
274
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
264
275
|
if (percent >= 1) {
|
|
@@ -522,6 +533,8 @@ class Request extends module_1.default {
|
|
|
522
533
|
return 'Locked';
|
|
523
534
|
case 424 /* HTTP_STATUS.FAILED_DEPENDENCY */:
|
|
524
535
|
return 'Failed Dependency';
|
|
536
|
+
case 425 /* HTTP_STATUS.TOO_EARLY */:
|
|
537
|
+
return 'Too Early';
|
|
525
538
|
case 426 /* HTTP_STATUS.UPGRADE_REQUIRED */:
|
|
526
539
|
return 'Upgrade Required';
|
|
527
540
|
case 428 /* HTTP_STATUS.PRECONDITION_REQUIRED */:
|
|
@@ -554,6 +567,8 @@ class Request extends module_1.default {
|
|
|
554
567
|
return 'Insufficient Storage';
|
|
555
568
|
case 508 /* HTTP_STATUS.LOOP_DETECTED */:
|
|
556
569
|
return 'Loop Detected';
|
|
570
|
+
case 509 /* HTTP_STATUS.BANDWIDTH_LIMIT_EXCEEDED */:
|
|
571
|
+
return 'Bandwidth Limit Exceeded';
|
|
557
572
|
case 510 /* HTTP_STATUS.NOT_EXTENDED */:
|
|
558
573
|
return 'Not Extended';
|
|
559
574
|
case 511 /* HTTP_STATUS.NETWORK_AUTHENTICATION_REQUIRED */:
|
|
@@ -634,10 +649,11 @@ class Request extends module_1.default {
|
|
|
634
649
|
this[_e] = Object.create(null);
|
|
635
650
|
this[_f] = Object.create(null);
|
|
636
651
|
this[_g] = [{}, {}];
|
|
637
|
-
this[_h] =
|
|
638
|
-
this[_j] =
|
|
639
|
-
this[_k] =
|
|
640
|
-
this[_l] =
|
|
652
|
+
this[_h] = null;
|
|
653
|
+
this[_j] = null;
|
|
654
|
+
this[_k] = new Set();
|
|
655
|
+
this[_l] = {};
|
|
656
|
+
this[_m] = [Object.create(null)];
|
|
641
657
|
if ((0, types_1.isPlainObject)(data)) {
|
|
642
658
|
const { headers, read_timeout, agent, use, connect, certs } = data;
|
|
643
659
|
const timeout = (0, util_1.fromSeconds)(data.timeout);
|
|
@@ -826,8 +842,11 @@ class Request extends module_1.default {
|
|
|
826
842
|
}
|
|
827
843
|
return this;
|
|
828
844
|
}
|
|
829
|
-
addDns(hostname, address, family) {
|
|
845
|
+
addDns(hostname, address, family, timeout) {
|
|
830
846
|
switch (family) {
|
|
847
|
+
case 4:
|
|
848
|
+
case 6:
|
|
849
|
+
break;
|
|
831
850
|
case 'IPv4':
|
|
832
851
|
family = 4;
|
|
833
852
|
break;
|
|
@@ -835,6 +854,9 @@ class Request extends module_1.default {
|
|
|
835
854
|
family = 6;
|
|
836
855
|
break;
|
|
837
856
|
default:
|
|
857
|
+
if (typeof family === 'number' && timeout === undefined) {
|
|
858
|
+
timeout = family;
|
|
859
|
+
}
|
|
838
860
|
if (net.isIPv4(address)) {
|
|
839
861
|
family = 4;
|
|
840
862
|
}
|
|
@@ -846,17 +868,17 @@ class Request extends module_1.default {
|
|
|
846
868
|
}
|
|
847
869
|
break;
|
|
848
870
|
}
|
|
849
|
-
setDnsCache(hostname, this[kConnectDns][hostname] = [{ address, family }]);
|
|
871
|
+
setDnsCache(hostname, this[kConnectDns][hostname] = [{ address, family }], timeout);
|
|
850
872
|
}
|
|
851
873
|
lookupDns(hostname) {
|
|
852
|
-
var
|
|
874
|
+
var _o;
|
|
853
875
|
const resolved = this[kConnectDns][hostname] || DNS.CACHE[hostname];
|
|
854
876
|
if (resolved) {
|
|
855
877
|
return (...args) => {
|
|
856
878
|
return SUPPORT_NODEJS20 ? args[2](null, resolved) : args[2](null, resolved[0].address, resolved[0].family);
|
|
857
879
|
};
|
|
858
880
|
}
|
|
859
|
-
const pending = (
|
|
881
|
+
const pending = (_o = this[kPendingDns])[hostname] || (_o[hostname] = []);
|
|
860
882
|
return (value, options, callback) => {
|
|
861
883
|
if (pending.push(callback) === 1) {
|
|
862
884
|
const configure = (family) => family === 0 ? options : { family, hints: family === 6 ? dns.V4MAPPED : 0 };
|
|
@@ -928,13 +950,29 @@ class Request extends module_1.default {
|
|
|
928
950
|
}
|
|
929
951
|
}
|
|
930
952
|
}
|
|
953
|
+
statusOn(code, patternUrl = '*', callback) {
|
|
954
|
+
if (typeof patternUrl === 'function') {
|
|
955
|
+
callback = patternUrl;
|
|
956
|
+
patternUrl = '*';
|
|
957
|
+
}
|
|
958
|
+
if ((0, types_1.isString)(patternUrl) && typeof callback === 'function') {
|
|
959
|
+
const on = this[kStatusOn] || (this[kStatusOn] = new Map());
|
|
960
|
+
for (const item of !Array.isArray(code) ? [code] : code) {
|
|
961
|
+
let status = on.get(item);
|
|
962
|
+
if (!status) {
|
|
963
|
+
on.set(item, status = []);
|
|
964
|
+
}
|
|
965
|
+
status.push([patternUrl, callback]);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
931
969
|
headersOn(name, patternUrl = '*', callback) {
|
|
932
970
|
if (typeof patternUrl === 'function') {
|
|
933
971
|
callback = patternUrl;
|
|
934
972
|
patternUrl = '*';
|
|
935
973
|
}
|
|
936
974
|
if ((0, types_1.isString)(patternUrl) && typeof callback === 'function') {
|
|
937
|
-
const on = this[kHeadersOn];
|
|
975
|
+
const on = this[kHeadersOn] || (this[kHeadersOn] = new Map());
|
|
938
976
|
for (const item of !Array.isArray(name) ? [name] : name) {
|
|
939
977
|
let headers = on.get(item);
|
|
940
978
|
if (!headers) {
|
|
@@ -1311,21 +1349,21 @@ class Request extends module_1.default {
|
|
|
1311
1349
|
return this.get(uri, options);
|
|
1312
1350
|
}
|
|
1313
1351
|
opts(url, options) {
|
|
1314
|
-
var
|
|
1352
|
+
var _o, _p, _q, _r;
|
|
1315
1353
|
if (typeof url === 'string') {
|
|
1316
1354
|
url = new URL(url);
|
|
1317
1355
|
}
|
|
1318
1356
|
let host;
|
|
1319
1357
|
if (this.host) {
|
|
1320
|
-
host = (
|
|
1358
|
+
host = (_o = HTTP.HOST)[_p = url.origin] || (_o[_p] = new host_1.default(url, HTTP.VERSION));
|
|
1321
1359
|
}
|
|
1322
1360
|
else {
|
|
1323
|
-
host = (
|
|
1361
|
+
host = (_q = this[kHostInfo])[_r = url.origin] || (_q[_r] = new host_1.default(url, this.httpVersion || 1));
|
|
1324
1362
|
}
|
|
1325
1363
|
return { ...options, host, url };
|
|
1326
1364
|
}
|
|
1327
1365
|
open(uri, options) {
|
|
1328
|
-
var
|
|
1366
|
+
var _o, _p;
|
|
1329
1367
|
let { host, url, httpVersion, method = 'GET', encoding, format, headers, postData, keepAlive, agentTimeout, socketPath, timeout = this._config.connectTimeout, outStream } = options;
|
|
1330
1368
|
const getting = method === 'GET';
|
|
1331
1369
|
const posting = method === 'POST';
|
|
@@ -1417,7 +1455,7 @@ class Request extends module_1.default {
|
|
|
1417
1455
|
const version = this.httpVersion;
|
|
1418
1456
|
let request, ca, cert, key, minVersion, baseHeaders = this.headersOf(uri);
|
|
1419
1457
|
if (getting && this.acceptEncoding && !localhost && !baseHeaders?.['accept-encoding']) {
|
|
1420
|
-
(
|
|
1458
|
+
(_o = (headers || (headers = {})))['accept-encoding'] || (_o['accept-encoding'] = 'gzip, deflate, br' + (LIB_ZSTD ? ', zstd' : ''));
|
|
1421
1459
|
}
|
|
1422
1460
|
if (secure) {
|
|
1423
1461
|
const certs = this[kCerts]?.[0][origin] || (this.host ? TLS.TEXT[origin] : null);
|
|
@@ -1426,7 +1464,7 @@ class Request extends module_1.default {
|
|
|
1426
1464
|
}
|
|
1427
1465
|
}
|
|
1428
1466
|
if (!proxy && httpVersion !== 1 && ((httpVersion || host.version) === 2 && version !== 1 || secure && version === 2 && host.failed(2, true) === 0)) {
|
|
1429
|
-
request = ((
|
|
1467
|
+
request = ((_p = this[kSession][0])[origin] || (_p[origin] = http2.connect(origin, { lookup: this.lookupDns(hostname), ca, cert, key, minVersion, settings: localhost ? { initialWindowSize: 4294967295 /* CONSTANTS.INITIAL_WINDOW_SIZE */, maxFrameSize: 16777215 /* CONSTANTS.MAX_FRAME_SIZE */, enablePush: false } : { enablePush: false } }))).request({ ...baseHeaders, ...host_1.default.getBasicAuth(url), ...headers, ':path': pathname, ':method': method });
|
|
1430
1468
|
if (getting) {
|
|
1431
1469
|
const listenerMap = {};
|
|
1432
1470
|
const onEvent = request.on.bind(request);
|
|
@@ -1435,7 +1473,7 @@ class Request extends module_1.default {
|
|
|
1435
1473
|
request.on('response', response => {
|
|
1436
1474
|
connected = true;
|
|
1437
1475
|
const statusCode = response[':status'];
|
|
1438
|
-
if (statusCode >= 200 /* HTTP_STATUS.OK */ && statusCode < 300 /* HTTP_STATUS.MULTIPLE_CHOICES */) {
|
|
1476
|
+
if (this.matchStatus(statusCode, url, response, request, options) && statusCode >= 200 /* HTTP_STATUS.OK */ && statusCode < 300 /* HTTP_STATUS.MULTIPLE_CHOICES */) {
|
|
1439
1477
|
if (emitter = checkEncoding(request, statusCode, response['content-encoding'])) {
|
|
1440
1478
|
for (const event in listenerMap) {
|
|
1441
1479
|
listenerMap[event].forEach(listener => {
|
|
@@ -1463,7 +1501,7 @@ class Request extends module_1.default {
|
|
|
1463
1501
|
this.matchHeaders(url, response, request, options);
|
|
1464
1502
|
});
|
|
1465
1503
|
request.on = function (event, listener) {
|
|
1466
|
-
var
|
|
1504
|
+
var _o;
|
|
1467
1505
|
switch (event) {
|
|
1468
1506
|
case 'data':
|
|
1469
1507
|
case 'error':
|
|
@@ -1473,7 +1511,7 @@ class Request extends module_1.default {
|
|
|
1473
1511
|
break;
|
|
1474
1512
|
}
|
|
1475
1513
|
if (!connected) {
|
|
1476
|
-
(listenerMap[
|
|
1514
|
+
(listenerMap[_o = event + '-on'] || (listenerMap[_o] = [])).push(listener);
|
|
1477
1515
|
}
|
|
1478
1516
|
default:
|
|
1479
1517
|
onEvent(event, listener);
|
|
@@ -1482,7 +1520,7 @@ class Request extends module_1.default {
|
|
|
1482
1520
|
return this;
|
|
1483
1521
|
};
|
|
1484
1522
|
request.once = function (event, listener) {
|
|
1485
|
-
var
|
|
1523
|
+
var _o;
|
|
1486
1524
|
switch (event) {
|
|
1487
1525
|
case 'data':
|
|
1488
1526
|
case 'error':
|
|
@@ -1492,7 +1530,7 @@ class Request extends module_1.default {
|
|
|
1492
1530
|
break;
|
|
1493
1531
|
}
|
|
1494
1532
|
if (!connected) {
|
|
1495
|
-
(listenerMap[
|
|
1533
|
+
(listenerMap[_o = event + '-once'] || (listenerMap[_o] = [])).push(listener);
|
|
1496
1534
|
}
|
|
1497
1535
|
default:
|
|
1498
1536
|
onceEvent(event, listener);
|
|
@@ -1556,7 +1594,7 @@ class Request extends module_1.default {
|
|
|
1556
1594
|
}, response => {
|
|
1557
1595
|
const statusCode = response.statusCode;
|
|
1558
1596
|
const incoming = response.headers;
|
|
1559
|
-
if ((getting || posting) && statusCode >= 200 /* HTTP_STATUS.OK */ && statusCode < 300 /* HTTP_STATUS.MULTIPLE_CHOICES */) {
|
|
1597
|
+
if (this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 /* HTTP_STATUS.OK */ && statusCode < 300 /* HTTP_STATUS.MULTIPLE_CHOICES */) {
|
|
1560
1598
|
let source = checkEncoding(response, statusCode, incoming['content-encoding']);
|
|
1561
1599
|
if (source) {
|
|
1562
1600
|
source.once('finish', () => request.emit('end'));
|
|
@@ -1788,7 +1826,7 @@ class Request extends module_1.default {
|
|
|
1788
1826
|
async get(uri, options = {}) {
|
|
1789
1827
|
const opts = (typeof options === 'string' ? { format: options, encoding: 'utf-8' } : options);
|
|
1790
1828
|
if (this.readExpect === 'string') {
|
|
1791
|
-
opts.encoding = (0, types_1.getEncoding)(opts
|
|
1829
|
+
opts.encoding = (0, types_1.getEncoding)(opts.encoding);
|
|
1792
1830
|
}
|
|
1793
1831
|
return new Promise((resolve, reject) => {
|
|
1794
1832
|
const { silent = this[kSingleton], pipeTo } = opts;
|
|
@@ -2217,9 +2255,33 @@ class Request extends module_1.default {
|
|
|
2217
2255
|
});
|
|
2218
2256
|
this[kDownloading].clear();
|
|
2219
2257
|
}
|
|
2258
|
+
matchStatus(code, url, headers, request, options) {
|
|
2259
|
+
const status = this[kStatusOn]?.get(code);
|
|
2260
|
+
if (status) {
|
|
2261
|
+
const href = url.href;
|
|
2262
|
+
const called = new Set();
|
|
2263
|
+
for (const [pattern, callback] of status) {
|
|
2264
|
+
if (pattern === '*' || pm.isMatch(href, pattern)) {
|
|
2265
|
+
called.add(callback);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
for (const callback of called) {
|
|
2269
|
+
try {
|
|
2270
|
+
if (callback(code, headers, url) === true) {
|
|
2271
|
+
abortHeaders.call(this, href, request, options);
|
|
2272
|
+
return false;
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
catch (err) {
|
|
2276
|
+
this.writeFail(["Unable to process headers" /* ERR_HTTP.HEADERS */, url.origin], err, { type: 1024 /* LOG_TYPE.HTTP */, abortable: this.abortable, fatal: false });
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
return true;
|
|
2281
|
+
}
|
|
2220
2282
|
matchHeaders(url, headers, request, options) {
|
|
2221
2283
|
const on = this[kHeadersOn];
|
|
2222
|
-
if (on
|
|
2284
|
+
if (on?.size) {
|
|
2223
2285
|
const href = url.href;
|
|
2224
2286
|
const called = new Map();
|
|
2225
2287
|
for (const [name, item] of on) {
|
|
@@ -2238,21 +2300,16 @@ class Request extends module_1.default {
|
|
|
2238
2300
|
for (const [callback, data] of called) {
|
|
2239
2301
|
try {
|
|
2240
2302
|
if (callback(data, url) === true) {
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
if (outAbort) {
|
|
2244
|
-
outAbort.abort(reason);
|
|
2245
|
-
this[kDownloading].delete(outAbort);
|
|
2246
|
-
}
|
|
2247
|
-
request.destroy(reason);
|
|
2248
|
-
return;
|
|
2303
|
+
abortHeaders.call(this, href, request, options);
|
|
2304
|
+
return false;
|
|
2249
2305
|
}
|
|
2250
2306
|
}
|
|
2251
2307
|
catch (err) {
|
|
2252
|
-
this.writeFail([
|
|
2308
|
+
this.writeFail(["Unable to process headers" /* ERR_HTTP.HEADERS */, url.origin], err, { type: 1024 /* LOG_TYPE.HTTP */, abortable: this.abortable, fatal: false });
|
|
2253
2309
|
}
|
|
2254
2310
|
}
|
|
2255
2311
|
}
|
|
2312
|
+
return true;
|
|
2256
2313
|
}
|
|
2257
2314
|
set agentTimeout(value) {
|
|
2258
2315
|
if (value > 0) {
|
|
@@ -2291,11 +2348,11 @@ class Request extends module_1.default {
|
|
|
2291
2348
|
return this[kIpVersion];
|
|
2292
2349
|
}
|
|
2293
2350
|
get settings() {
|
|
2294
|
-
var
|
|
2295
|
-
return (
|
|
2351
|
+
var _o;
|
|
2352
|
+
return (_o = this.module).settings || (_o.settings = {});
|
|
2296
2353
|
}
|
|
2297
2354
|
}
|
|
2298
|
-
_a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kConnectDns, _f = kPendingDns, _g = kConnectHttp, _h =
|
|
2355
|
+
_a = kSingleton, _b = kHttpVersion, _c = kHeaders, _d = kCerts, _e = kConnectDns, _f = kPendingDns, _g = kConnectHttp, _h = kStatusOn, _j = kHeadersOn, _k = kDownloading, _l = kHostInfo, _m = kSession;
|
|
2299
2356
|
exports.default = Request;
|
|
2300
2357
|
|
|
2301
2358
|
if (exports.default) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/request",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Request constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/anpham6/e-mc.git",
|
|
12
|
+
"url": "git+https://github.com/anpham6/e-mc.git",
|
|
13
13
|
"directory": "src/request"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"license": "BSD 3-Clause",
|
|
21
21
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/module": "0.8.
|
|
24
|
-
"@e-mc/types": "0.8.
|
|
23
|
+
"@e-mc/module": "0.8.3",
|
|
24
|
+
"@e-mc/types": "0.8.3",
|
|
25
25
|
"combined-stream": "^1.0.8",
|
|
26
26
|
"js-yaml": "^4.1.0",
|
|
27
27
|
"picomatch": "^3.0.1",
|