got 11.5.1 → 11.6.2
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/source/as-promise/create-rejection.d.ts +0 -0
- package/dist/source/as-promise/create-rejection.js +0 -0
- package/dist/source/as-promise/index.d.ts +1 -3
- package/dist/source/as-promise/index.js +44 -125
- package/dist/source/as-promise/normalize-arguments.d.ts +3 -0
- package/dist/source/as-promise/normalize-arguments.js +78 -0
- package/dist/source/as-promise/parse-body.d.ts +3 -0
- package/dist/source/as-promise/parse-body.js +25 -0
- package/dist/source/as-promise/types.d.ts +206 -24
- package/dist/source/as-promise/types.js +18 -7
- package/dist/source/{as-promise → core}/calculate-retry-delay.d.ts +2 -1
- package/dist/source/core/calculate-retry-delay.js +29 -0
- package/dist/source/core/index.d.ts +822 -5
- package/dist/source/core/index.js +234 -46
- package/dist/source/core/utils/dns-ip-version.d.ts +0 -0
- package/dist/source/core/utils/dns-ip-version.js +0 -0
- package/dist/source/core/utils/get-body-size.d.ts +0 -0
- package/dist/source/core/utils/get-body-size.js +0 -0
- package/dist/source/core/utils/get-buffer.d.ts +0 -0
- package/dist/source/core/utils/get-buffer.js +0 -0
- package/dist/source/core/utils/is-form-data.d.ts +0 -0
- package/dist/source/core/utils/is-form-data.js +0 -0
- package/dist/source/core/utils/is-response-ok.d.ts +2 -0
- package/dist/source/core/utils/is-response-ok.js +8 -0
- package/dist/source/core/utils/options-to-url.d.ts +0 -0
- package/dist/source/core/utils/options-to-url.js +0 -0
- package/dist/source/core/utils/proxy-events.d.ts +0 -0
- package/dist/source/core/utils/proxy-events.js +0 -0
- package/dist/source/core/utils/timed-out.d.ts +0 -0
- package/dist/source/core/utils/timed-out.js +0 -0
- package/dist/source/core/utils/unhandle.d.ts +0 -0
- package/dist/source/core/utils/unhandle.js +0 -0
- package/dist/source/core/utils/url-to-options.d.ts +0 -0
- package/dist/source/core/utils/url-to-options.js +0 -0
- package/dist/source/core/utils/weakable-map.d.ts +0 -0
- package/dist/source/core/utils/weakable-map.js +0 -0
- package/dist/source/create.d.ts +0 -0
- package/dist/source/create.js +22 -14
- package/dist/source/index.d.ts +0 -0
- package/dist/source/index.js +3 -2
- package/dist/source/types.d.ts +240 -1
- package/dist/source/types.js +0 -0
- package/dist/source/utils/deep-freeze.d.ts +0 -0
- package/dist/source/utils/deep-freeze.js +0 -0
- package/dist/source/utils/deprecation-warning.d.ts +0 -0
- package/dist/source/utils/deprecation-warning.js +0 -0
- package/license +0 -0
- package/package.json +20 -16
- package/readme.md +180 -40
- package/dist/source/as-promise/calculate-retry-delay.js +0 -38
- package/dist/source/as-promise/core.d.ts +0 -13
- package/dist/source/as-promise/core.js +0 -127
|
@@ -25,7 +25,11 @@ const options_to_url_1 = require("./utils/options-to-url");
|
|
|
25
25
|
const weakable_map_1 = require("./utils/weakable-map");
|
|
26
26
|
const get_buffer_1 = require("./utils/get-buffer");
|
|
27
27
|
const dns_ip_version_1 = require("./utils/dns-ip-version");
|
|
28
|
+
const is_response_ok_1 = require("./utils/is-response-ok");
|
|
28
29
|
const deprecation_warning_1 = require("../utils/deprecation-warning");
|
|
30
|
+
const normalize_arguments_1 = require("../as-promise/normalize-arguments");
|
|
31
|
+
const calculate_retry_delay_1 = require("./calculate-retry-delay");
|
|
32
|
+
const globalDnsCache = new cacheable_lookup_1.default();
|
|
29
33
|
const kRequest = Symbol('request');
|
|
30
34
|
const kResponse = Symbol('response');
|
|
31
35
|
const kResponseSize = Symbol('responseSize');
|
|
@@ -42,10 +46,19 @@ const kTriggerRead = Symbol('triggerRead');
|
|
|
42
46
|
const kBody = Symbol('body');
|
|
43
47
|
const kJobs = Symbol('jobs');
|
|
44
48
|
const kOriginalResponse = Symbol('originalResponse');
|
|
49
|
+
const kRetryTimeout = Symbol('retryTimeout');
|
|
45
50
|
exports.kIsNormalizedAlready = Symbol('isNormalizedAlready');
|
|
46
51
|
const supportsBrotli = is_1.default.string(process.versions.brotli);
|
|
47
52
|
exports.withoutBody = new Set(['GET', 'HEAD']);
|
|
48
|
-
exports.knownHookEvents = [
|
|
53
|
+
exports.knownHookEvents = [
|
|
54
|
+
'init',
|
|
55
|
+
'beforeRequest',
|
|
56
|
+
'beforeRedirect',
|
|
57
|
+
'beforeError',
|
|
58
|
+
'beforeRetry',
|
|
59
|
+
// Promise-Only
|
|
60
|
+
'afterResponse'
|
|
61
|
+
];
|
|
49
62
|
function validateSearchParameters(searchParameters) {
|
|
50
63
|
// eslint-disable-next-line guard-for-in
|
|
51
64
|
for (const key in searchParameters) {
|
|
@@ -102,6 +115,10 @@ exports.setNonEnumerableProperties = (sources, to) => {
|
|
|
102
115
|
}
|
|
103
116
|
Object.defineProperties(to, properties);
|
|
104
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
An error to be thrown when a request fails.
|
|
120
|
+
Contains a `code` property with error class code, like `ECONNREFUSED`.
|
|
121
|
+
*/
|
|
105
122
|
class RequestError extends Error {
|
|
106
123
|
constructor(message, error, self) {
|
|
107
124
|
var _a;
|
|
@@ -148,6 +165,10 @@ class RequestError extends Error {
|
|
|
148
165
|
}
|
|
149
166
|
}
|
|
150
167
|
exports.RequestError = RequestError;
|
|
168
|
+
/**
|
|
169
|
+
An error to be thrown when the server redirects you more than ten times.
|
|
170
|
+
Includes a `response` property.
|
|
171
|
+
*/
|
|
151
172
|
class MaxRedirectsError extends RequestError {
|
|
152
173
|
constructor(request) {
|
|
153
174
|
super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
|
|
@@ -155,6 +176,10 @@ class MaxRedirectsError extends RequestError {
|
|
|
155
176
|
}
|
|
156
177
|
}
|
|
157
178
|
exports.MaxRedirectsError = MaxRedirectsError;
|
|
179
|
+
/**
|
|
180
|
+
An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
|
|
181
|
+
Includes a `response` property.
|
|
182
|
+
*/
|
|
158
183
|
class HTTPError extends RequestError {
|
|
159
184
|
constructor(response) {
|
|
160
185
|
super(`Response code ${response.statusCode} (${response.statusMessage})`, {}, response.request);
|
|
@@ -162,6 +187,10 @@ class HTTPError extends RequestError {
|
|
|
162
187
|
}
|
|
163
188
|
}
|
|
164
189
|
exports.HTTPError = HTTPError;
|
|
190
|
+
/**
|
|
191
|
+
An error to be thrown when a cache method fails.
|
|
192
|
+
For example, if the database goes down or there's a filesystem error.
|
|
193
|
+
*/
|
|
165
194
|
class CacheError extends RequestError {
|
|
166
195
|
constructor(error, request) {
|
|
167
196
|
super(error.message, error, request);
|
|
@@ -169,6 +198,9 @@ class CacheError extends RequestError {
|
|
|
169
198
|
}
|
|
170
199
|
}
|
|
171
200
|
exports.CacheError = CacheError;
|
|
201
|
+
/**
|
|
202
|
+
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
|
|
203
|
+
*/
|
|
172
204
|
class UploadError extends RequestError {
|
|
173
205
|
constructor(error, request) {
|
|
174
206
|
super(error.message, error, request);
|
|
@@ -176,6 +208,10 @@ class UploadError extends RequestError {
|
|
|
176
208
|
}
|
|
177
209
|
}
|
|
178
210
|
exports.UploadError = UploadError;
|
|
211
|
+
/**
|
|
212
|
+
An error to be thrown when the request is aborted due to a timeout.
|
|
213
|
+
Includes an `event` and `timings` property.
|
|
214
|
+
*/
|
|
179
215
|
class TimeoutError extends RequestError {
|
|
180
216
|
constructor(error, timings, request) {
|
|
181
217
|
super(error.message, error, request);
|
|
@@ -185,6 +221,9 @@ class TimeoutError extends RequestError {
|
|
|
185
221
|
}
|
|
186
222
|
}
|
|
187
223
|
exports.TimeoutError = TimeoutError;
|
|
224
|
+
/**
|
|
225
|
+
An error to be thrown when reading from response stream fails.
|
|
226
|
+
*/
|
|
188
227
|
class ReadError extends RequestError {
|
|
189
228
|
constructor(error, request) {
|
|
190
229
|
super(error.message, error, request);
|
|
@@ -192,6 +231,9 @@ class ReadError extends RequestError {
|
|
|
192
231
|
}
|
|
193
232
|
}
|
|
194
233
|
exports.ReadError = ReadError;
|
|
234
|
+
/**
|
|
235
|
+
An error to be thrown when given an unsupported protocol.
|
|
236
|
+
*/
|
|
195
237
|
class UnsupportedProtocolError extends RequestError {
|
|
196
238
|
constructor(options) {
|
|
197
239
|
super(`Unsupported protocol "${options.url.protocol}"`, {}, options);
|
|
@@ -210,6 +252,9 @@ const proxiedRequestEvents = [
|
|
|
210
252
|
class Request extends stream_1.Duplex {
|
|
211
253
|
constructor(url, options = {}, defaults) {
|
|
212
254
|
super({
|
|
255
|
+
// This must be false, to enable throwing after destroy
|
|
256
|
+
// It is used for retry logic in Promise API
|
|
257
|
+
autoDestroy: false,
|
|
213
258
|
// It needs to be zero because we're just proxying the data to another stream
|
|
214
259
|
highWaterMark: 0
|
|
215
260
|
});
|
|
@@ -221,6 +266,7 @@ class Request extends stream_1.Duplex {
|
|
|
221
266
|
this[kStopReading] = false;
|
|
222
267
|
this[kTriggerRead] = false;
|
|
223
268
|
this[kJobs] = [];
|
|
269
|
+
this.retryCount = 0;
|
|
224
270
|
// TODO: Remove this when targeting Node.js >= 12
|
|
225
271
|
this._progressCallbacks = [];
|
|
226
272
|
const unlockWrite = () => this._unlockWrite();
|
|
@@ -278,6 +324,8 @@ class Request extends stream_1.Duplex {
|
|
|
278
324
|
for (const job of this[kJobs]) {
|
|
279
325
|
job();
|
|
280
326
|
}
|
|
327
|
+
// Prevent memory leak
|
|
328
|
+
this[kJobs].length = 0;
|
|
281
329
|
this.requestInitialized = true;
|
|
282
330
|
}
|
|
283
331
|
catch (error) {
|
|
@@ -293,7 +341,7 @@ class Request extends stream_1.Duplex {
|
|
|
293
341
|
})(options);
|
|
294
342
|
}
|
|
295
343
|
static normalizeArguments(url, options, defaults) {
|
|
296
|
-
var _a, _b, _c, _d;
|
|
344
|
+
var _a, _b, _c, _d, _e;
|
|
297
345
|
const rawOptions = options;
|
|
298
346
|
if (is_1.default.object(url) && !is_1.default.urlInstance(url)) {
|
|
299
347
|
options = { ...defaults, ...url, ...options };
|
|
@@ -347,6 +395,7 @@ class Request extends stream_1.Duplex {
|
|
|
347
395
|
is_1.assert.any([is_1.default.string, is_1.default.object, is_1.default.array, is_1.default.undefined], options.https.certificate);
|
|
348
396
|
is_1.assert.any([is_1.default.string, is_1.default.undefined], options.https.passphrase);
|
|
349
397
|
}
|
|
398
|
+
is_1.assert.any([is_1.default.object, is_1.default.undefined], options.cacheOptions);
|
|
350
399
|
// `options.method`
|
|
351
400
|
if (is_1.default.string(options.method)) {
|
|
352
401
|
options.method = options.method.toUpperCase();
|
|
@@ -404,15 +453,15 @@ class Request extends stream_1.Duplex {
|
|
|
404
453
|
options.username = (_b = options.username) !== null && _b !== void 0 ? _b : '';
|
|
405
454
|
options.password = (_c = options.password) !== null && _c !== void 0 ? _c : '';
|
|
406
455
|
// `options.prefixUrl` & `options.url`
|
|
407
|
-
if (options.prefixUrl) {
|
|
456
|
+
if (is_1.default.undefined(options.prefixUrl)) {
|
|
457
|
+
options.prefixUrl = (_d = defaults === null || defaults === void 0 ? void 0 : defaults.prefixUrl) !== null && _d !== void 0 ? _d : '';
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
408
460
|
options.prefixUrl = options.prefixUrl.toString();
|
|
409
461
|
if (options.prefixUrl !== '' && !options.prefixUrl.endsWith('/')) {
|
|
410
462
|
options.prefixUrl += '/';
|
|
411
463
|
}
|
|
412
464
|
}
|
|
413
|
-
else {
|
|
414
|
-
options.prefixUrl = '';
|
|
415
|
-
}
|
|
416
465
|
if (is_1.default.string(options.url)) {
|
|
417
466
|
if (options.url.startsWith('/')) {
|
|
418
467
|
throw new Error('`input` must not start with a slash when using `prefixUrl`');
|
|
@@ -478,9 +527,7 @@ class Request extends stream_1.Duplex {
|
|
|
478
527
|
getCookieString = util_1.promisify(getCookieString.bind(options.cookieJar));
|
|
479
528
|
options.cookieJar = {
|
|
480
529
|
setCookie,
|
|
481
|
-
|
|
482
|
-
// @ts-expect-error TypeScript thinks that promisifying callback(error, string) will result in Promise<void>
|
|
483
|
-
getCookieString
|
|
530
|
+
getCookieString: getCookieString
|
|
484
531
|
};
|
|
485
532
|
}
|
|
486
533
|
}
|
|
@@ -521,9 +568,11 @@ class Request extends stream_1.Duplex {
|
|
|
521
568
|
}), cache));
|
|
522
569
|
}
|
|
523
570
|
}
|
|
571
|
+
// `options.cacheOptions`
|
|
572
|
+
options.cacheOptions = { ...options.cacheOptions };
|
|
524
573
|
// `options.dnsCache`
|
|
525
574
|
if (options.dnsCache === true) {
|
|
526
|
-
options.dnsCache =
|
|
575
|
+
options.dnsCache = globalDnsCache;
|
|
527
576
|
}
|
|
528
577
|
else if (!is_1.default.undefined(options.dnsCache) && !options.dnsCache.lookup) {
|
|
529
578
|
throw new TypeError(`Parameter \`dnsCache\` must be a CacheableLookup instance or a boolean, got ${is_1.default(options.dnsCache)}`);
|
|
@@ -611,10 +660,10 @@ class Request extends stream_1.Duplex {
|
|
|
611
660
|
}
|
|
612
661
|
}
|
|
613
662
|
}
|
|
614
|
-
options.maxRedirects = (
|
|
663
|
+
options.maxRedirects = (_e = options.maxRedirects) !== null && _e !== void 0 ? _e : 0;
|
|
615
664
|
// Set non-enumerable properties
|
|
616
665
|
exports.setNonEnumerableProperties([defaults, rawOptions], options);
|
|
617
|
-
return options;
|
|
666
|
+
return normalize_arguments_1.default(options, defaults);
|
|
618
667
|
}
|
|
619
668
|
_lockWrite() {
|
|
620
669
|
const onLockedWrite = () => {
|
|
@@ -716,6 +765,7 @@ class Request extends stream_1.Duplex {
|
|
|
716
765
|
typedResponse.request = this;
|
|
717
766
|
typedResponse.isFromCache = response.fromCache || false;
|
|
718
767
|
typedResponse.ip = this.ip;
|
|
768
|
+
typedResponse.retryCount = this.retryCount;
|
|
719
769
|
this[kIsFromCache] = typedResponse.isFromCache;
|
|
720
770
|
this[kResponseSize] = Number(response.headers['content-length']) || undefined;
|
|
721
771
|
this[kResponse] = response;
|
|
@@ -753,7 +803,7 @@ class Request extends stream_1.Duplex {
|
|
|
753
803
|
}
|
|
754
804
|
if (options.followRedirect && response.headers.location && redirectCodes.has(statusCode)) {
|
|
755
805
|
// We're being redirected, we don't care about the response.
|
|
756
|
-
// It'd be
|
|
806
|
+
// It'd be best to abort the request, but we can't because
|
|
757
807
|
// we would have to sacrifice the TCP connection. We don't want that.
|
|
758
808
|
response.resume();
|
|
759
809
|
if (this[kRequest]) {
|
|
@@ -789,7 +839,7 @@ class Request extends stream_1.Duplex {
|
|
|
789
839
|
const redirectString = redirectUrl.toString();
|
|
790
840
|
decodeURI(redirectString);
|
|
791
841
|
// Redirecting to a different site, clear sensitive data.
|
|
792
|
-
if (redirectUrl.hostname !== url.hostname) {
|
|
842
|
+
if (redirectUrl.hostname !== url.hostname || redirectUrl.port !== url.port) {
|
|
793
843
|
if ('host' in options.headers) {
|
|
794
844
|
delete options.headers.host;
|
|
795
845
|
}
|
|
@@ -800,9 +850,15 @@ class Request extends stream_1.Duplex {
|
|
|
800
850
|
delete options.headers.authorization;
|
|
801
851
|
}
|
|
802
852
|
if (options.username || options.password) {
|
|
853
|
+
// TODO: Fix this ignore.
|
|
854
|
+
// @ts-expect-error
|
|
803
855
|
delete options.username;
|
|
856
|
+
// @ts-expect-error
|
|
804
857
|
delete options.password;
|
|
805
858
|
}
|
|
859
|
+
if ('port' in options) {
|
|
860
|
+
delete options.port;
|
|
861
|
+
}
|
|
806
862
|
}
|
|
807
863
|
this.redirects.push(redirectString);
|
|
808
864
|
options.url = redirectUrl;
|
|
@@ -819,16 +875,9 @@ class Request extends stream_1.Duplex {
|
|
|
819
875
|
}
|
|
820
876
|
return;
|
|
821
877
|
}
|
|
822
|
-
|
|
823
|
-
const isOk = (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304;
|
|
824
|
-
if (options.throwHttpErrors && !isOk) {
|
|
825
|
-
// Normally we would have to use `void [await] this._beforeError(error)` everywhere,
|
|
826
|
-
// but since there's `void (async () => { ... })()` inside of it, we don't have to.
|
|
878
|
+
if (options.isStream && options.throwHttpErrors && !is_response_ok_1.isResponseOk(typedResponse)) {
|
|
827
879
|
this._beforeError(new HTTPError(typedResponse));
|
|
828
|
-
|
|
829
|
-
if (this[kStopReading]) {
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
880
|
+
return;
|
|
832
881
|
}
|
|
833
882
|
response.on('readable', () => {
|
|
834
883
|
if (this[kTriggerRead]) {
|
|
@@ -865,6 +914,7 @@ class Request extends stream_1.Duplex {
|
|
|
865
914
|
await this._onResponseBase(response);
|
|
866
915
|
}
|
|
867
916
|
catch (error) {
|
|
917
|
+
/* istanbul ignore next: better safe than sorry */
|
|
868
918
|
this._beforeError(error);
|
|
869
919
|
}
|
|
870
920
|
}
|
|
@@ -902,9 +952,6 @@ class Request extends stream_1.Duplex {
|
|
|
902
952
|
body.once('error', (error) => {
|
|
903
953
|
this._beforeError(new UploadError(error, this));
|
|
904
954
|
});
|
|
905
|
-
body.once('end', () => {
|
|
906
|
-
delete options.body;
|
|
907
|
-
});
|
|
908
955
|
}
|
|
909
956
|
else {
|
|
910
957
|
this._unlockWrite();
|
|
@@ -925,6 +972,8 @@ class Request extends stream_1.Duplex {
|
|
|
925
972
|
// TODO: Remove `utils/url-to-options.ts` when `cacheable-request` is fixed
|
|
926
973
|
Object.assign(options, url_to_options_1.default(url));
|
|
927
974
|
// `http-cache-semantics` checks this
|
|
975
|
+
// TODO: Fix this ignore.
|
|
976
|
+
// @ts-expect-error
|
|
928
977
|
delete options.url;
|
|
929
978
|
let request;
|
|
930
979
|
// This is ugly
|
|
@@ -946,7 +995,7 @@ class Request extends stream_1.Duplex {
|
|
|
946
995
|
});
|
|
947
996
|
}
|
|
948
997
|
async _makeRequest() {
|
|
949
|
-
var _a;
|
|
998
|
+
var _a, _b, _c, _d, _e;
|
|
950
999
|
const { options } = this;
|
|
951
1000
|
const { headers } = options;
|
|
952
1001
|
for (const key in headers) {
|
|
@@ -1012,14 +1061,20 @@ class Request extends stream_1.Duplex {
|
|
|
1012
1061
|
// Prepare plain HTTP request options
|
|
1013
1062
|
options[kRequest] = realFn;
|
|
1014
1063
|
delete options.request;
|
|
1064
|
+
// TODO: Fix this ignore.
|
|
1065
|
+
// @ts-expect-error
|
|
1015
1066
|
delete options.timeout;
|
|
1016
1067
|
const requestOptions = options;
|
|
1068
|
+
requestOptions.shared = (_b = options.cacheOptions) === null || _b === void 0 ? void 0 : _b.shared;
|
|
1069
|
+
requestOptions.cacheHeuristic = (_c = options.cacheOptions) === null || _c === void 0 ? void 0 : _c.cacheHeuristic;
|
|
1070
|
+
requestOptions.immutableMinTimeToLive = (_d = options.cacheOptions) === null || _d === void 0 ? void 0 : _d.immutableMinTimeToLive;
|
|
1071
|
+
requestOptions.ignoreCargoCult = (_e = options.cacheOptions) === null || _e === void 0 ? void 0 : _e.ignoreCargoCult;
|
|
1017
1072
|
// If `dnsLookupIpVersion` is not present do not override `family`
|
|
1018
1073
|
if (options.dnsLookupIpVersion !== undefined) {
|
|
1019
1074
|
try {
|
|
1020
1075
|
requestOptions.family = dns_ip_version_1.dnsLookupIpVersionToFamily(options.dnsLookupIpVersion);
|
|
1021
1076
|
}
|
|
1022
|
-
catch (
|
|
1077
|
+
catch (_f) {
|
|
1023
1078
|
throw new Error('Invalid `dnsLookupIpVersion` option value');
|
|
1024
1079
|
}
|
|
1025
1080
|
}
|
|
@@ -1053,6 +1108,28 @@ class Request extends stream_1.Duplex {
|
|
|
1053
1108
|
options.request = request;
|
|
1054
1109
|
options.timeout = timeout;
|
|
1055
1110
|
options.agent = agent;
|
|
1111
|
+
// HTTPS options restore
|
|
1112
|
+
if (options.https) {
|
|
1113
|
+
if ('rejectUnauthorized' in options.https) {
|
|
1114
|
+
delete requestOptions.rejectUnauthorized;
|
|
1115
|
+
}
|
|
1116
|
+
if (options.https.checkServerIdentity) {
|
|
1117
|
+
// @ts-expect-error - This one will be removed when we remove the alias.
|
|
1118
|
+
delete requestOptions.checkServerIdentity;
|
|
1119
|
+
}
|
|
1120
|
+
if (options.https.certificateAuthority) {
|
|
1121
|
+
delete requestOptions.ca;
|
|
1122
|
+
}
|
|
1123
|
+
if (options.https.certificate) {
|
|
1124
|
+
delete requestOptions.cert;
|
|
1125
|
+
}
|
|
1126
|
+
if (options.https.key) {
|
|
1127
|
+
delete requestOptions.key;
|
|
1128
|
+
}
|
|
1129
|
+
if (options.https.passphrase) {
|
|
1130
|
+
delete requestOptions.passphrase;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1056
1133
|
if (isClientRequest(requestOrResponse)) {
|
|
1057
1134
|
this._onRequest(requestOrResponse);
|
|
1058
1135
|
// Emit the response after the stream has been ended
|
|
@@ -1076,34 +1153,97 @@ class Request extends stream_1.Duplex {
|
|
|
1076
1153
|
throw new RequestError(error.message, error, this);
|
|
1077
1154
|
}
|
|
1078
1155
|
}
|
|
1156
|
+
async _error(error) {
|
|
1157
|
+
try {
|
|
1158
|
+
for (const hook of this.options.hooks.beforeError) {
|
|
1159
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1160
|
+
error = await hook(error);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
catch (error_) {
|
|
1164
|
+
error = new RequestError(error_.message, error_, this);
|
|
1165
|
+
}
|
|
1166
|
+
this.destroy(error);
|
|
1167
|
+
}
|
|
1079
1168
|
_beforeError(error) {
|
|
1080
|
-
if (this
|
|
1169
|
+
if (this[kStopReading]) {
|
|
1081
1170
|
return;
|
|
1082
1171
|
}
|
|
1172
|
+
const { options } = this;
|
|
1173
|
+
const retryCount = this.retryCount + 1;
|
|
1083
1174
|
this[kStopReading] = true;
|
|
1084
1175
|
if (!(error instanceof RequestError)) {
|
|
1085
1176
|
error = new RequestError(error.message, error, this);
|
|
1086
1177
|
}
|
|
1178
|
+
const typedError = error;
|
|
1179
|
+
const { response } = typedError;
|
|
1087
1180
|
void (async () => {
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
response.setEncoding(this._readableState.encoding);
|
|
1181
|
+
if (response && !response.body) {
|
|
1182
|
+
response.setEncoding(this._readableState.encoding);
|
|
1183
|
+
try {
|
|
1092
1184
|
response.rawBody = await get_buffer_1.default(response);
|
|
1093
1185
|
response.body = response.rawBody.toString();
|
|
1094
1186
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1187
|
+
catch (_a) { }
|
|
1188
|
+
}
|
|
1189
|
+
if (this.listenerCount('retry') !== 0) {
|
|
1190
|
+
let backoff;
|
|
1191
|
+
try {
|
|
1192
|
+
let retryAfter;
|
|
1193
|
+
if (response && 'retry-after' in response.headers) {
|
|
1194
|
+
retryAfter = Number(response.headers['retry-after']);
|
|
1195
|
+
if (Number.isNaN(retryAfter)) {
|
|
1196
|
+
retryAfter = Date.parse(response.headers['retry-after']) - Date.now();
|
|
1197
|
+
if (retryAfter <= 0) {
|
|
1198
|
+
retryAfter = 1;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
retryAfter *= 1000;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
backoff = await options.retry.calculateDelay({
|
|
1206
|
+
attemptCount: retryCount,
|
|
1207
|
+
retryOptions: options.retry,
|
|
1208
|
+
error: typedError,
|
|
1209
|
+
retryAfter,
|
|
1210
|
+
computedValue: calculate_retry_delay_1.default({
|
|
1211
|
+
attemptCount: retryCount,
|
|
1212
|
+
retryOptions: options.retry,
|
|
1213
|
+
error: typedError,
|
|
1214
|
+
retryAfter,
|
|
1215
|
+
computedValue: 0
|
|
1216
|
+
})
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
catch (error_) {
|
|
1220
|
+
void this._error(new RequestError(error_.message, error_, this));
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
if (backoff) {
|
|
1224
|
+
const retry = async () => {
|
|
1225
|
+
try {
|
|
1226
|
+
for (const hook of this.options.hooks.beforeRetry) {
|
|
1227
|
+
// eslint-disable-next-line no-await-in-loop
|
|
1228
|
+
await hook(this.options, typedError, retryCount);
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
catch (error_) {
|
|
1232
|
+
void this._error(new RequestError(error_.message, error, this));
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
// Something forced us to abort the retry
|
|
1236
|
+
if (this.destroyed) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
this.destroy();
|
|
1240
|
+
this.emit('retry', retryCount, error);
|
|
1241
|
+
};
|
|
1242
|
+
this[kRetryTimeout] = setTimeout(retry, backoff);
|
|
1243
|
+
return;
|
|
1101
1244
|
}
|
|
1102
1245
|
}
|
|
1103
|
-
|
|
1104
|
-
error = new RequestError(error_.message, error_, this);
|
|
1105
|
-
}
|
|
1106
|
-
this.destroy(error);
|
|
1246
|
+
void this._error(typedError);
|
|
1107
1247
|
})();
|
|
1108
1248
|
}
|
|
1109
1249
|
_read() {
|
|
@@ -1140,6 +1280,10 @@ class Request extends stream_1.Duplex {
|
|
|
1140
1280
|
}
|
|
1141
1281
|
}
|
|
1142
1282
|
_writeRequest(chunk, encoding, callback) {
|
|
1283
|
+
if (this[kRequest].destroyed) {
|
|
1284
|
+
// Probably the `ClientRequest` instance will throw
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1143
1287
|
this._progressCallbacks.push(() => {
|
|
1144
1288
|
this[kUploadedSize] += Buffer.byteLength(chunk, encoding);
|
|
1145
1289
|
const progress = this.uploadProgress;
|
|
@@ -1190,6 +1334,8 @@ class Request extends stream_1.Duplex {
|
|
|
1190
1334
|
_destroy(error, callback) {
|
|
1191
1335
|
var _a;
|
|
1192
1336
|
this[kStopReading] = true;
|
|
1337
|
+
// Prevent further retries
|
|
1338
|
+
clearTimeout(this[kRetryTimeout]);
|
|
1193
1339
|
if (kRequest in this) {
|
|
1194
1340
|
this[kCancelTimeouts]();
|
|
1195
1341
|
// TODO: Remove the next `if` when these get fixed:
|
|
@@ -1203,10 +1349,19 @@ class Request extends stream_1.Duplex {
|
|
|
1203
1349
|
}
|
|
1204
1350
|
callback(error);
|
|
1205
1351
|
}
|
|
1352
|
+
get _isAboutToError() {
|
|
1353
|
+
return this[kStopReading];
|
|
1354
|
+
}
|
|
1355
|
+
/**
|
|
1356
|
+
The remote IP address.
|
|
1357
|
+
*/
|
|
1206
1358
|
get ip() {
|
|
1207
1359
|
var _a;
|
|
1208
1360
|
return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket.remoteAddress;
|
|
1209
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
Indicates whether the request has been aborted or not.
|
|
1364
|
+
*/
|
|
1210
1365
|
get aborted() {
|
|
1211
1366
|
var _a, _b, _c;
|
|
1212
1367
|
return ((_b = (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.destroyed) !== null && _b !== void 0 ? _b : this.destroyed) && !((_c = this[kOriginalResponse]) === null || _c === void 0 ? void 0 : _c.complete);
|
|
@@ -1215,6 +1370,9 @@ class Request extends stream_1.Duplex {
|
|
|
1215
1370
|
var _a;
|
|
1216
1371
|
return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.socket;
|
|
1217
1372
|
}
|
|
1373
|
+
/**
|
|
1374
|
+
Progress event for downloading (receiving a response).
|
|
1375
|
+
*/
|
|
1218
1376
|
get downloadProgress() {
|
|
1219
1377
|
let percent;
|
|
1220
1378
|
if (this[kResponseSize]) {
|
|
@@ -1232,6 +1390,9 @@ class Request extends stream_1.Duplex {
|
|
|
1232
1390
|
total: this[kResponseSize]
|
|
1233
1391
|
};
|
|
1234
1392
|
}
|
|
1393
|
+
/**
|
|
1394
|
+
Progress event for uploading (sending a request).
|
|
1395
|
+
*/
|
|
1235
1396
|
get uploadProgress() {
|
|
1236
1397
|
let percent;
|
|
1237
1398
|
if (this[kBodySize]) {
|
|
@@ -1249,16 +1410,43 @@ class Request extends stream_1.Duplex {
|
|
|
1249
1410
|
total: this[kBodySize]
|
|
1250
1411
|
};
|
|
1251
1412
|
}
|
|
1413
|
+
/**
|
|
1414
|
+
The object contains the following properties:
|
|
1415
|
+
|
|
1416
|
+
- `start` - Time when the request started.
|
|
1417
|
+
- `socket` - Time when a socket was assigned to the request.
|
|
1418
|
+
- `lookup` - Time when the DNS lookup finished.
|
|
1419
|
+
- `connect` - Time when the socket successfully connected.
|
|
1420
|
+
- `secureConnect` - Time when the socket securely connected.
|
|
1421
|
+
- `upload` - Time when the request finished uploading.
|
|
1422
|
+
- `response` - Time when the request fired `response` event.
|
|
1423
|
+
- `end` - Time when the response fired `end` event.
|
|
1424
|
+
- `error` - Time when the request fired `error` event.
|
|
1425
|
+
- `abort` - Time when the request fired `abort` event.
|
|
1426
|
+
- `phases`
|
|
1427
|
+
- `wait` - `timings.socket - timings.start`
|
|
1428
|
+
- `dns` - `timings.lookup - timings.socket`
|
|
1429
|
+
- `tcp` - `timings.connect - timings.lookup`
|
|
1430
|
+
- `tls` - `timings.secureConnect - timings.connect`
|
|
1431
|
+
- `request` - `timings.upload - (timings.secureConnect || timings.connect)`
|
|
1432
|
+
- `firstByte` - `timings.response - timings.upload`
|
|
1433
|
+
- `download` - `timings.end - timings.response`
|
|
1434
|
+
- `total` - `(timings.end || timings.error || timings.abort) - timings.start`
|
|
1435
|
+
|
|
1436
|
+
If something has not been measured yet, it will be `undefined`.
|
|
1437
|
+
|
|
1438
|
+
__Note__: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
|
|
1439
|
+
*/
|
|
1252
1440
|
get timings() {
|
|
1253
1441
|
var _a;
|
|
1254
1442
|
return (_a = this[kRequest]) === null || _a === void 0 ? void 0 : _a.timings;
|
|
1255
1443
|
}
|
|
1444
|
+
/**
|
|
1445
|
+
Whether the response was retrieved from the cache.
|
|
1446
|
+
*/
|
|
1256
1447
|
get isFromCache() {
|
|
1257
1448
|
return this[kIsFromCache];
|
|
1258
1449
|
}
|
|
1259
|
-
get _response() {
|
|
1260
|
-
return this[kResponse];
|
|
1261
|
-
}
|
|
1262
1450
|
pipe(destination, options) {
|
|
1263
1451
|
if (this[kStartedReading]) {
|
|
1264
1452
|
throw new Error('Failed to pipe. The response has been emitted already.');
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isResponseOk = void 0;
|
|
4
|
+
exports.isResponseOk = (response) => {
|
|
5
|
+
const { statusCode } = response;
|
|
6
|
+
const limitStatusCode = response.request.options.followRedirect ? 299 : 399;
|
|
7
|
+
return (statusCode >= 200 && statusCode <= limitStatusCode) || statusCode === 304;
|
|
8
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/source/create.d.ts
CHANGED
|
File without changes
|