@e-mc/request 0.9.1 → 0.9.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 +4 -4
- package/http/host/index.js +4 -4
- package/index.js +98 -70
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
* [View Source](https://www.unpkg.com/@e-mc/types@0.9.
|
|
12
|
+
* [View Source](https://www.unpkg.com/@e-mc/types@0.9.3/lib/index.d.ts)
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IModule, ModuleConstructor } from "./index";
|
|
@@ -201,9 +201,9 @@ instance.get("http://hostname/path/config.yml", options).then(data => {
|
|
|
201
201
|
|
|
202
202
|
## References
|
|
203
203
|
|
|
204
|
-
- https://www.unpkg.com/@e-mc/types@0.9.
|
|
205
|
-
- https://www.unpkg.com/@e-mc/types@0.9.
|
|
206
|
-
- https://www.unpkg.com/@e-mc/types@0.9.
|
|
204
|
+
- https://www.unpkg.com/@e-mc/types@0.9.3/lib/http.d.ts
|
|
205
|
+
- https://www.unpkg.com/@e-mc/types@0.9.3/lib/request.d.ts
|
|
206
|
+
- https://www.unpkg.com/@e-mc/types@0.9.3/lib/settings.d.ts
|
|
207
207
|
|
|
208
208
|
* https://www.npmjs.com/package/@types/node
|
|
209
209
|
|
package/http/host/index.js
CHANGED
|
@@ -100,28 +100,28 @@ class HttpHost {
|
|
|
100
100
|
return this._tlsConnect || (this._tlsConnect = new Promise(resolve => {
|
|
101
101
|
const alpn = 'h' + version;
|
|
102
102
|
const socket = tls.connect(+this.port, this.hostname, { ALPNProtocols: [alpn], requestCert: true, rejectUnauthorized: false }, () => {
|
|
103
|
-
resolve(data[3] = alpn === socket.alpnProtocol ? 1 : 0);
|
|
104
103
|
this._tlsConnect = null;
|
|
104
|
+
resolve(data[3] = alpn === socket.alpnProtocol ? 1 : 0);
|
|
105
105
|
});
|
|
106
106
|
socket
|
|
107
107
|
.setNoDelay(false)
|
|
108
108
|
.setTimeout(10000)
|
|
109
109
|
.on('timeout', () => {
|
|
110
|
+
socket.destroy();
|
|
110
111
|
if (this._tlsConnect) {
|
|
112
|
+
this._tlsConnect = null;
|
|
111
113
|
if (this.error(version) >= 10) {
|
|
112
114
|
resolve(data[3] = 0);
|
|
113
115
|
}
|
|
114
116
|
else {
|
|
115
117
|
resolve(2);
|
|
116
118
|
}
|
|
117
|
-
this._tlsConnect = null;
|
|
118
119
|
}
|
|
119
|
-
socket.destroy();
|
|
120
120
|
})
|
|
121
121
|
.on('error', () => {
|
|
122
122
|
this.failed(version);
|
|
123
|
-
resolve(data[3] = 0);
|
|
124
123
|
this._tlsConnect = null;
|
|
124
|
+
resolve(data[3] = 0);
|
|
125
125
|
})
|
|
126
126
|
.end();
|
|
127
127
|
}));
|
package/index.js
CHANGED
|
@@ -267,6 +267,61 @@ function abortHeaders(href, request, options) {
|
|
|
267
267
|
}
|
|
268
268
|
request.destroy(reason);
|
|
269
269
|
}
|
|
270
|
+
function checkEncoding(request, response, statusCode, outStream, contentEncoding = '') {
|
|
271
|
+
switch (statusCode) {
|
|
272
|
+
case 206:
|
|
273
|
+
request.emit('error', (0, types_1.errorValue)("Aborted", 'Partial content'));
|
|
274
|
+
case 204:
|
|
275
|
+
return;
|
|
276
|
+
default:
|
|
277
|
+
contentEncoding = contentEncoding.trim();
|
|
278
|
+
if (!contentEncoding) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
contentEncoding = contentEncoding.toLowerCase();
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
const chunkSize = outStream?.writableHighWaterMark;
|
|
285
|
+
let pipeTo;
|
|
286
|
+
if (contentEncoding.indexOf(',') === -1) {
|
|
287
|
+
pipeTo = decompressEncoding(contentEncoding, chunkSize);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
for (const value of contentEncoding.split(/\s*,\s*/).reverse()) {
|
|
291
|
+
const next = decompressEncoding(value, chunkSize);
|
|
292
|
+
if (!next) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
pipeTo = pipeTo ? pipeTo.pipe(next) : next;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (pipeTo) {
|
|
299
|
+
if (outStream) {
|
|
300
|
+
stream.pipeline(response, pipeTo, outStream, err => err && response.emit('error', err));
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
stream.pipeline(response, pipeTo, err => err && response.emit('error', err));
|
|
304
|
+
}
|
|
305
|
+
return pipeTo;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function decompressEncoding(value, chunkSize) {
|
|
309
|
+
switch (value) {
|
|
310
|
+
case 'gzip':
|
|
311
|
+
return zlib.createGunzip({ chunkSize });
|
|
312
|
+
case 'br':
|
|
313
|
+
return zlib.createBrotliDecompress({ chunkSize });
|
|
314
|
+
case 'deflate':
|
|
315
|
+
return zlib.createInflate({ chunkSize });
|
|
316
|
+
case 'deflate-raw':
|
|
317
|
+
return zlib.createInflateRaw({ chunkSize });
|
|
318
|
+
case 'zstd':
|
|
319
|
+
if (LIB_ZSTD) {
|
|
320
|
+
return new LIB_ZSTD.ZstdDecompressTransform({ writableHighWaterMark: chunkSize });
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
270
325
|
class Request extends module_1 {
|
|
271
326
|
static async purgeMemory(percent = 1, limit = 0, parent) {
|
|
272
327
|
if (percent >= 1) {
|
|
@@ -877,7 +932,12 @@ class Request extends module_1 {
|
|
|
877
932
|
const resolved = this[kConnectDns][hostname] || DNS.CACHE[hostname];
|
|
878
933
|
if (resolved) {
|
|
879
934
|
return (...args) => {
|
|
880
|
-
|
|
935
|
+
if (SUPPORT_NODEJS20) {
|
|
936
|
+
args[2](null, resolved);
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
args[2](null, resolved[0].address, resolved[0].family);
|
|
940
|
+
}
|
|
881
941
|
};
|
|
882
942
|
}
|
|
883
943
|
const pending = (_o = this[kPendingDns])[hostname] || (_o[hostname] = []);
|
|
@@ -1414,44 +1474,6 @@ class Request extends module_1 {
|
|
|
1414
1474
|
}
|
|
1415
1475
|
uri = url.href;
|
|
1416
1476
|
}
|
|
1417
|
-
const checkEncoding = (response, statusCode, contentEncoding = '') => {
|
|
1418
|
-
switch (statusCode) {
|
|
1419
|
-
case 206:
|
|
1420
|
-
request.emit('error', (0, types_1.errorValue)("Aborted", 'Partial content'));
|
|
1421
|
-
case 204:
|
|
1422
|
-
return;
|
|
1423
|
-
}
|
|
1424
|
-
const chunkSize = outStream?.writableHighWaterMark;
|
|
1425
|
-
let pipeTo;
|
|
1426
|
-
switch (contentEncoding.trim().toLowerCase()) {
|
|
1427
|
-
case 'gzip':
|
|
1428
|
-
pipeTo = zlib.createGunzip({ chunkSize });
|
|
1429
|
-
break;
|
|
1430
|
-
case 'br':
|
|
1431
|
-
pipeTo = zlib.createBrotliDecompress({ chunkSize });
|
|
1432
|
-
break;
|
|
1433
|
-
case 'deflate':
|
|
1434
|
-
pipeTo = zlib.createInflate({ chunkSize });
|
|
1435
|
-
break;
|
|
1436
|
-
case 'deflate-raw':
|
|
1437
|
-
pipeTo = zlib.createInflateRaw({ chunkSize });
|
|
1438
|
-
break;
|
|
1439
|
-
case 'zstd':
|
|
1440
|
-
if (LIB_ZSTD) {
|
|
1441
|
-
pipeTo = new LIB_ZSTD.ZstdDecompressTransform({ writableHighWaterMark: chunkSize });
|
|
1442
|
-
}
|
|
1443
|
-
break;
|
|
1444
|
-
}
|
|
1445
|
-
if (pipeTo) {
|
|
1446
|
-
if (outStream) {
|
|
1447
|
-
stream.pipeline(response, pipeTo, outStream, err => err && response.emit('error', err));
|
|
1448
|
-
}
|
|
1449
|
-
else {
|
|
1450
|
-
stream.pipeline(response, pipeTo, err => err && response.emit('error', err));
|
|
1451
|
-
}
|
|
1452
|
-
return pipeTo;
|
|
1453
|
-
}
|
|
1454
|
-
};
|
|
1455
1477
|
const { hostname, origin, secure, localhost } = host;
|
|
1456
1478
|
const pathname = url.pathname + (socketPath ? '' : url.search);
|
|
1457
1479
|
const proxy = this.proxyOf(uri, localhost);
|
|
@@ -1477,7 +1499,8 @@ class Request extends module_1 {
|
|
|
1477
1499
|
connected = true;
|
|
1478
1500
|
const statusCode = response[':status'];
|
|
1479
1501
|
if (this.matchStatus(statusCode, url, response, request, options) && statusCode >= 200 && statusCode < 300) {
|
|
1480
|
-
|
|
1502
|
+
emitter = checkEncoding(request, request, statusCode, outStream, response['content-encoding']);
|
|
1503
|
+
if (emitter) {
|
|
1481
1504
|
for (const event in listenerMap) {
|
|
1482
1505
|
listenerMap[event].forEach(listener => {
|
|
1483
1506
|
const [name, type] = event.split('-');
|
|
@@ -1598,7 +1621,7 @@ class Request extends module_1 {
|
|
|
1598
1621
|
const statusCode = response.statusCode;
|
|
1599
1622
|
const incoming = response.headers;
|
|
1600
1623
|
if (this.matchStatus(statusCode, url, incoming, request, options) && (getting || posting) && statusCode >= 200 && statusCode < 300) {
|
|
1601
|
-
let source = checkEncoding(response, statusCode, incoming['content-encoding']);
|
|
1624
|
+
let source = checkEncoding(request, response, statusCode, outStream, incoming['content-encoding']);
|
|
1602
1625
|
if (source) {
|
|
1603
1626
|
source.once('finish', () => request.emit('end'));
|
|
1604
1627
|
}
|
|
@@ -1832,11 +1855,14 @@ class Request extends module_1 {
|
|
|
1832
1855
|
opts.encoding = (0, types_1.getEncoding)(opts.encoding);
|
|
1833
1856
|
}
|
|
1834
1857
|
return new Promise((resolve, reject) => {
|
|
1835
|
-
const
|
|
1836
|
-
const
|
|
1858
|
+
const pipeTo = opts.pipeTo;
|
|
1859
|
+
const status = opts.silent === false || !opts.silent && !this[kSingleton];
|
|
1860
|
+
let log = status && LOG_HTTP && LOG_TIMEPROCESS, retries = 0, redirects = 0, closed, timeout, outStream;
|
|
1837
1861
|
const startTime = log ? process.hrtime() : 0;
|
|
1838
|
-
let retries = 0, redirects = 0, closed, timeout, outStream;
|
|
1839
1862
|
const throwError = (err, outAbort) => {
|
|
1863
|
+
if (timeout) {
|
|
1864
|
+
clearTimeout(timeout);
|
|
1865
|
+
}
|
|
1840
1866
|
if (!closed) {
|
|
1841
1867
|
closed = true;
|
|
1842
1868
|
if (outStream && (0, types_1.isString)(pipeTo)) {
|
|
@@ -1844,9 +1870,6 @@ class Request extends module_1 {
|
|
|
1844
1870
|
}
|
|
1845
1871
|
reject(typeof err === 'string' ? new Error(err) : err);
|
|
1846
1872
|
}
|
|
1847
|
-
if (timeout) {
|
|
1848
|
-
clearTimeout(timeout);
|
|
1849
|
-
}
|
|
1850
1873
|
if (outAbort) {
|
|
1851
1874
|
this[kDownloading].delete(outAbort);
|
|
1852
1875
|
}
|
|
@@ -1880,7 +1903,8 @@ class Request extends module_1 {
|
|
|
1880
1903
|
const isUnsupported = (value) => value === 421 || value === 505;
|
|
1881
1904
|
const isDowngrade = (err) => err instanceof Error && (err.code === 'ERR_HTTP2_ERROR' || isUnsupported(Math.abs(err.errno)));
|
|
1882
1905
|
const wasAborted = (err) => err instanceof Error && err.message.startsWith("Aborted");
|
|
1883
|
-
const
|
|
1906
|
+
const sendWarning = (message) => status && LOG_HTTP && this.formatMessage(1024, 'HTTP' + httpVersion, [message, host.origin], url.toString(), { ...module_1.LOG_STYLE_WARN });
|
|
1907
|
+
const formatRetry = (message) => message + ` (${retries} / ${this._config.retryLimit})`;
|
|
1884
1908
|
const formatNgFlags = (value, statusCode, location) => location ? `Using HTTP 1.1 for URL redirect (${location})` : formatStatus(statusCode, value ? 'NGHTTP2 Error ' + value : '');
|
|
1885
1909
|
const abortResponse = () => {
|
|
1886
1910
|
if (closed) {
|
|
@@ -1900,7 +1924,7 @@ class Request extends module_1 {
|
|
|
1900
1924
|
client.destroy();
|
|
1901
1925
|
};
|
|
1902
1926
|
const retryTimeout = () => {
|
|
1903
|
-
|
|
1927
|
+
sendWarning(formatRetry('Connection timeout'));
|
|
1904
1928
|
downloadUri.call(this, href);
|
|
1905
1929
|
};
|
|
1906
1930
|
const acceptResponse = (headers) => {
|
|
@@ -1910,9 +1934,8 @@ class Request extends module_1 {
|
|
|
1910
1934
|
if ('outFilename' in opts) {
|
|
1911
1935
|
opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
|
|
1912
1936
|
}
|
|
1913
|
-
const buffering = request.connected?.call(client, headers);
|
|
1914
1937
|
const pipeline = pipeTo ? !(0, types_1.isString)(pipeTo) : false;
|
|
1915
|
-
const enabled =
|
|
1938
|
+
const enabled = request.connected?.call(client, headers) !== false && !pipeline;
|
|
1916
1939
|
const maxBufferSize = request.maxBufferSize ? (0, types_1.alignSize)(request.maxBufferSize) : 0;
|
|
1917
1940
|
const { host: parent, readTimeout } = this;
|
|
1918
1941
|
const contentLength = parent && progressId !== undefined ? parseInt(headers['content-length'] || '0') : 0;
|
|
@@ -1926,13 +1949,18 @@ class Request extends module_1 {
|
|
|
1926
1949
|
}, readTimeout);
|
|
1927
1950
|
}
|
|
1928
1951
|
if (log) {
|
|
1929
|
-
switch (this.settings
|
|
1952
|
+
switch (this.settings.time_format || LOG_TIMEFORMAT) {
|
|
1930
1953
|
case 'readable':
|
|
1931
1954
|
delayTime = process.hrtime(startTime);
|
|
1932
1955
|
break;
|
|
1933
1956
|
case 'relative':
|
|
1934
1957
|
delayTime = Date.now() - this.startTime;
|
|
1935
1958
|
break;
|
|
1959
|
+
case 'none':
|
|
1960
|
+
if (opts.silent !== false) {
|
|
1961
|
+
log = false;
|
|
1962
|
+
}
|
|
1963
|
+
break;
|
|
1936
1964
|
}
|
|
1937
1965
|
}
|
|
1938
1966
|
mibsTime = process.hrtime();
|
|
@@ -1983,8 +2011,7 @@ class Request extends module_1 {
|
|
|
1983
2011
|
this[kDownloading].delete(outAbort);
|
|
1984
2012
|
}
|
|
1985
2013
|
closed = true;
|
|
1986
|
-
let messageUnit, titleBgColor;
|
|
1987
|
-
let result;
|
|
2014
|
+
let result, messageUnit, titleBgColor;
|
|
1988
2015
|
if (buffer) {
|
|
1989
2016
|
if (Array.isArray(buffer)) {
|
|
1990
2017
|
buffer = Buffer.concat(buffer);
|
|
@@ -2029,7 +2056,7 @@ class Request extends module_1 {
|
|
|
2029
2056
|
}
|
|
2030
2057
|
}
|
|
2031
2058
|
catch (err) {
|
|
2032
|
-
if (
|
|
2059
|
+
if (status && !(packageName && this.checkPackage(err, packageName))) {
|
|
2033
2060
|
this.writeFail(['Unable to parse URI response', format], err, 1024);
|
|
2034
2061
|
}
|
|
2035
2062
|
result = null;
|
|
@@ -2051,10 +2078,10 @@ class Request extends module_1 {
|
|
|
2051
2078
|
result = encoding && !pipeline ? '' : null;
|
|
2052
2079
|
titleBgColor = 'bgBlue';
|
|
2053
2080
|
}
|
|
2054
|
-
resolve(result);
|
|
2055
2081
|
if (log) {
|
|
2056
2082
|
this.writeTimeProcess('HTTP' + httpVersion, request.statusMessage || url.toString(), startTime, { type: 1024, queue: !!this.host, titleBgColor, messageUnit, messageUnitMinWidth: 9, delayTime, bypassLog: LOG_STDOUT });
|
|
2057
2083
|
}
|
|
2084
|
+
resolve(result);
|
|
2058
2085
|
});
|
|
2059
2086
|
host.success(httpVersion);
|
|
2060
2087
|
};
|
|
@@ -2105,7 +2132,7 @@ class Request extends module_1 {
|
|
|
2105
2132
|
}
|
|
2106
2133
|
if (offset > 0) {
|
|
2107
2134
|
if (offset <= this._config.retryAfter) {
|
|
2108
|
-
|
|
2135
|
+
sendWarning(`Retry After (${retryAfter})`);
|
|
2109
2136
|
setTimeout(() => downloadUri.call(this, href), offset);
|
|
2110
2137
|
}
|
|
2111
2138
|
else {
|
|
@@ -2114,7 +2141,7 @@ class Request extends module_1 {
|
|
|
2114
2141
|
return;
|
|
2115
2142
|
}
|
|
2116
2143
|
}
|
|
2117
|
-
|
|
2144
|
+
sendWarning(formatRetry(Request.fromStatusCode(statusCode)));
|
|
2118
2145
|
if ((0, util_1.isRetryable)(statusCode, true)) {
|
|
2119
2146
|
process.nextTick(downloadUri.bind(this), href);
|
|
2120
2147
|
}
|
|
@@ -2131,7 +2158,7 @@ class Request extends module_1 {
|
|
|
2131
2158
|
if (downgrade) {
|
|
2132
2159
|
host.failed(2);
|
|
2133
2160
|
if (host.version > 1) {
|
|
2134
|
-
if (
|
|
2161
|
+
if (status && LOG_HTTP) {
|
|
2135
2162
|
this.formatMessage(1024, 'HTTP2', ['Unsupported protocol', host.origin], message, { failed: true });
|
|
2136
2163
|
}
|
|
2137
2164
|
host.version = 1;
|
|
@@ -2193,18 +2220,19 @@ class Request extends module_1 {
|
|
|
2193
2220
|
}
|
|
2194
2221
|
if (wasAborted(err)) {
|
|
2195
2222
|
errorResponse(err);
|
|
2196
|
-
return;
|
|
2197
2223
|
}
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2224
|
+
else {
|
|
2225
|
+
switch (!isDowngrade(err) && await host.hasProtocol(2)) {
|
|
2226
|
+
case 1:
|
|
2227
|
+
errorResponse(err);
|
|
2228
|
+
break;
|
|
2229
|
+
case 2:
|
|
2230
|
+
retryDownload(false, err);
|
|
2231
|
+
break;
|
|
2232
|
+
default:
|
|
2233
|
+
retryDownload(true, err);
|
|
2234
|
+
break;
|
|
2235
|
+
}
|
|
2208
2236
|
}
|
|
2209
2237
|
});
|
|
2210
2238
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/request",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Request constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -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.9.
|
|
24
|
-
"@e-mc/types": "0.9.
|
|
23
|
+
"@e-mc/module": "0.9.3",
|
|
24
|
+
"@e-mc/types": "0.9.3",
|
|
25
25
|
"combined-stream": "^1.0.8",
|
|
26
26
|
"js-yaml": "^4.1.0",
|
|
27
27
|
"picomatch": "^4.0.2",
|