@e-mc/request 0.8.27 → 0.8.28
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/index.js +33 -12
- package/package.json +3 -3
- package/http/adapter/index.js +0 -569
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Interface
|
|
11
11
|
|
|
12
|
-
- https://www.unpkg.com/@e-mc/types@0.8.
|
|
12
|
+
- https://www.unpkg.com/@e-mc/types@0.8.28/lib/index.d.ts
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
15
|
import type { IModule, ModuleConstructor } from "./index";
|
|
@@ -82,9 +82,9 @@ interface RequestConstructor extends ModuleConstructor {
|
|
|
82
82
|
|
|
83
83
|
## References
|
|
84
84
|
|
|
85
|
-
- https://www.unpkg.com/@e-mc/types@0.8.
|
|
86
|
-
- https://www.unpkg.com/@e-mc/types@0.8.
|
|
87
|
-
- https://www.unpkg.com/@e-mc/types@0.8.
|
|
85
|
+
- https://www.unpkg.com/@e-mc/types@0.8.28/lib/http.d.ts
|
|
86
|
+
- https://www.unpkg.com/@e-mc/types@0.8.28/lib/request.d.ts
|
|
87
|
+
- https://www.unpkg.com/@e-mc/types@0.8.28/lib/settings.d.ts
|
|
88
88
|
|
|
89
89
|
## LICENSE
|
|
90
90
|
|
package/index.js
CHANGED
|
@@ -266,6 +266,8 @@ function checkEncoding(request, response, statusCode, outStream, contentEncoding
|
|
|
266
266
|
case 206:
|
|
267
267
|
request.emit('error', (0, types_1.errorValue)("Aborted", 'Partial content'));
|
|
268
268
|
case 204:
|
|
269
|
+
case 205:
|
|
270
|
+
case 304:
|
|
269
271
|
return;
|
|
270
272
|
default:
|
|
271
273
|
contentEncoding = contentEncoding.trim();
|
|
@@ -666,7 +668,7 @@ class Request extends module_1.default {
|
|
|
666
668
|
break;
|
|
667
669
|
}
|
|
668
670
|
if (expires !== undefined) {
|
|
669
|
-
if (
|
|
671
|
+
if ((0, types_1.isString)(expires)) {
|
|
670
672
|
expires = (0, types_1.parseExpires)(expires);
|
|
671
673
|
}
|
|
672
674
|
if (expires >= 0) {
|
|
@@ -897,8 +899,12 @@ class Request extends module_1.default {
|
|
|
897
899
|
}
|
|
898
900
|
break;
|
|
899
901
|
case 'readExpect':
|
|
900
|
-
|
|
901
|
-
|
|
902
|
+
switch (value) {
|
|
903
|
+
case 'string':
|
|
904
|
+
case 'always':
|
|
905
|
+
case 'none':
|
|
906
|
+
this[name] = value;
|
|
907
|
+
break;
|
|
902
908
|
}
|
|
903
909
|
break;
|
|
904
910
|
}
|
|
@@ -1942,7 +1948,7 @@ class Request extends module_1.default {
|
|
|
1942
1948
|
formatWarning(`Connection timeout (${retries} / ${this._config.retryLimit})`);
|
|
1943
1949
|
downloadUri.call(this, href);
|
|
1944
1950
|
};
|
|
1945
|
-
const acceptResponse = (headers) => {
|
|
1951
|
+
const acceptResponse = (headers, empty) => {
|
|
1946
1952
|
var _o;
|
|
1947
1953
|
if ('outHeaders' in opts) {
|
|
1948
1954
|
opts.outHeaders = headers;
|
|
@@ -1976,7 +1982,7 @@ class Request extends module_1.default {
|
|
|
1976
1982
|
}
|
|
1977
1983
|
});
|
|
1978
1984
|
}
|
|
1979
|
-
if (enabled) {
|
|
1985
|
+
if (enabled && !empty) {
|
|
1980
1986
|
client.on('data', (chunk) => {
|
|
1981
1987
|
if (buffer) {
|
|
1982
1988
|
if (typeof buffer === 'string') {
|
|
@@ -2166,13 +2172,21 @@ class Request extends module_1.default {
|
|
|
2166
2172
|
return;
|
|
2167
2173
|
}
|
|
2168
2174
|
const statusCode = headers[':status'];
|
|
2169
|
-
if (statusCode
|
|
2170
|
-
acceptResponse(headers);
|
|
2175
|
+
if (statusCode === 204 || statusCode === 304) {
|
|
2176
|
+
acceptResponse(headers, true);
|
|
2171
2177
|
}
|
|
2172
|
-
else if (statusCode <
|
|
2178
|
+
else if (statusCode < 300) {
|
|
2179
|
+
acceptResponse(headers, false);
|
|
2180
|
+
}
|
|
2181
|
+
else if (statusCode === 301 ||
|
|
2182
|
+
statusCode === 302 ||
|
|
2183
|
+
statusCode === 303 ||
|
|
2184
|
+
statusCode === 307 ||
|
|
2185
|
+
statusCode === 308) {
|
|
2173
2186
|
redirectResponse(statusCode, headers.location);
|
|
2174
2187
|
}
|
|
2175
|
-
else if (statusCode ===
|
|
2188
|
+
else if (statusCode === 305 ||
|
|
2189
|
+
statusCode === 401 ||
|
|
2176
2190
|
statusCode === 402 ||
|
|
2177
2191
|
statusCode === 403 ||
|
|
2178
2192
|
statusCode === 404 ||
|
|
@@ -2236,10 +2250,17 @@ class Request extends module_1.default {
|
|
|
2236
2250
|
return;
|
|
2237
2251
|
}
|
|
2238
2252
|
const statusCode = res.statusCode;
|
|
2239
|
-
if (statusCode
|
|
2240
|
-
acceptResponse(res.headers);
|
|
2253
|
+
if (statusCode === 204 || statusCode === 304) {
|
|
2254
|
+
acceptResponse(res.headers, true);
|
|
2255
|
+
}
|
|
2256
|
+
else if (statusCode < 300) {
|
|
2257
|
+
acceptResponse(res.headers, false);
|
|
2241
2258
|
}
|
|
2242
|
-
else if (statusCode
|
|
2259
|
+
else if (statusCode === 301 ||
|
|
2260
|
+
statusCode === 302 ||
|
|
2261
|
+
statusCode === 303 ||
|
|
2262
|
+
statusCode === 307 ||
|
|
2263
|
+
statusCode === 308) {
|
|
2243
2264
|
redirectResponse(statusCode, res.headers.location);
|
|
2244
2265
|
}
|
|
2245
2266
|
else if (isRetry(statusCode)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/request",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.28",
|
|
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": "MIT",
|
|
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.28",
|
|
24
|
+
"@e-mc/types": "0.8.28",
|
|
25
25
|
"combined-stream": "^1.0.8",
|
|
26
26
|
"js-yaml": "^4.1.0",
|
|
27
27
|
"picomatch": "^3.0.1",
|
package/http/adapter/index.js
DELETED
|
@@ -1,569 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const http2 = require("node:http2");
|
|
4
|
-
const yaml = require("js-yaml");
|
|
5
|
-
const types_1 = require("@e-mc/types");
|
|
6
|
-
const module_1 = require("@e-mc/module");
|
|
7
|
-
const util_1 = require("@e-mc/request/util");
|
|
8
|
-
let LOG_TIMEFORMAT = 'readable';
|
|
9
|
-
class HttpAdapter {
|
|
10
|
-
instance;
|
|
11
|
-
state;
|
|
12
|
-
uri;
|
|
13
|
-
static isUnsupported(value) {
|
|
14
|
-
return value === 421 || value === 505;
|
|
15
|
-
}
|
|
16
|
-
static isDowngrade(err) {
|
|
17
|
-
return err instanceof Error && (err.code === 'ERR_HTTP2_ERROR' || this.isUnsupported(Math.abs(err.errno)));
|
|
18
|
-
}
|
|
19
|
-
static wasAborted(err) {
|
|
20
|
-
return err instanceof Error && err.message.startsWith("Aborted");
|
|
21
|
-
}
|
|
22
|
-
static isConnectionError(err) {
|
|
23
|
-
switch (err instanceof Error && err.code) {
|
|
24
|
-
case 'ETIMEDOUT':
|
|
25
|
-
case 'ECONNRESET':
|
|
26
|
-
return true;
|
|
27
|
-
default:
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
static defineHostConfig({ settings }) {
|
|
32
|
-
const time_format = settings?.time_format;
|
|
33
|
-
switch (time_format) {
|
|
34
|
-
case 'readable':
|
|
35
|
-
case 'relative':
|
|
36
|
-
case 'none':
|
|
37
|
-
LOG_TIMEFORMAT = time_format;
|
|
38
|
-
break;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
contentLength = 0;
|
|
42
|
-
retries = 0;
|
|
43
|
-
redirects = 0;
|
|
44
|
-
closed = false;
|
|
45
|
-
aborted = false;
|
|
46
|
-
timeout = null;
|
|
47
|
-
dataTime = null;
|
|
48
|
-
delayTime = undefined;
|
|
49
|
-
opts;
|
|
50
|
-
client;
|
|
51
|
-
resolve;
|
|
52
|
-
reject;
|
|
53
|
-
startTime;
|
|
54
|
-
#outStream = null;
|
|
55
|
-
#options;
|
|
56
|
-
constructor(instance, state, uri, options) {
|
|
57
|
-
this.instance = instance;
|
|
58
|
-
this.state = state;
|
|
59
|
-
this.uri = uri;
|
|
60
|
-
this.#options = options;
|
|
61
|
-
this.startTime = state.log ? process.hrtime.bigint() : BigInt(0);
|
|
62
|
-
this.setOpts();
|
|
63
|
-
}
|
|
64
|
-
async start() {
|
|
65
|
-
return new Promise((resolve, reject) => {
|
|
66
|
-
this.resolve = resolve;
|
|
67
|
-
this.reject = reject;
|
|
68
|
-
this.init();
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
init() {
|
|
72
|
-
this.aborted = false;
|
|
73
|
-
this.setWriteStream();
|
|
74
|
-
this.client = this.instance.open(this.uri, this.opts);
|
|
75
|
-
if (this.opts.httpVersion === 2) {
|
|
76
|
-
this.client
|
|
77
|
-
.on('response', (headers, flags) => {
|
|
78
|
-
if (this.destroyed) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const statusCode = headers[':status'];
|
|
82
|
-
if (statusCode < 300) {
|
|
83
|
-
this.acceptResponse(headers);
|
|
84
|
-
}
|
|
85
|
-
else if (statusCode < 400) {
|
|
86
|
-
this.redirectResponse(statusCode, headers.location);
|
|
87
|
-
}
|
|
88
|
-
else if (statusCode === 401 ||
|
|
89
|
-
statusCode === 402 ||
|
|
90
|
-
statusCode === 403 ||
|
|
91
|
-
statusCode === 404 ||
|
|
92
|
-
statusCode === 407 ||
|
|
93
|
-
statusCode === 410) {
|
|
94
|
-
this.terminate(this.formatStatus(statusCode));
|
|
95
|
-
}
|
|
96
|
-
else if (this.isRetry(statusCode)) {
|
|
97
|
-
this.retryResponse(statusCode, headers['retry-after']);
|
|
98
|
-
}
|
|
99
|
-
else if (HttpAdapter.isUnsupported(statusCode)) {
|
|
100
|
-
this.retryDownload(true, this.#formatNgFlags(http2.constants.NGHTTP2_PROTOCOL_ERROR, statusCode));
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
switch (flags) {
|
|
104
|
-
case http2.constants.NGHTTP2_PROTOCOL_ERROR:
|
|
105
|
-
case http2.constants.NGHTTP2_INADEQUATE_SECURITY:
|
|
106
|
-
case http2.constants.NGHTTP2_HTTP_1_1_REQUIRED:
|
|
107
|
-
this.retryDownload(true, this.#formatNgFlags(flags, statusCode, headers.location));
|
|
108
|
-
break;
|
|
109
|
-
default:
|
|
110
|
-
this.retryDownload(false, this.formatStatus(statusCode));
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
.on('unknownProtocol', () => {
|
|
116
|
-
if (this.aborted) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
this.retryDownload(true, 'Unknown protocol (HTTP/2)');
|
|
120
|
-
})
|
|
121
|
-
.on('aborted', () => {
|
|
122
|
-
this.aborted = true;
|
|
123
|
-
this.terminate((0, types_1.createAbortError)());
|
|
124
|
-
})
|
|
125
|
-
.on('error', async (err) => {
|
|
126
|
-
if (this.aborted) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if (HttpAdapter.wasAborted(err)) {
|
|
130
|
-
this.errorResponse(err);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
switch (!HttpAdapter.isDowngrade(err) && await this.host.hasProtocol(2)) {
|
|
134
|
-
case 1:
|
|
135
|
-
this.errorResponse(err);
|
|
136
|
-
break;
|
|
137
|
-
case 2:
|
|
138
|
-
this.retryDownload(false, err);
|
|
139
|
-
break;
|
|
140
|
-
default:
|
|
141
|
-
this.retryDownload(true, err);
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
this.client
|
|
149
|
-
.on('response', res => {
|
|
150
|
-
if (this.destroyed) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const statusCode = res.statusCode;
|
|
154
|
-
if (statusCode < 300) {
|
|
155
|
-
this.acceptResponse(res.headers);
|
|
156
|
-
}
|
|
157
|
-
else if (statusCode < 400) {
|
|
158
|
-
this.redirectResponse(statusCode, res.headers.location);
|
|
159
|
-
}
|
|
160
|
-
else if (this.isRetry(statusCode)) {
|
|
161
|
-
this.retryResponse(statusCode, res.headers['retry-after']);
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
this.terminate(this.formatStatus(statusCode));
|
|
165
|
-
}
|
|
166
|
-
})
|
|
167
|
-
.on('abort', () => {
|
|
168
|
-
this.aborted = true;
|
|
169
|
-
this.terminate((0, types_1.createAbortError)());
|
|
170
|
-
})
|
|
171
|
-
.on('error', err => {
|
|
172
|
-
if (this.aborted) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
this.errorResponse(err);
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
this.client.on('timeout', () => {
|
|
179
|
-
if (this.aborted) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (++this.retries <= this.retryLimit) {
|
|
183
|
-
this.abortResponse();
|
|
184
|
-
this.retryTimeout();
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
this.terminate(this.formatStatus(408));
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
setOpts(uri) {
|
|
192
|
-
if (uri) {
|
|
193
|
-
this.uri = uri;
|
|
194
|
-
}
|
|
195
|
-
this.opts = this.instance.opts(this.uri, this.#options);
|
|
196
|
-
}
|
|
197
|
-
setWriteStream() {
|
|
198
|
-
const pipeTo = this.pipeTo;
|
|
199
|
-
if (typeof pipeTo === 'string') {
|
|
200
|
-
try {
|
|
201
|
-
this.outStream = fs.createWriteStream(pipeTo, { emitClose: false, highWaterMark: this.host.streamSize });
|
|
202
|
-
}
|
|
203
|
-
catch (err) {
|
|
204
|
-
this.terminate(err);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
else if (pipeTo) {
|
|
208
|
-
this.outStream = pipeTo;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
retryDownload(downgrade, message) {
|
|
212
|
-
if (this.aborted) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
this.abortResponse();
|
|
216
|
-
if (downgrade) {
|
|
217
|
-
const host = this.host;
|
|
218
|
-
host.failed(2);
|
|
219
|
-
if (host.version > 1) {
|
|
220
|
-
if (this.state.verbose) {
|
|
221
|
-
this.instance.formatMessage(1024, 'HTTP2', ["Unsupported protocol", host.origin], message, { failed: true });
|
|
222
|
-
}
|
|
223
|
-
host.version = 1;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
this.opts.httpVersion = 1;
|
|
227
|
-
this.init();
|
|
228
|
-
}
|
|
229
|
-
acceptResponse(headers) {
|
|
230
|
-
const opts = this.opts;
|
|
231
|
-
if ('outHeaders' in opts) {
|
|
232
|
-
opts.outHeaders = headers;
|
|
233
|
-
}
|
|
234
|
-
if ('outFilename' in opts) {
|
|
235
|
-
opts.outFilename = (0, util_1.parseHeader)(headers, 'content-disposition');
|
|
236
|
-
}
|
|
237
|
-
const pipeline = this.pipeTo ? !(0, types_1.isString)(this.pipeTo) : false;
|
|
238
|
-
const enabled = opts.connected?.call(this.client, headers) !== false && !pipeline;
|
|
239
|
-
const maxBufferSize = opts.maxBufferSize ? (0, types_1.alignSize)(opts.maxBufferSize) : 0;
|
|
240
|
-
this.contentLength = parseInt(headers['content-length'] || '0');
|
|
241
|
-
const updating = opts.progressId !== undefined && !!this.instance.host && this.contentLength > 0;
|
|
242
|
-
const readTimeout = this.instance.readTimeout;
|
|
243
|
-
let log = this.state.log, buffer = null, dataLength = 0;
|
|
244
|
-
this.client.once('readable', () => {
|
|
245
|
-
if (readTimeout > 0) {
|
|
246
|
-
this.timeout = setTimeout(() => {
|
|
247
|
-
this.terminate((0, types_1.errorValue)("Timeout was exceeded", this.uri.toString()));
|
|
248
|
-
}, readTimeout);
|
|
249
|
-
}
|
|
250
|
-
if (log) {
|
|
251
|
-
switch (this.instance.settings?.time_format || LOG_TIMEFORMAT) {
|
|
252
|
-
case 'readable':
|
|
253
|
-
this.delayTime = process.hrtime.bigint() - this.startTime;
|
|
254
|
-
break;
|
|
255
|
-
case 'relative':
|
|
256
|
-
this.delayTime = Date.now() - this.instance.startTime;
|
|
257
|
-
break;
|
|
258
|
-
case 'none':
|
|
259
|
-
if (!this.silent) {
|
|
260
|
-
log = false;
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
this.dataTime = process.hrtime.bigint();
|
|
266
|
-
if (updating) {
|
|
267
|
-
this.updateProgress(0, 0);
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
if (enabled) {
|
|
271
|
-
const encoding = opts.encoding;
|
|
272
|
-
this.client.on('data', (chunk) => {
|
|
273
|
-
if (buffer) {
|
|
274
|
-
if (typeof buffer === 'string') {
|
|
275
|
-
buffer += typeof chunk === 'string' ? chunk : chunk.toString(encoding);
|
|
276
|
-
}
|
|
277
|
-
else if (Array.isArray(buffer)) {
|
|
278
|
-
buffer.push(typeof chunk === 'string' ? Buffer.from(chunk, encoding) : chunk);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
buffer = Buffer.concat([buffer, typeof chunk === 'string' ? Buffer.from(chunk, encoding) : chunk]);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
buffer = typeof chunk === 'string' ? chunk : [chunk];
|
|
286
|
-
}
|
|
287
|
-
if (updating) {
|
|
288
|
-
dataLength += Buffer.byteLength(chunk, encoding);
|
|
289
|
-
this.updateProgress(dataLength, this.contentLength);
|
|
290
|
-
}
|
|
291
|
-
if (maxBufferSize > 0) {
|
|
292
|
-
if (!updating) {
|
|
293
|
-
dataLength += Buffer.byteLength(chunk, encoding);
|
|
294
|
-
}
|
|
295
|
-
if (dataLength > maxBufferSize) {
|
|
296
|
-
this.terminate((0, types_1.errorValue)("Size limit was exceeded", this.uri.toString()));
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
if (opts.trailers) {
|
|
302
|
-
this.client.once('trailers', (trailers) => {
|
|
303
|
-
opts.trailers.call(this.client, trailers);
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
this.client.once('end', () => {
|
|
307
|
-
if (this.closed || this.aborted) {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
this.close();
|
|
311
|
-
const encoding = opts.encoding;
|
|
312
|
-
let result;
|
|
313
|
-
if (buffer) {
|
|
314
|
-
if (Array.isArray(buffer)) {
|
|
315
|
-
buffer = Buffer.concat(buffer);
|
|
316
|
-
if (encoding) {
|
|
317
|
-
buffer = buffer.toString(encoding);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
dataLength = Buffer.byteLength(buffer, encoding);
|
|
321
|
-
if (updating) {
|
|
322
|
-
this.updateProgress(dataLength, dataLength);
|
|
323
|
-
}
|
|
324
|
-
if (typeof buffer === 'string') {
|
|
325
|
-
if (buffer.startsWith('\uFEFF') && encoding !== 'utf16le' && encoding !== 'utf-16le') {
|
|
326
|
-
buffer = buffer.substring(1);
|
|
327
|
-
}
|
|
328
|
-
if (opts.outFormat) {
|
|
329
|
-
const { out: format, parser } = opts.outFormat;
|
|
330
|
-
let packageName;
|
|
331
|
-
try {
|
|
332
|
-
switch (format) {
|
|
333
|
-
case 'yaml':
|
|
334
|
-
result = yaml.load(buffer, parser);
|
|
335
|
-
break;
|
|
336
|
-
case 'json5':
|
|
337
|
-
result = require(packageName = 'json5').parse(buffer);
|
|
338
|
-
break;
|
|
339
|
-
case 'xml':
|
|
340
|
-
result = new (require(packageName = 'fast-xml-parser').XMLParser)(parser).parse(buffer);
|
|
341
|
-
break;
|
|
342
|
-
case 'toml':
|
|
343
|
-
result = require(packageName = 'toml').parse(buffer);
|
|
344
|
-
break;
|
|
345
|
-
default:
|
|
346
|
-
result = JSON.parse(buffer);
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
if (!(0, types_1.isObject)(result)) {
|
|
350
|
-
result = null;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
catch (err) {
|
|
354
|
-
if (this.state.verbose && !(packageName && this.instance.checkPackage(err, packageName))) {
|
|
355
|
-
this.instance.writeFail(["Unable to parse URI response", format], err, 1024);
|
|
356
|
-
}
|
|
357
|
-
result = null;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (result === undefined) {
|
|
362
|
-
result = buffer;
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
if (updating) {
|
|
367
|
-
this.updateProgress(0, this.contentLength);
|
|
368
|
-
}
|
|
369
|
-
if (enabled && this.instance.readExpect === 'always') {
|
|
370
|
-
this.terminate("No data received");
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
dataLength = this.contentLength || (typeof this.pipeTo === 'string' ? (0, util_1.getSize)(this.pipeTo) : 0);
|
|
374
|
-
result = encoding && !pipeline ? '' : null;
|
|
375
|
-
}
|
|
376
|
-
this.endResponse(result, dataLength, log);
|
|
377
|
-
});
|
|
378
|
-
this.host.success(this.httpVersion);
|
|
379
|
-
}
|
|
380
|
-
updateProgress(dataLength, contentLength) {
|
|
381
|
-
const { host, moduleName } = this.instance;
|
|
382
|
-
host.updateProgress(moduleName, this.opts.progressId, dataLength, contentLength, this.dataTime);
|
|
383
|
-
}
|
|
384
|
-
endResponse(result, dataLength = 0, logging = this.state.log) {
|
|
385
|
-
if (logging) {
|
|
386
|
-
this.instance.writeTimeProcess('HTTP' + this.httpVersion, this.opts.statusMessage || this.uri.toString(), this.startTime, {
|
|
387
|
-
type: 1024,
|
|
388
|
-
queue: !!this.instance.host,
|
|
389
|
-
titleBgColor: !result ? 'bgBlue' : undefined,
|
|
390
|
-
messageUnit: this.formatMibs(dataLength),
|
|
391
|
-
messageUnitMinWidth: 9,
|
|
392
|
-
delayTime: this.delayTime,
|
|
393
|
-
bypassLog: module_1.hasLogType(32768)
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
this.resolve(result);
|
|
397
|
-
}
|
|
398
|
-
redirectResponse(statusCode, location) {
|
|
399
|
-
if (location) {
|
|
400
|
-
if (this.opts.followRedirect === false) {
|
|
401
|
-
this.terminate(this.formatStatus(statusCode, "Follow redirect was disabled"));
|
|
402
|
-
}
|
|
403
|
-
else if (++this.redirects <= this.redirectLimit) {
|
|
404
|
-
this.abortResponse();
|
|
405
|
-
this.setOpts((0, util_1.fromURL)(this.opts.url, location));
|
|
406
|
-
this.init();
|
|
407
|
-
}
|
|
408
|
-
else {
|
|
409
|
-
this.terminate(this.formatStatus(statusCode, "Exceeded redirect limit"));
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
this.terminate(this.formatStatus(statusCode, "Missing redirect location"));
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
abortResponse() {
|
|
417
|
-
if (this.closed) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
this.aborted = true;
|
|
421
|
-
this.client.destroy();
|
|
422
|
-
this.instance.reset(this);
|
|
423
|
-
this.cleanup();
|
|
424
|
-
}
|
|
425
|
-
errorResponse(err) {
|
|
426
|
-
if (HttpAdapter.wasAborted(err)) {
|
|
427
|
-
this.terminate(err);
|
|
428
|
-
}
|
|
429
|
-
else if ((0, util_1.checkRetryable)(err) && ++this.retries <= this.retryLimit) {
|
|
430
|
-
this.abortResponse();
|
|
431
|
-
if (HttpAdapter.isConnectionError(err)) {
|
|
432
|
-
this.retryTimeout();
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
setTimeout(() => {
|
|
436
|
-
this.init();
|
|
437
|
-
}, this.retryWait);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
this.host.error(this.httpVersion);
|
|
442
|
-
this.terminate(err);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
retryResponse(statusCode, retryAfter) {
|
|
446
|
-
this.abortResponse();
|
|
447
|
-
if (retryAfter && this.retryAfter > 0) {
|
|
448
|
-
let offset = +retryAfter || new Date(retryAfter);
|
|
449
|
-
if (offset instanceof Date) {
|
|
450
|
-
offset = Math.max(0, offset.getTime() - Date.now());
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
offset *= 1000;
|
|
454
|
-
}
|
|
455
|
-
if (offset > 0) {
|
|
456
|
-
if (offset <= this.retryAfter) {
|
|
457
|
-
this.sendWarning(`Retry After (${retryAfter})`);
|
|
458
|
-
setTimeout(() => {
|
|
459
|
-
this.init();
|
|
460
|
-
}, offset);
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
this.terminate(this.formatStatus(statusCode));
|
|
464
|
-
}
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
this.sendWarning(this.#formatRetry((0, util_1.fromStatusCode)(statusCode)));
|
|
469
|
-
if ((0, util_1.isRetryable)(statusCode, true)) {
|
|
470
|
-
setImmediate(this.init.bind(this));
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
setTimeout(() => {
|
|
474
|
-
this.init();
|
|
475
|
-
}, this.retryWait);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
isRetry(value) {
|
|
479
|
-
return (0, util_1.isRetryable)(value) && ++this.retries <= this.retryLimit;
|
|
480
|
-
}
|
|
481
|
-
retryTimeout() {
|
|
482
|
-
this.sendWarning(this.#formatRetry("HTTP connection timeout"));
|
|
483
|
-
this.init();
|
|
484
|
-
}
|
|
485
|
-
terminate(err) {
|
|
486
|
-
if (this.closed) {
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
this.cleanup();
|
|
490
|
-
this.close();
|
|
491
|
-
this.reject(typeof err === 'string' ? new Error(err) : err);
|
|
492
|
-
}
|
|
493
|
-
sendWarning(message) {
|
|
494
|
-
if (this.state.verbose) {
|
|
495
|
-
const { host, url } = this.opts;
|
|
496
|
-
this.instance.formatMessage(1024, 'HTTP' + this.httpVersion, [message, host.origin], url.toString(), { ...module_1.LOG_STYLE_WARN });
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
formatStatus(value, hint) {
|
|
500
|
-
return value + ': ' + (hint || (0, util_1.fromStatusCode)(value)) + ` (${this.uri.toString()})`;
|
|
501
|
-
}
|
|
502
|
-
formatMibs(dataLength) {
|
|
503
|
-
if (dataLength > 0 && this.dataTime) {
|
|
504
|
-
return (0, util_1.getTransferRate)(dataLength, Math.max(1, (0, types_1.convertTime)(process.hrtime.bigint() - this.dataTime, false) * 1000));
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
close() {
|
|
508
|
-
this.closed = true;
|
|
509
|
-
this.instance.reset(this);
|
|
510
|
-
if (this.aborted && !this.client.aborted) {
|
|
511
|
-
this.abortController?.abort();
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
cleanup() {
|
|
515
|
-
if ((0, types_1.isString)(this.pipeTo) && this.outStream) {
|
|
516
|
-
(0, util_1.cleanupStream)(this.outStream, this.pipeTo);
|
|
517
|
-
this.outStream = null;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
#formatNgFlags(value, statusCode, location) {
|
|
521
|
-
return location ? `Using HTTP 1.1 for URL redirect (${location})` : this.formatStatus(statusCode, value ? 'NGHTTP2 Error ' + value : '');
|
|
522
|
-
}
|
|
523
|
-
#formatRetry(message) {
|
|
524
|
-
return `${message} (${this.retries} / ${this.retryLimit})`;
|
|
525
|
-
}
|
|
526
|
-
set abortController(value) {
|
|
527
|
-
this.opts.outAbort = value;
|
|
528
|
-
}
|
|
529
|
-
get abortController() {
|
|
530
|
-
return this.opts.outAbort || null;
|
|
531
|
-
}
|
|
532
|
-
set outStream(value) {
|
|
533
|
-
this.#outStream = value;
|
|
534
|
-
if (value) {
|
|
535
|
-
this.opts.outStream = value;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
get outStream() {
|
|
539
|
-
return this.#outStream;
|
|
540
|
-
}
|
|
541
|
-
get destroyed() {
|
|
542
|
-
return this.client.destroyed || this.httpVersion === 2 && this.client.aborted;
|
|
543
|
-
}
|
|
544
|
-
get host() {
|
|
545
|
-
return this.opts.host;
|
|
546
|
-
}
|
|
547
|
-
get httpVersion() {
|
|
548
|
-
return this.opts.httpVersion;
|
|
549
|
-
}
|
|
550
|
-
get pipeTo() {
|
|
551
|
-
return this.opts.pipeTo;
|
|
552
|
-
}
|
|
553
|
-
get silent() {
|
|
554
|
-
return this.opts.silent === false;
|
|
555
|
-
}
|
|
556
|
-
get retryLimit() {
|
|
557
|
-
return this.state.config.retryLimit;
|
|
558
|
-
}
|
|
559
|
-
get retryWait() {
|
|
560
|
-
return this.state.config.retryWait;
|
|
561
|
-
}
|
|
562
|
-
get retryAfter() {
|
|
563
|
-
return this.state.config.retryAfter;
|
|
564
|
-
}
|
|
565
|
-
get redirectLimit() {
|
|
566
|
-
return this.state.config.redirectLimit;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
module.exports = HttpAdapter;
|