got 9.3.2 → 9.6.0
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/package.json +9 -9
- package/readme.md +197 -85
- package/source/as-promise.js +1 -0
- package/source/as-stream.js +1 -0
- package/source/errors.js +26 -24
- package/source/index.js +10 -0
- package/source/known-hook-events.js +2 -0
- package/source/normalize-arguments.js +42 -27
- package/source/request-as-event-emitter.js +32 -16
- package/source/utils/timed-out.js +9 -2
- package/source/utils/is-retry-on-network-error-allowed.js +0 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "got",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.6.0",
|
|
4
4
|
"description": "Simplified HTTP requests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/got",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"electron"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@sindresorhus/is": "^0.
|
|
38
|
-
"@szmarczak/http-timer": "^1.1.
|
|
39
|
-
"cacheable-request": "^
|
|
37
|
+
"@sindresorhus/is": "^0.14.0",
|
|
38
|
+
"@szmarczak/http-timer": "^1.1.2",
|
|
39
|
+
"cacheable-request": "^6.0.0",
|
|
40
40
|
"decompress-response": "^3.3.0",
|
|
41
41
|
"duplexer3": "^0.1.4",
|
|
42
42
|
"get-stream": "^4.1.0",
|
|
@@ -47,22 +47,22 @@
|
|
|
47
47
|
"url-parse-lax": "^3.0.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"ava": "1.
|
|
50
|
+
"ava": "^1.1.0",
|
|
51
51
|
"coveralls": "^3.0.0",
|
|
52
52
|
"delay": "^4.1.0",
|
|
53
53
|
"form-data": "^2.3.3",
|
|
54
54
|
"get-port": "^4.0.0",
|
|
55
|
-
"np": "^3.0
|
|
55
|
+
"np": "^3.1.0",
|
|
56
56
|
"nyc": "^13.1.0",
|
|
57
57
|
"p-event": "^2.1.0",
|
|
58
58
|
"pem": "^1.13.2",
|
|
59
59
|
"proxyquire": "^2.0.1",
|
|
60
|
-
"sinon": "^7.
|
|
60
|
+
"sinon": "^7.2.2",
|
|
61
61
|
"slow-stream": "0.0.4",
|
|
62
62
|
"tempfile": "^2.0.0",
|
|
63
63
|
"tempy": "^0.2.1",
|
|
64
|
-
"tough-cookie": "^
|
|
65
|
-
"xo": "^0.
|
|
64
|
+
"tough-cookie": "^3.0.0",
|
|
65
|
+
"xo": "^0.24.0"
|
|
66
66
|
},
|
|
67
67
|
"ava": {
|
|
68
68
|
"concurrency": 4
|
package/readme.md
CHANGED
|
@@ -35,15 +35,16 @@ Got is for Node.js. For browsers, we recommend [Ky](https://github.com/sindresor
|
|
|
35
35
|
- [Errors with metadata](#errors)
|
|
36
36
|
- [JSON mode](#json)
|
|
37
37
|
- [WHATWG URL support](#url)
|
|
38
|
-
- [Hooks](
|
|
38
|
+
- [Hooks](#hooks)
|
|
39
39
|
- [Instances with custom defaults](#instances)
|
|
40
40
|
- [Composable](advanced-creation.md#merging-instances)
|
|
41
41
|
- [Electron support](#useelectronnet)
|
|
42
42
|
- [Used by ~2000 packages and ~500K repos](https://github.com/sindresorhus/got/network/dependents)
|
|
43
43
|
- Actively maintained
|
|
44
44
|
|
|
45
|
-
[
|
|
45
|
+
[Moving from Request?](migration-guides.md)
|
|
46
46
|
|
|
47
|
+
[See how Got compares to other HTTP libraries](#comparison)
|
|
47
48
|
|
|
48
49
|
## Install
|
|
49
50
|
|
|
@@ -154,7 +155,7 @@ Returns a `Stream` instead of a `Promise`. This is equivalent to calling `got.st
|
|
|
154
155
|
|
|
155
156
|
Type: `string` `Buffer` `stream.Readable` [`form-data` instance](https://github.com/form-data/form-data)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
**Note:** If you provide this option, `got.stream()` will be read-only.
|
|
158
159
|
|
|
159
160
|
The body that will be sent with a `POST` request.
|
|
160
161
|
|
|
@@ -166,9 +167,9 @@ The `content-length` header will be automatically set if `body` is a `string` /
|
|
|
166
167
|
|
|
167
168
|
Type: [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)
|
|
168
169
|
|
|
169
|
-
|
|
170
|
+
**Note:** If you provide this option, `options.headers.cookie` will be overridden.
|
|
170
171
|
|
|
171
|
-
|
|
172
|
+
Cookie support. You don't have to care about parsing or how to store them. [Example.](#cookies)
|
|
172
173
|
|
|
173
174
|
###### encoding
|
|
174
175
|
|
|
@@ -182,25 +183,23 @@ Default: `'utf8'`
|
|
|
182
183
|
Type: `boolean`<br>
|
|
183
184
|
Default: `false`
|
|
184
185
|
|
|
185
|
-
|
|
186
|
+
**Note:** If you provide this option, `got.stream()` will be read-only.
|
|
187
|
+
**Note:** `body` must be a plain object. It will be converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
|
|
186
188
|
|
|
187
189
|
If set to `true` and `Content-Type` header is not set, it will be set to `application/x-www-form-urlencoded`.
|
|
188
190
|
|
|
189
|
-
`body` must be a plain object. It will be converted to a query string using [`(new URLSearchParams(object)).toString()`](https://nodejs.org/api/url.html#url_constructor_new_urlsearchparams_obj).
|
|
190
|
-
|
|
191
191
|
###### json
|
|
192
192
|
|
|
193
193
|
Type: `boolean`<br>
|
|
194
194
|
Default: `false`
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
**Note:** If you use `got.stream()`, this option will be ignored.
|
|
197
|
+
**Note:** `body` must be a plain object or array and will be stringified.
|
|
197
198
|
|
|
198
199
|
If set to `true` and `Content-Type` header is not set, it will be set to `application/json`.
|
|
199
200
|
|
|
200
201
|
Parse response body with `JSON.parse` and set `accept` header to `application/json`. If used in conjunction with the `form` option, the `body` will the stringified as querystring and the response parsed as JSON.
|
|
201
202
|
|
|
202
|
-
`body` must be a plain object or array and will be stringified.
|
|
203
|
-
|
|
204
203
|
###### query
|
|
205
204
|
|
|
206
205
|
Type: `string` `Object<string, string|number>` [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
|
|
@@ -258,8 +257,9 @@ Default:
|
|
|
258
257
|
- methods: `GET` `PUT` `HEAD` `DELETE` `OPTIONS` `TRACE`
|
|
259
258
|
- statusCodes: [`408`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) [`413`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413) [`429`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) [`500`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) [`502`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) [`503`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) [`504`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504)
|
|
260
259
|
- maxRetryAfter: `undefined`
|
|
260
|
+
- errorCodes: `ETIMEDOUT` `ECONNRESET` `EADDRINUSE` `ECONNREFUSED` `EPIPE` `ENOTFOUND` `ENETUNREACH` `EAI_AGAIN`
|
|
261
261
|
|
|
262
|
-
An object representing `retries`, `methods`, `statusCodes` and `
|
|
262
|
+
An object representing `retries`, `methods`, `statusCodes`, `maxRetryAfter` and `errorCodes` fields for the time until retry, allowed methods, allowed status codes, maximum [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) time and allowed error codes.
|
|
263
263
|
|
|
264
264
|
If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`.<br>
|
|
265
265
|
If [`Retry-After`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After) header is greater than `maxRetryAfter`, it will cancel the request.
|
|
@@ -268,12 +268,15 @@ Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.ra
|
|
|
268
268
|
|
|
269
269
|
The `retries` property can be a `number` or a `function` with `retry` and `error` arguments. The function must return a delay in milliseconds (`0` return value cancels retry).
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
By default, it retries *only* on the specified methods, status codes, and on these network errors:
|
|
272
272
|
- `ETIMEDOUT`: One of the [timeout](#timeout) limits were reached.
|
|
273
273
|
- `ECONNRESET`: Connection was forcibly closed by a peer.
|
|
274
274
|
- `EADDRINUSE`: Could not bind to any free port.
|
|
275
275
|
- `ECONNREFUSED`: Connection was refused by the server.
|
|
276
276
|
- `EPIPE`: The remote side of the stream being written has been closed.
|
|
277
|
+
- `ENOTFOUND`: Couldn't resolve the hostname to an IP address.
|
|
278
|
+
- `ENETUNREACH`: No internet connection.
|
|
279
|
+
- `EAI_AGAIN`: DNS lookup timed out.
|
|
277
280
|
|
|
278
281
|
###### followRedirect
|
|
279
282
|
|
|
@@ -348,6 +351,17 @@ Type: `Object<string, Function[]>`
|
|
|
348
351
|
|
|
349
352
|
Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
|
|
350
353
|
|
|
354
|
+
###### hooks.init
|
|
355
|
+
|
|
356
|
+
Type: `Function[]`<br>
|
|
357
|
+
Default: `[]`
|
|
358
|
+
|
|
359
|
+
Called with plain [request options](#options), right before their normalization. This is especially useful in conjunction with [`got.extend()`](#instances) and [`got.create()`](advanced-creation.md) when the input needs custom handling.
|
|
360
|
+
|
|
361
|
+
See the [Request migration guide](migration-guides.md#breaking-changes) for an example.
|
|
362
|
+
|
|
363
|
+
**Note**: This hook must be synchronous!
|
|
364
|
+
|
|
351
365
|
###### hooks.beforeRequest
|
|
352
366
|
|
|
353
367
|
Type: `Function[]`<br>
|
|
@@ -357,7 +371,7 @@ Called with [normalized](source/normalize-arguments.js) [request options](#optio
|
|
|
357
371
|
|
|
358
372
|
See the [AWS section](#aws) for an example.
|
|
359
373
|
|
|
360
|
-
**Note
|
|
374
|
+
**Note:** If you modify the `body` you will need to modify the `content-length` header too, because it has already been computed and assigned.
|
|
361
375
|
|
|
362
376
|
###### hooks.beforeRedirect
|
|
363
377
|
|
|
@@ -444,10 +458,47 @@ const instance = got.extend({
|
|
|
444
458
|
});
|
|
445
459
|
```
|
|
446
460
|
|
|
461
|
+
###### hooks.beforeError
|
|
462
|
+
|
|
463
|
+
Type: `Function[]`<br>
|
|
464
|
+
Default: `[]`
|
|
465
|
+
|
|
466
|
+
Called with an `Error` instance. The error is passed to the hook right before it's thrown. This is especially useful when you want to have more detailed errors.
|
|
467
|
+
|
|
468
|
+
**Note**: Errors thrown while normalizing input options are thrown directly and not part of this hook.
|
|
469
|
+
|
|
470
|
+
```js
|
|
471
|
+
const got = require('got');
|
|
472
|
+
|
|
473
|
+
got('api.github.com/some-endpoint', {
|
|
474
|
+
hooks: {
|
|
475
|
+
onError: [
|
|
476
|
+
error => {
|
|
477
|
+
const {response} = error;
|
|
478
|
+
if (response && response.body) {
|
|
479
|
+
error.name = 'GitHubError';
|
|
480
|
+
error.message = `${response.body.message} (${error.statusCode})`;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return error;
|
|
484
|
+
}
|
|
485
|
+
]
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
```
|
|
489
|
+
|
|
447
490
|
#### Response
|
|
448
491
|
|
|
449
492
|
The response object will typically be a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage), however, if returned from the cache it will be a [response-like object](https://github.com/lukechilds/responselike) which behaves in the same way.
|
|
450
493
|
|
|
494
|
+
##### request
|
|
495
|
+
|
|
496
|
+
Type: `Object`
|
|
497
|
+
|
|
498
|
+
**Note:** This is not a [http.ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest).
|
|
499
|
+
|
|
500
|
+
- `gotOptions` - The options that were set on this request.
|
|
501
|
+
|
|
451
502
|
##### body
|
|
452
503
|
|
|
453
504
|
Type: `string` `Object` *(depending on `options.json`)*
|
|
@@ -489,7 +540,7 @@ The object contains the following properties:
|
|
|
489
540
|
- `download` - `timings.end - timings.response`
|
|
490
541
|
- `total` - `timings.end - timings.start` or `timings.error - timings.start`
|
|
491
542
|
|
|
492
|
-
**Note
|
|
543
|
+
**Note:** The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
|
|
493
544
|
|
|
494
545
|
##### fromCache
|
|
495
546
|
|
|
@@ -511,7 +562,7 @@ The number of times the request was retried.
|
|
|
511
562
|
|
|
512
563
|
#### Streams
|
|
513
564
|
|
|
514
|
-
**Note
|
|
565
|
+
**Note:** Progress events, redirect events and request/response events can also be used with promises.
|
|
515
566
|
|
|
516
567
|
#### got.stream(url, [options])
|
|
517
568
|
|
|
@@ -523,7 +574,7 @@ Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream
|
|
|
523
574
|
|
|
524
575
|
`request` event to get the request object of the request.
|
|
525
576
|
|
|
526
|
-
**Tip
|
|
577
|
+
**Tip:** You can use `request` event to abort request:
|
|
527
578
|
|
|
528
579
|
```js
|
|
529
580
|
got.stream('github.com')
|
|
@@ -626,7 +677,7 @@ client.get('/demo');
|
|
|
626
677
|
})();
|
|
627
678
|
```
|
|
628
679
|
|
|
629
|
-
|
|
680
|
+
**Tip:** Need more control over the behavior of Got? Check out the [`got.create()`](advanced-creation.md).
|
|
630
681
|
|
|
631
682
|
#### got.mergeOptions(parentOptions, newOptions)
|
|
632
683
|
|
|
@@ -658,7 +709,7 @@ The default Got options.
|
|
|
658
709
|
|
|
659
710
|
## Errors
|
|
660
711
|
|
|
661
|
-
Each error contains
|
|
712
|
+
Each error contains `host`, `hostname`, `method`, `path`, `protocol`, `url` and `gotOptions` properties to make debugging easier.
|
|
662
713
|
|
|
663
714
|
In Promise mode, the `response` is attached to the error.
|
|
664
715
|
|
|
@@ -676,15 +727,15 @@ When reading from response stream fails.
|
|
|
676
727
|
|
|
677
728
|
#### got.ParseError
|
|
678
729
|
|
|
679
|
-
When `json` option is enabled, server response code is 2xx, and `JSON.parse` fails.
|
|
730
|
+
When `json` option is enabled, server response code is 2xx, and `JSON.parse` fails. Includes `statusCode` and `statusMessage` properties.
|
|
680
731
|
|
|
681
732
|
#### got.HTTPError
|
|
682
733
|
|
|
683
|
-
When the server response code is not 2xx. Includes `statusCode`, `statusMessage`, and `redirectUrls` properties.
|
|
734
|
+
When the server response code is not 2xx. Includes `body`, `statusCode`, `statusMessage`, and `redirectUrls` properties.
|
|
684
735
|
|
|
685
736
|
#### got.MaxRedirectsError
|
|
686
737
|
|
|
687
|
-
When the server redirects you more than ten times. Includes a `redirectUrls` property
|
|
738
|
+
When the server redirects you more than ten times. Includes a `statusCode`, `statusMessage`, and `redirectUrls` property which is an array of the URLs Got was redirected to before giving up.
|
|
688
739
|
|
|
689
740
|
#### got.UnsupportedProtocolError
|
|
690
741
|
|
|
@@ -696,7 +747,7 @@ When the request is aborted with `.cancel()`.
|
|
|
696
747
|
|
|
697
748
|
#### got.TimeoutError
|
|
698
749
|
|
|
699
|
-
When the request is aborted due to a [timeout](#timeout)
|
|
750
|
+
When the request is aborted due to a [timeout](#timeout). Includes an `event` property.
|
|
700
751
|
|
|
701
752
|
## Aborting the request
|
|
702
753
|
|
|
@@ -1002,7 +1053,7 @@ const custom = got.extend({
|
|
|
1002
1053
|
})();
|
|
1003
1054
|
```
|
|
1004
1055
|
|
|
1005
|
-
|
|
1056
|
+
**Tip:** Need to merge some instances into a single one? Check out [`got.mergeInstances()`](advanced-creation.md#merging-instances).
|
|
1006
1057
|
|
|
1007
1058
|
### Experimental HTTP2 support
|
|
1008
1059
|
|
|
@@ -1022,86 +1073,147 @@ const h2got = got.extend({request});
|
|
|
1022
1073
|
|
|
1023
1074
|
## Comparison
|
|
1024
1075
|
|
|
1025
|
-
| |
|
|
1026
|
-
|
|
1027
|
-
| HTTP/2 support |
|
|
1028
|
-
| Browser support | ✖
|
|
1029
|
-
| Electron support |
|
|
1030
|
-
| Promise API | ✔
|
|
1031
|
-
| Stream API | ✔
|
|
1032
|
-
| Request cancelation |
|
|
1033
|
-
| RFC compliant caching |
|
|
1034
|
-
| Cookies (out-of-box) | ✔
|
|
1035
|
-
| Follows redirects | ✔
|
|
1036
|
-
| Retries on failure |
|
|
1037
|
-
| Progress events |
|
|
1038
|
-
| Handles gzip/deflate | ✔
|
|
1039
|
-
| Advanced timeouts |
|
|
1040
|
-
| Timings | ✔
|
|
1041
|
-
| Errors with metadata |
|
|
1042
|
-
| JSON mode | ✔
|
|
1043
|
-
| Custom defaults | ✔
|
|
1044
|
-
| Composable |
|
|
1045
|
-
| Hooks |
|
|
1046
|
-
| Issues open |
|
|
1047
|
-
| Issues closed |
|
|
1048
|
-
| Downloads |
|
|
1049
|
-
| Coverage |
|
|
1050
|
-
| Build |
|
|
1051
|
-
| Bugs |
|
|
1052
|
-
| Dependents |
|
|
1053
|
-
| Install size |
|
|
1076
|
+
| | `got` | [`request`][r0] | [`node-fetch`][n0] | [`axios`][a0] | [`superagent`][s0] |
|
|
1077
|
+
|-----------------------|:--------------:|:---------------:|:------------------:|:---------------:|:--------------------:|
|
|
1078
|
+
| HTTP/2 support | ❔ | ✖ | ✖ | ✖ | ✔\*\* |
|
|
1079
|
+
| Browser support | ✖ | ✖ | ✔\* | ✔ | ✔ |
|
|
1080
|
+
| Electron support | ✔ | ✖ | ✖ | ✖ | ✖ |
|
|
1081
|
+
| Promise API | ✔ | ✔ | ✔ | ✔ | ✔ |
|
|
1082
|
+
| Stream API | ✔ | ✔ | Node.js only | ✖ | ✔ |
|
|
1083
|
+
| Request cancelation | ✔ | ✖ | ✔ | ✔ | ✔ |
|
|
1084
|
+
| RFC compliant caching | ✔ | ✖ | ✖ | ✖ | ✖ |
|
|
1085
|
+
| Cookies (out-of-box) | ✔ | ✔ | ✖ | ✖ | ✖ |
|
|
1086
|
+
| Follows redirects | ✔ | ✔ | ✔ | ✔ | ✔ |
|
|
1087
|
+
| Retries on failure | ✔ | ✖ | ✖ | ✖ | ✔ |
|
|
1088
|
+
| Progress events | ✔ | ✖ | ✖ | Browser only | ✔ |
|
|
1089
|
+
| Handles gzip/deflate | ✔ | ✔ | ✔ | ✔ | ✔ |
|
|
1090
|
+
| Advanced timeouts | ✔ | ✖ | ✖ | ✖ | ✖ |
|
|
1091
|
+
| Timings | ✔ | ✔ | ✖ | ✖ | ✖ |
|
|
1092
|
+
| Errors with metadata | ✔ | ✖ | ✖ | ✔ | ✖ |
|
|
1093
|
+
| JSON mode | ✔ | ✔ | ✖ | ✔ | ✔ |
|
|
1094
|
+
| Custom defaults | ✔ | ✔ | ✖ | ✔ | ✖ |
|
|
1095
|
+
| Composable | ✔ | ✖ | ✖ | ✖ | ✔ |
|
|
1096
|
+
| Hooks | ✔ | ✖ | ✖ | ✔ | ✖ |
|
|
1097
|
+
| Issues open | [![][gio]][g1] | [![][rio]][r1] | [![][nio]][n1] | [![][aio]][a1] | [![][sio]][s1] |
|
|
1098
|
+
| Issues closed | [![][gic]][g2] | [![][ric]][r2] | [![][nic]][n2] | [![][aic]][a2] | [![][sic]][s2] |
|
|
1099
|
+
| Downloads | [![][gd]][g3] | [![][rd]][r3] | [![][nd]][n3] | [![][ad]][a3] | [![][sd]][s3] |
|
|
1100
|
+
| Coverage | [![][gc]][g4] | [![][rc]][r4] | [![][nc]][n4] | [![][ac]][a4] | unknown |
|
|
1101
|
+
| Build | [![][gb]][g5] | [![][rb]][r5] | [![][nb]][n5] | [![][ab]][a5] | [![][sb]][s5] |
|
|
1102
|
+
| Bugs | [![][gbg]][g6] | [![][rbg]][r6] | [![][nbg]][n6] | [![][abg]][a6] | [![][sbg]][s6] |
|
|
1103
|
+
| Dependents | [![][gdp]][g7] | [![][rdp]][r7] | [![][ndp]][n7] | [![][adp]][a7] | [![][sdp]][s7] |
|
|
1104
|
+
| Install size | [![][gis]][g8] | [![][ris]][r8] | [![][nis]][n8] | [![][ais]][a8] | [![][sis]][s8] |
|
|
1054
1105
|
|
|
1055
1106
|
\* It's almost API compatible with the browser `fetch` API.<br>
|
|
1107
|
+
\*\* Need to switch the protocol manually.<br>
|
|
1056
1108
|
❔ Experimental support.
|
|
1057
1109
|
|
|
1110
|
+
<!-- GITHUB -->
|
|
1111
|
+
[r0]: https://github.com/request/request
|
|
1112
|
+
[n0]: https://github.com/bitinn/node-fetch
|
|
1113
|
+
[a0]: https://github.com/axios/axios
|
|
1114
|
+
[s0]: https://github.com/visionmedia/superagent
|
|
1115
|
+
|
|
1058
1116
|
<!-- ISSUES OPEN -->
|
|
1059
|
-
[gio]: https://
|
|
1060
|
-
[rio]: https://
|
|
1061
|
-
[nio]: https://
|
|
1062
|
-
[aio]: https://
|
|
1117
|
+
[gio]: https://badgen.net/github/open-issues/sindresorhus/got?label
|
|
1118
|
+
[rio]: https://badgen.net/github/open-issues/request/request?label
|
|
1119
|
+
[nio]: https://badgen.net/github/open-issues/bitinn/node-fetch?label
|
|
1120
|
+
[aio]: https://badgen.net/github/open-issues/axios/axios?label
|
|
1121
|
+
[sio]: https://badgen.net/github/open-issues/visionmedia/superagent?label
|
|
1122
|
+
|
|
1123
|
+
[g1]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
|
|
1124
|
+
[r1]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
|
|
1125
|
+
[n1]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
|
|
1126
|
+
[a1]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
|
|
1127
|
+
[s1]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
|
|
1063
1128
|
|
|
1064
1129
|
<!-- ISSUES CLOSED -->
|
|
1065
|
-
[gic]: https://
|
|
1066
|
-
[ric]: https://
|
|
1067
|
-
[nic]: https://
|
|
1068
|
-
[aic]: https://
|
|
1130
|
+
[gic]: https://badgen.net/github/closed-issues/sindresorhus/got?label
|
|
1131
|
+
[ric]: https://badgen.net/github/closed-issues/request/request?label
|
|
1132
|
+
[nic]: https://badgen.net/github/closed-issues/bitinn/node-fetch?label
|
|
1133
|
+
[aic]: https://badgen.net/github/closed-issues/axios/axios?label
|
|
1134
|
+
[sic]: https://badgen.net/github/closed-issues/visionmedia/superagent?label
|
|
1135
|
+
|
|
1136
|
+
[g2]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
|
|
1137
|
+
[r2]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
|
|
1138
|
+
[n2]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
|
|
1139
|
+
[a2]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
|
|
1140
|
+
[s2]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc
|
|
1069
1141
|
|
|
1070
1142
|
<!-- DOWNLOADS -->
|
|
1071
|
-
[gd]: https://
|
|
1072
|
-
[rd]: https://
|
|
1073
|
-
[nd]: https://
|
|
1074
|
-
[ad]: https://
|
|
1143
|
+
[gd]: https://badgen.net/npm/dm/got?label
|
|
1144
|
+
[rd]: https://badgen.net/npm/dm/request?label
|
|
1145
|
+
[nd]: https://badgen.net/npm/dm/node-fetch?label
|
|
1146
|
+
[ad]: https://badgen.net/npm/dm/axios?label
|
|
1147
|
+
[sd]: https://badgen.net/npm/dm/superagent?label
|
|
1148
|
+
|
|
1149
|
+
[g3]: https://www.npmjs.com/package/got
|
|
1150
|
+
[r3]: https://www.npmjs.com/package/request
|
|
1151
|
+
[n3]: https://www.npmjs.com/package/node-fetch
|
|
1152
|
+
[a3]: https://www.npmjs.com/package/axios
|
|
1153
|
+
[s3]: https://www.npmjs.com/package/superagent
|
|
1075
1154
|
|
|
1076
1155
|
<!-- COVERAGE -->
|
|
1077
|
-
[gc]: https://
|
|
1078
|
-
[rc]: https://
|
|
1079
|
-
[nc]: https://
|
|
1080
|
-
[ac]: https://
|
|
1156
|
+
[gc]: https://badgen.net/coveralls/c/github/sindresorhus/got?label
|
|
1157
|
+
[rc]: https://badgen.net/coveralls/c/github/request/request?label
|
|
1158
|
+
[nc]: https://badgen.net/coveralls/c/github/bitinn/node-fetch?label
|
|
1159
|
+
[ac]: https://badgen.net/coveralls/c/github/mzabriskie/axios?label
|
|
1160
|
+
|
|
1161
|
+
[g4]: https://coveralls.io/github/sindresorhus/got
|
|
1162
|
+
[r4]: https://coveralls.io/github/request/request
|
|
1163
|
+
[n4]: https://coveralls.io/github/bitinn/node-fetch
|
|
1164
|
+
[a4]: https://coveralls.io/github/mzabriskie/axios
|
|
1081
1165
|
|
|
1082
1166
|
<!-- BUILD -->
|
|
1083
|
-
[gb]: https://
|
|
1084
|
-
[rb]: https://
|
|
1085
|
-
[nb]: https://
|
|
1086
|
-
[ab]: https://
|
|
1167
|
+
[gb]: https://badgen.net/travis/sindresorhus/got?label
|
|
1168
|
+
[rb]: https://badgen.net/travis/request/request?label
|
|
1169
|
+
[nb]: https://badgen.net/travis/bitinn/node-fetch?label
|
|
1170
|
+
[ab]: https://badgen.net/travis/axios/axios?label
|
|
1171
|
+
[sb]: https://badgen.net/travis/visionmedia/superagent?label
|
|
1172
|
+
|
|
1173
|
+
[g5]: https://travis-ci.org/sindresorhus/got
|
|
1174
|
+
[r5]: https://travis-ci.org/request/request
|
|
1175
|
+
[n5]: https://travis-ci.org/bitinn/node-fetch
|
|
1176
|
+
[a5]: https://travis-ci.org/axios/axios
|
|
1177
|
+
[s5]: https://travis-ci.org/visionmedia/superagent
|
|
1087
1178
|
|
|
1088
1179
|
<!-- BUGS -->
|
|
1089
|
-
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open
|
|
1090
|
-
[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open
|
|
1091
|
-
[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open
|
|
1092
|
-
[abg]: https://badgen.net/github/label-issues/axios/axios/bug/open
|
|
1180
|
+
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open?label
|
|
1181
|
+
[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open?label
|
|
1182
|
+
[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open?label
|
|
1183
|
+
[abg]: https://badgen.net/github/label-issues/axios/axios/bug/open?label
|
|
1184
|
+
[sbg]: https://badgen.net/github/label-issues/visionmedia/superagent/Bug/open?label
|
|
1185
|
+
|
|
1186
|
+
[g6]: https://github.com/sindresorhus/got/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
|
|
1187
|
+
[r6]: https://github.com/request/request/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A"Needs+investigation"
|
|
1188
|
+
[n6]: https://github.com/bitinn/node-fetch/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
|
|
1189
|
+
[a6]: https://github.com/axios/axios/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Abug
|
|
1190
|
+
[s6]: https://github.com/visionmedia/superagent/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3ABug
|
|
1093
1191
|
|
|
1094
1192
|
<!-- DEPENDENTS -->
|
|
1095
|
-
[gdp]: https://badgen.net/npm/dependents/got
|
|
1096
|
-
[rdp]: https://badgen.net/npm/dependents/request
|
|
1097
|
-
[ndp]: https://badgen.net/npm/dependents/node-fetch
|
|
1098
|
-
[adp]: https://badgen.net/npm/dependents/axios
|
|
1193
|
+
[gdp]: https://badgen.net/npm/dependents/got?label
|
|
1194
|
+
[rdp]: https://badgen.net/npm/dependents/request?label
|
|
1195
|
+
[ndp]: https://badgen.net/npm/dependents/node-fetch?label
|
|
1196
|
+
[adp]: https://badgen.net/npm/dependents/axios?label
|
|
1197
|
+
[sdp]: https://badgen.net/npm/dependents/superagent?label
|
|
1198
|
+
|
|
1199
|
+
[g7]: https://www.npmjs.com/package/got?activeTab=dependents
|
|
1200
|
+
[r7]: https://www.npmjs.com/package/request?activeTab=dependents
|
|
1201
|
+
[n7]: https://www.npmjs.com/package/node-fetch?activeTab=dependents
|
|
1202
|
+
[a7]: https://www.npmjs.com/package/axios?activeTab=dependents
|
|
1203
|
+
[s7]: https://www.npmjs.com/package/visionmedia?activeTab=dependents
|
|
1099
1204
|
|
|
1100
1205
|
<!-- INSTALL SIZE -->
|
|
1101
|
-
[gis]: https://
|
|
1102
|
-
[ris]: https://
|
|
1103
|
-
[nis]: https://
|
|
1104
|
-
[ais]: https://
|
|
1206
|
+
[gis]: https://badgen.net/packagephobia/install/got?label
|
|
1207
|
+
[ris]: https://badgen.net/packagephobia/install/request?label
|
|
1208
|
+
[nis]: https://badgen.net/packagephobia/install/node-fetch?label
|
|
1209
|
+
[ais]: https://badgen.net/packagephobia/install/axios?label
|
|
1210
|
+
[sis]: https://badgen.net/packagephobia/install/superagent?label
|
|
1211
|
+
|
|
1212
|
+
[g8]: https://packagephobia.now.sh/result?p=got
|
|
1213
|
+
[r8]: https://packagephobia.now.sh/result?p=request
|
|
1214
|
+
[n8]: https://packagephobia.now.sh/result?p=node-fetch
|
|
1215
|
+
[a8]: https://packagephobia.now.sh/result?p=axios
|
|
1216
|
+
[s8]: https://packagephobia.now.sh/result?p=superagent
|
|
1105
1217
|
|
|
1106
1218
|
|
|
1107
1219
|
## Related
|
package/source/as-promise.js
CHANGED
package/source/as-stream.js
CHANGED
package/source/errors.js
CHANGED
|
@@ -5,7 +5,7 @@ const PCancelable = require('p-cancelable');
|
|
|
5
5
|
const is = require('@sindresorhus/is');
|
|
6
6
|
|
|
7
7
|
class GotError extends Error {
|
|
8
|
-
constructor(message, error,
|
|
8
|
+
constructor(message, error, options) {
|
|
9
9
|
super(message);
|
|
10
10
|
Error.captureStackTrace(this, this.constructor);
|
|
11
11
|
this.name = 'GotError';
|
|
@@ -15,13 +15,14 @@ class GotError extends Error {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
Object.assign(this, {
|
|
18
|
-
host:
|
|
19
|
-
hostname:
|
|
20
|
-
method:
|
|
21
|
-
path:
|
|
22
|
-
socketPath:
|
|
23
|
-
protocol:
|
|
24
|
-
url:
|
|
18
|
+
host: options.host,
|
|
19
|
+
hostname: options.hostname,
|
|
20
|
+
method: options.method,
|
|
21
|
+
path: options.path,
|
|
22
|
+
socketPath: options.socketPath,
|
|
23
|
+
protocol: options.protocol,
|
|
24
|
+
url: options.href,
|
|
25
|
+
gotOptions: options
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
28
|
}
|
|
@@ -29,29 +30,29 @@ class GotError extends Error {
|
|
|
29
30
|
module.exports.GotError = GotError;
|
|
30
31
|
|
|
31
32
|
module.exports.CacheError = class extends GotError {
|
|
32
|
-
constructor(error,
|
|
33
|
-
super(error.message, error,
|
|
33
|
+
constructor(error, options) {
|
|
34
|
+
super(error.message, error, options);
|
|
34
35
|
this.name = 'CacheError';
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
|
|
38
39
|
module.exports.RequestError = class extends GotError {
|
|
39
|
-
constructor(error,
|
|
40
|
-
super(error.message, error,
|
|
40
|
+
constructor(error, options) {
|
|
41
|
+
super(error.message, error, options);
|
|
41
42
|
this.name = 'RequestError';
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
module.exports.ReadError = class extends GotError {
|
|
46
|
-
constructor(error,
|
|
47
|
-
super(error.message, error,
|
|
47
|
+
constructor(error, options) {
|
|
48
|
+
super(error.message, error, options);
|
|
48
49
|
this.name = 'ReadError';
|
|
49
50
|
}
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
module.exports.ParseError = class extends GotError {
|
|
53
|
-
constructor(error, statusCode,
|
|
54
|
-
super(`${error.message} in "${urlLib.format(
|
|
54
|
+
constructor(error, statusCode, options, data) {
|
|
55
|
+
super(`${error.message} in "${urlLib.format(options)}": \n${data.slice(0, 77)}...`, error, options);
|
|
55
56
|
this.name = 'ParseError';
|
|
56
57
|
this.statusCode = statusCode;
|
|
57
58
|
this.statusMessage = http.STATUS_CODES[this.statusCode];
|
|
@@ -59,7 +60,7 @@ module.exports.ParseError = class extends GotError {
|
|
|
59
60
|
};
|
|
60
61
|
|
|
61
62
|
module.exports.HTTPError = class extends GotError {
|
|
62
|
-
constructor(response,
|
|
63
|
+
constructor(response, options) {
|
|
63
64
|
const {statusCode} = response;
|
|
64
65
|
let {statusMessage} = response;
|
|
65
66
|
|
|
@@ -68,7 +69,8 @@ module.exports.HTTPError = class extends GotError {
|
|
|
68
69
|
} else {
|
|
69
70
|
statusMessage = http.STATUS_CODES[statusCode];
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
|
|
73
|
+
super(`Response code ${statusCode} (${statusMessage})`, {}, options);
|
|
72
74
|
this.name = 'HTTPError';
|
|
73
75
|
this.statusCode = statusCode;
|
|
74
76
|
this.statusMessage = statusMessage;
|
|
@@ -78,8 +80,8 @@ module.exports.HTTPError = class extends GotError {
|
|
|
78
80
|
};
|
|
79
81
|
|
|
80
82
|
module.exports.MaxRedirectsError = class extends GotError {
|
|
81
|
-
constructor(statusCode, redirectUrls,
|
|
82
|
-
super('Redirected 10 times. Aborting.', {},
|
|
83
|
+
constructor(statusCode, redirectUrls, options) {
|
|
84
|
+
super('Redirected 10 times. Aborting.', {}, options);
|
|
83
85
|
this.name = 'MaxRedirectsError';
|
|
84
86
|
this.statusCode = statusCode;
|
|
85
87
|
this.statusMessage = http.STATUS_CODES[this.statusCode];
|
|
@@ -88,15 +90,15 @@ module.exports.MaxRedirectsError = class extends GotError {
|
|
|
88
90
|
};
|
|
89
91
|
|
|
90
92
|
module.exports.UnsupportedProtocolError = class extends GotError {
|
|
91
|
-
constructor(
|
|
92
|
-
super(`Unsupported protocol "${
|
|
93
|
+
constructor(options) {
|
|
94
|
+
super(`Unsupported protocol "${options.protocol}"`, {}, options);
|
|
93
95
|
this.name = 'UnsupportedProtocolError';
|
|
94
96
|
}
|
|
95
97
|
};
|
|
96
98
|
|
|
97
99
|
module.exports.TimeoutError = class extends GotError {
|
|
98
|
-
constructor(error,
|
|
99
|
-
super(error.message, {code: 'ETIMEDOUT'},
|
|
100
|
+
constructor(error, options) {
|
|
101
|
+
super(error.message, {code: 'ETIMEDOUT'}, options);
|
|
100
102
|
this.name = 'TimeoutError';
|
|
101
103
|
this.event = error.event;
|
|
102
104
|
}
|
package/source/index.js
CHANGED
|
@@ -4,7 +4,6 @@ const urlLib = require('url');
|
|
|
4
4
|
const is = require('@sindresorhus/is');
|
|
5
5
|
const urlParseLax = require('url-parse-lax');
|
|
6
6
|
const lowercaseKeys = require('lowercase-keys');
|
|
7
|
-
const isRetryOnNetworkErrorAllowed = require('./utils/is-retry-on-network-error-allowed');
|
|
8
7
|
const urlToOptions = require('./utils/url-to-options');
|
|
9
8
|
const isFormData = require('./utils/is-form-data');
|
|
10
9
|
const merge = require('./merge');
|
|
@@ -12,8 +11,15 @@ const knownHookEvents = require('./known-hook-events');
|
|
|
12
11
|
|
|
13
12
|
const retryAfterStatusCodes = new Set([413, 429, 503]);
|
|
14
13
|
|
|
15
|
-
// `preNormalize` handles static
|
|
16
|
-
//
|
|
14
|
+
// `preNormalize` handles static options (e.g. headers).
|
|
15
|
+
// For example, when you create a custom instance and make a request
|
|
16
|
+
// with no static changes, they won't be normalized again.
|
|
17
|
+
//
|
|
18
|
+
// `normalize` operates on dynamic options - they cannot be saved.
|
|
19
|
+
// For example, `body` is everytime different per request.
|
|
20
|
+
// When it's done normalizing the new options, it performs merge()
|
|
21
|
+
// on the prenormalized options and the normalized ones.
|
|
22
|
+
|
|
17
23
|
const preNormalize = (options, defaults) => {
|
|
18
24
|
if (is.nullOrUndefined(options.headers)) {
|
|
19
25
|
options.headers = {};
|
|
@@ -50,13 +56,15 @@ const preNormalize = (options, defaults) => {
|
|
|
50
56
|
} else if (is.object(options.timeout)) {
|
|
51
57
|
options.gotTimeout = options.timeout;
|
|
52
58
|
}
|
|
59
|
+
|
|
53
60
|
delete options.timeout;
|
|
54
61
|
|
|
55
62
|
const {retry} = options;
|
|
56
63
|
options.retry = {
|
|
57
64
|
retries: 0,
|
|
58
65
|
methods: [],
|
|
59
|
-
statusCodes: []
|
|
66
|
+
statusCodes: [],
|
|
67
|
+
errorCodes: []
|
|
60
68
|
};
|
|
61
69
|
|
|
62
70
|
if (is.nonEmptyObject(defaults) && retry !== false) {
|
|
@@ -83,6 +91,10 @@ const preNormalize = (options, defaults) => {
|
|
|
83
91
|
options.retry.statusCodes = new Set(options.retry.statusCodes);
|
|
84
92
|
}
|
|
85
93
|
|
|
94
|
+
if (is.array(options.retry.errorCodes)) {
|
|
95
|
+
options.retry.errorCodes = new Set(options.retry.errorCodes);
|
|
96
|
+
}
|
|
97
|
+
|
|
86
98
|
return options;
|
|
87
99
|
};
|
|
88
100
|
|
|
@@ -96,7 +108,7 @@ const normalize = (url, options, defaults) => {
|
|
|
96
108
|
if (defaults) {
|
|
97
109
|
options = merge({}, defaults.options, options ? preNormalize(options, defaults.options) : {});
|
|
98
110
|
} else {
|
|
99
|
-
options = merge({},
|
|
111
|
+
options = merge({}, preNormalize(options));
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
if (!is.string(url) && !is.object(url)) {
|
|
@@ -112,11 +124,7 @@ const normalize = (url, options, defaults) => {
|
|
|
112
124
|
url = urlToOptions(new URL(url, options.baseUrl));
|
|
113
125
|
} else {
|
|
114
126
|
url = url.replace(/^unix:/, 'http://$&');
|
|
115
|
-
|
|
116
127
|
url = urlParseLax(url);
|
|
117
|
-
if (url.auth) {
|
|
118
|
-
throw new Error('Basic authentication must be done with the `auth` option');
|
|
119
|
-
}
|
|
120
128
|
}
|
|
121
129
|
} else if (is(url) === 'URL') {
|
|
122
130
|
url = urlToOptions(url);
|
|
@@ -125,6 +133,14 @@ const normalize = (url, options, defaults) => {
|
|
|
125
133
|
// Override both null/undefined with default protocol
|
|
126
134
|
options = merge({path: ''}, url, {protocol: url.protocol || 'https:'}, options);
|
|
127
135
|
|
|
136
|
+
for (const hook of options.hooks.init) {
|
|
137
|
+
const called = hook(options);
|
|
138
|
+
|
|
139
|
+
if (is.promise(called)) {
|
|
140
|
+
throw new TypeError('The `init` hook must be a synchronous function');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
128
144
|
const {baseUrl} = options;
|
|
129
145
|
Object.defineProperty(options, 'baseUrl', {
|
|
130
146
|
set: () => {
|
|
@@ -138,6 +154,7 @@ const normalize = (url, options, defaults) => {
|
|
|
138
154
|
if (!is.string(query)) {
|
|
139
155
|
options.query = (new URLSearchParams(query)).toString();
|
|
140
156
|
}
|
|
157
|
+
|
|
141
158
|
options.path = `${options.path.split('?')[0]}?${options.query}`;
|
|
142
159
|
delete options.query;
|
|
143
160
|
}
|
|
@@ -210,29 +227,27 @@ const normalize = (url, options, defaults) => {
|
|
|
210
227
|
return 0;
|
|
211
228
|
}
|
|
212
229
|
|
|
213
|
-
if (error
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (Reflect.has(error, 'headers') && Reflect.has(error.headers, 'retry-after') && retryAfterStatusCodes.has(error.statusCode)) {
|
|
219
|
-
let after = Number(error.headers['retry-after']);
|
|
220
|
-
if (is.nan(after)) {
|
|
221
|
-
after = Date.parse(error.headers['retry-after']) - Date.now();
|
|
222
|
-
} else {
|
|
223
|
-
after *= 1000;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (after > options.retry.maxRetryAfter) {
|
|
227
|
-
return 0;
|
|
228
|
-
}
|
|
230
|
+
if ((!error || !options.retry.errorCodes.has(error.code)) && (!options.retry.methods.has(error.method) || !options.retry.statusCodes.has(error.statusCode))) {
|
|
231
|
+
return 0;
|
|
232
|
+
}
|
|
229
233
|
|
|
230
|
-
|
|
234
|
+
if (Reflect.has(error, 'headers') && Reflect.has(error.headers, 'retry-after') && retryAfterStatusCodes.has(error.statusCode)) {
|
|
235
|
+
let after = Number(error.headers['retry-after']);
|
|
236
|
+
if (is.nan(after)) {
|
|
237
|
+
after = Date.parse(error.headers['retry-after']) - Date.now();
|
|
238
|
+
} else {
|
|
239
|
+
after *= 1000;
|
|
231
240
|
}
|
|
232
241
|
|
|
233
|
-
if (
|
|
242
|
+
if (after > options.retry.maxRetryAfter) {
|
|
234
243
|
return 0;
|
|
235
244
|
}
|
|
245
|
+
|
|
246
|
+
return after;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (error.statusCode === 413) {
|
|
250
|
+
return 0;
|
|
236
251
|
}
|
|
237
252
|
|
|
238
253
|
const noise = Math.random() * 100;
|
|
@@ -33,6 +33,19 @@ module.exports = (options, input) => {
|
|
|
33
33
|
const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
|
|
34
34
|
const agents = is.object(options.agent) ? options.agent : null;
|
|
35
35
|
|
|
36
|
+
const emitError = async error => {
|
|
37
|
+
try {
|
|
38
|
+
for (const hook of options.hooks.beforeError) {
|
|
39
|
+
// eslint-disable-next-line no-await-in-loop
|
|
40
|
+
error = await hook(error);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
emitter.emit('error', error);
|
|
44
|
+
} catch (error2) {
|
|
45
|
+
emitter.emit('error', error2);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
36
49
|
const get = async options => {
|
|
37
50
|
const currentUrl = redirectString || requestUrl;
|
|
38
51
|
|
|
@@ -92,6 +105,9 @@ module.exports = (options, input) => {
|
|
|
92
105
|
response.retryCount = retryCount;
|
|
93
106
|
response.timings = timings;
|
|
94
107
|
response.redirectUrls = redirects;
|
|
108
|
+
response.request = {
|
|
109
|
+
gotOptions: options
|
|
110
|
+
};
|
|
95
111
|
|
|
96
112
|
const rawCookies = response.headers['set-cookie'];
|
|
97
113
|
if (options.cookieJar && rawCookies) {
|
|
@@ -119,26 +135,26 @@ module.exports = (options, input) => {
|
|
|
119
135
|
|
|
120
136
|
redirects.push(redirectString);
|
|
121
137
|
|
|
122
|
-
const
|
|
138
|
+
const redirectOptions = {
|
|
123
139
|
...options,
|
|
124
140
|
...urlToOptions(redirectURL)
|
|
125
141
|
};
|
|
126
142
|
|
|
127
143
|
for (const hook of options.hooks.beforeRedirect) {
|
|
128
144
|
// eslint-disable-next-line no-await-in-loop
|
|
129
|
-
await hook(
|
|
145
|
+
await hook(redirectOptions);
|
|
130
146
|
}
|
|
131
147
|
|
|
132
|
-
emitter.emit('redirect', response,
|
|
148
|
+
emitter.emit('redirect', response, redirectOptions);
|
|
133
149
|
|
|
134
|
-
await get(
|
|
150
|
+
await get(redirectOptions);
|
|
135
151
|
return;
|
|
136
152
|
}
|
|
137
153
|
}
|
|
138
154
|
|
|
139
155
|
getResponse(response, options, emitter);
|
|
140
156
|
} catch (error) {
|
|
141
|
-
|
|
157
|
+
emitError(error);
|
|
142
158
|
}
|
|
143
159
|
};
|
|
144
160
|
|
|
@@ -163,7 +179,7 @@ module.exports = (options, input) => {
|
|
|
163
179
|
}
|
|
164
180
|
|
|
165
181
|
if (emitter.retry(error) === false) {
|
|
166
|
-
|
|
182
|
+
emitError(error);
|
|
167
183
|
}
|
|
168
184
|
});
|
|
169
185
|
|
|
@@ -195,29 +211,29 @@ module.exports = (options, input) => {
|
|
|
195
211
|
request.end(uploadComplete);
|
|
196
212
|
}
|
|
197
213
|
} catch (error) {
|
|
198
|
-
|
|
214
|
+
emitError(new RequestError(error, options));
|
|
199
215
|
}
|
|
200
216
|
};
|
|
201
217
|
|
|
202
218
|
if (options.cache) {
|
|
203
219
|
const cacheableRequest = new CacheableRequest(fn.request, options.cache);
|
|
204
|
-
const
|
|
220
|
+
const cacheRequest = cacheableRequest(options, handleResponse);
|
|
205
221
|
|
|
206
|
-
|
|
222
|
+
cacheRequest.once('error', error => {
|
|
207
223
|
if (error instanceof CacheableRequest.RequestError) {
|
|
208
|
-
|
|
224
|
+
emitError(new RequestError(error, options));
|
|
209
225
|
} else {
|
|
210
|
-
|
|
226
|
+
emitError(new CacheError(error, options));
|
|
211
227
|
}
|
|
212
228
|
});
|
|
213
229
|
|
|
214
|
-
|
|
230
|
+
cacheRequest.once('request', handleRequest);
|
|
215
231
|
} else {
|
|
216
232
|
// Catches errors thrown by calling fn.request(...)
|
|
217
233
|
try {
|
|
218
234
|
handleRequest(fn.request(options, handleResponse));
|
|
219
235
|
} catch (error) {
|
|
220
|
-
|
|
236
|
+
emitError(new RequestError(error, options));
|
|
221
237
|
}
|
|
222
238
|
}
|
|
223
239
|
};
|
|
@@ -228,7 +244,7 @@ module.exports = (options, input) => {
|
|
|
228
244
|
try {
|
|
229
245
|
backoff = options.retry.retries(++retryCount, error);
|
|
230
246
|
} catch (error2) {
|
|
231
|
-
|
|
247
|
+
emitError(error2);
|
|
232
248
|
return;
|
|
233
249
|
}
|
|
234
250
|
|
|
@@ -242,7 +258,7 @@ module.exports = (options, input) => {
|
|
|
242
258
|
|
|
243
259
|
await get(options);
|
|
244
260
|
} catch (error) {
|
|
245
|
-
|
|
261
|
+
emitError(error);
|
|
246
262
|
}
|
|
247
263
|
};
|
|
248
264
|
|
|
@@ -288,7 +304,7 @@ module.exports = (options, input) => {
|
|
|
288
304
|
|
|
289
305
|
await get(options);
|
|
290
306
|
} catch (error) {
|
|
291
|
-
|
|
307
|
+
emitError(error);
|
|
292
308
|
}
|
|
293
309
|
});
|
|
294
310
|
|
|
@@ -82,9 +82,16 @@ module.exports = (request, delays, options) => {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
if (delays.socket !== undefined) {
|
|
85
|
-
|
|
85
|
+
const socketTimeoutHandler = () => {
|
|
86
86
|
timeoutHandler(delays.socket, 'socket');
|
|
87
|
-
}
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
request.setTimeout(delays.socket, socketTimeoutHandler);
|
|
90
|
+
|
|
91
|
+
// `request.setTimeout(0)` causes a memory leak.
|
|
92
|
+
// We can just remove the listener and forget about the timer - it's unreffed.
|
|
93
|
+
// See https://github.com/sindresorhus/got/issues/690
|
|
94
|
+
cancelers.push(() => request.removeListener('timeout', socketTimeoutHandler));
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
if (delays.lookup !== undefined && !request.socketPath && !net.isIP(hostname || host)) {
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const WHITELIST = new Set([
|
|
4
|
-
'ETIMEDOUT',
|
|
5
|
-
'ECONNRESET',
|
|
6
|
-
'EADDRINUSE',
|
|
7
|
-
'ECONNREFUSED',
|
|
8
|
-
'EPIPE',
|
|
9
|
-
'ENOTFOUND',
|
|
10
|
-
'ENETUNREACH',
|
|
11
|
-
'EAI_AGAIN'
|
|
12
|
-
]);
|
|
13
|
-
|
|
14
|
-
module.exports = error => {
|
|
15
|
-
if (error && WHITELIST.has(error.code)) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return false;
|
|
20
|
-
};
|