got 9.2.1 → 9.3.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/package.json +15 -12
- package/readme.md +131 -13
- package/source/as-promise.js +40 -42
- package/source/as-stream.js +8 -31
- package/source/create.js +24 -14
- package/source/errors.js +9 -5
- package/source/get-response.js +4 -33
- package/source/index.js +15 -7
- package/source/known-hook-events.js +6 -1
- package/source/merge.js +41 -0
- package/source/normalize-arguments.js +123 -132
- package/source/progress.js +34 -5
- package/source/request-as-event-emitter.js +171 -109
- package/source/{deep-freeze.js → utils/deep-freeze.js} +0 -0
- package/source/{get-body-size.js → utils/get-body-size.js} +0 -4
- package/source/{is-form-data.js → utils/is-form-data.js} +0 -0
- package/source/{is-retry-on-network-error-allowed.js → utils/is-retry-on-network-error-allowed.js} +4 -1
- package/source/utils/timed-out.js +153 -0
- package/source/{url-to-options.js → utils/url-to-options.js} +0 -0
- package/source/merge-instances.js +0 -36
- package/source/timed-out.js +0 -160
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "got",
|
|
3
|
-
"version": "9.2
|
|
3
|
+
"version": "9.3.2",
|
|
4
4
|
"description": "Simplified HTTP requests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/got",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"node": ">=8.6"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"test": "xo && nyc ava"
|
|
12
|
+
"test": "xo && nyc ava",
|
|
13
|
+
"release": "np"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"source"
|
|
@@ -33,28 +34,30 @@
|
|
|
33
34
|
"electron"
|
|
34
35
|
],
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@sindresorhus/is": "^0.
|
|
37
|
+
"@sindresorhus/is": "^0.12.0",
|
|
37
38
|
"@szmarczak/http-timer": "^1.1.0",
|
|
38
|
-
"cacheable-request": "^5.
|
|
39
|
+
"cacheable-request": "^5.1.0",
|
|
39
40
|
"decompress-response": "^3.3.0",
|
|
40
41
|
"duplexer3": "^0.1.4",
|
|
41
|
-
"get-stream": "^4.
|
|
42
|
+
"get-stream": "^4.1.0",
|
|
43
|
+
"lowercase-keys": "^1.0.1",
|
|
42
44
|
"mimic-response": "^1.0.1",
|
|
43
|
-
"p-cancelable": "^0.
|
|
45
|
+
"p-cancelable": "^1.0.0",
|
|
44
46
|
"to-readable-stream": "^1.0.0",
|
|
45
47
|
"url-parse-lax": "^3.0.0"
|
|
46
48
|
},
|
|
47
49
|
"devDependencies": {
|
|
48
|
-
"ava": "1.0.0-
|
|
50
|
+
"ava": "1.0.0-rc.1",
|
|
49
51
|
"coveralls": "^3.0.0",
|
|
50
|
-
"delay": "^4.
|
|
51
|
-
"form-data": "^2.
|
|
52
|
+
"delay": "^4.1.0",
|
|
53
|
+
"form-data": "^2.3.3",
|
|
52
54
|
"get-port": "^4.0.0",
|
|
53
|
-
"
|
|
55
|
+
"np": "^3.0.4",
|
|
56
|
+
"nyc": "^13.1.0",
|
|
54
57
|
"p-event": "^2.1.0",
|
|
55
|
-
"pem": "^1.
|
|
58
|
+
"pem": "^1.13.2",
|
|
56
59
|
"proxyquire": "^2.0.1",
|
|
57
|
-
"sinon": "^
|
|
60
|
+
"sinon": "^7.1.0",
|
|
58
61
|
"slow-stream": "0.0.4",
|
|
59
62
|
"tempfile": "^2.0.0",
|
|
60
63
|
"tempy": "^0.2.1",
|
package/readme.md
CHANGED
|
@@ -35,9 +35,10 @@ 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
|
-
- [
|
|
38
|
+
- [Hooks](https://github.com/sindresorhus/got#hooks)
|
|
39
39
|
- [Instances with custom defaults](#instances)
|
|
40
40
|
- [Composable](advanced-creation.md#merging-instances)
|
|
41
|
+
- [Electron support](#useelectronnet)
|
|
41
42
|
- [Used by ~2000 packages and ~500K repos](https://github.com/sindresorhus/got/network/dependents)
|
|
42
43
|
- Actively maintained
|
|
43
44
|
|
|
@@ -120,7 +121,7 @@ Very useful when used with `got.extend()` to create niche-specific Got instances
|
|
|
120
121
|
|
|
121
122
|
Can be a string or a [WHATWG `URL`](https://nodejs.org/api/url.html#url_class_url).
|
|
122
123
|
|
|
123
|
-
|
|
124
|
+
Slash at the end of `baseUrl` and at the beginning of the `url` argument is optional:
|
|
124
125
|
|
|
125
126
|
```js
|
|
126
127
|
await got('hello', {baseUrl: 'https://example.com/v1'});
|
|
@@ -202,9 +203,36 @@ Parse response body with `JSON.parse` and set `accept` header to `application/js
|
|
|
202
203
|
|
|
203
204
|
###### query
|
|
204
205
|
|
|
205
|
-
Type: `string` `Object
|
|
206
|
+
Type: `string` `Object<string, string|number>` [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
|
|
207
|
+
|
|
208
|
+
Query string that will be added to the request URL. This will override the query string in `url`.
|
|
209
|
+
|
|
210
|
+
If you need to pass in an array, you can do it using a `URLSearchParams` instance:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
const got = require('got');
|
|
214
|
+
|
|
215
|
+
const query = new URLSearchParams([['key', 'a'], ['key', 'b']]);
|
|
216
|
+
|
|
217
|
+
got('https://example.com', {query});
|
|
218
|
+
|
|
219
|
+
console.log(query.toString());
|
|
220
|
+
//=> 'key=a&key=b'
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
And if you need a different array format, you could use the [`query-string`](https://github.com/sindresorhus/query-string) package:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const got = require('got');
|
|
227
|
+
const queryString = require('query-string');
|
|
228
|
+
|
|
229
|
+
const query = queryString.stringify({key: ['a', 'b']}, {arrayFormat: 'bracket'});
|
|
230
|
+
|
|
231
|
+
got('https://example.com', {query});
|
|
206
232
|
|
|
207
|
-
|
|
233
|
+
console.log(query);
|
|
234
|
+
//=> 'key[]=a&key[]=b'
|
|
235
|
+
```
|
|
208
236
|
|
|
209
237
|
###### timeout
|
|
210
238
|
|
|
@@ -236,7 +264,7 @@ An object representing `retries`, `methods`, `statusCodes` and `maxRetryAfter` f
|
|
|
236
264
|
If `maxRetryAfter` is set to `undefined`, it will use `options.timeout`.<br>
|
|
237
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.
|
|
238
266
|
|
|
239
|
-
Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from
|
|
267
|
+
Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 1).
|
|
240
268
|
|
|
241
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).
|
|
242
270
|
|
|
@@ -316,8 +344,7 @@ got('sindresorhus.com', {
|
|
|
316
344
|
|
|
317
345
|
###### hooks
|
|
318
346
|
|
|
319
|
-
Type: `Object<string, Function[]
|
|
320
|
-
Default: `{beforeRequest: []}`
|
|
347
|
+
Type: `Object<string, Function[]>`
|
|
321
348
|
|
|
322
349
|
Hooks allow modifications during the request lifecycle. Hook functions may be async and are run serially.
|
|
323
350
|
|
|
@@ -326,11 +353,96 @@ Hooks allow modifications during the request lifecycle. Hook functions may be as
|
|
|
326
353
|
Type: `Function[]`<br>
|
|
327
354
|
Default: `[]`
|
|
328
355
|
|
|
329
|
-
Called with
|
|
356
|
+
Called with [normalized](source/normalize-arguments.js) [request options](#options). Got will make no further changes to the request before it is sent. This is especially useful in conjunction with [`got.extend()`](#instances) and [`got.create()`](advanced-creation.md) when you want to create an API client that, for example, uses HMAC-signing.
|
|
330
357
|
|
|
331
358
|
See the [AWS section](#aws) for an example.
|
|
332
359
|
|
|
333
|
-
**Note**:
|
|
360
|
+
**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
|
+
|
|
362
|
+
###### hooks.beforeRedirect
|
|
363
|
+
|
|
364
|
+
Type: `Function[]`<br>
|
|
365
|
+
Default: `[]`
|
|
366
|
+
|
|
367
|
+
Called with [normalized](source/normalize-arguments.js) [request options](#options). Got will make no further changes to the request. This is especially useful when you want to avoid dead sites. Example:
|
|
368
|
+
|
|
369
|
+
```js
|
|
370
|
+
const got = require('got');
|
|
371
|
+
|
|
372
|
+
got('example.com', {
|
|
373
|
+
hooks: {
|
|
374
|
+
beforeRedirect: [
|
|
375
|
+
options => {
|
|
376
|
+
if (options.hostname === 'deadSite') {
|
|
377
|
+
options.hostname = 'fallbackSite';
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
]
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
###### hooks.beforeRetry
|
|
386
|
+
|
|
387
|
+
Type: `Function[]`<br>
|
|
388
|
+
Default: `[]`
|
|
389
|
+
|
|
390
|
+
Called with [normalized](source/normalize-arguments.js) [request options](#options), the error and the retry count. Got will make no further changes to the request. This is especially useful when some extra work is required before the next try. Example:
|
|
391
|
+
|
|
392
|
+
```js
|
|
393
|
+
const got = require('got');
|
|
394
|
+
|
|
395
|
+
got('example.com', {
|
|
396
|
+
hooks: {
|
|
397
|
+
beforeRetry: [
|
|
398
|
+
(options, error, retryCount) => {
|
|
399
|
+
if (error.statusCode === 413) { // Payload too large
|
|
400
|
+
options.body = getNewBody();
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
###### hooks.afterResponse
|
|
409
|
+
|
|
410
|
+
Type: `Function[]`<br>
|
|
411
|
+
Default: `[]`
|
|
412
|
+
|
|
413
|
+
Called with [response object](#response) and a retry function.
|
|
414
|
+
|
|
415
|
+
Each function should return the response. This is especially useful when you want to refresh an access token. Example:
|
|
416
|
+
|
|
417
|
+
```js
|
|
418
|
+
const got = require('got');
|
|
419
|
+
|
|
420
|
+
const instance = got.extend({
|
|
421
|
+
hooks: {
|
|
422
|
+
afterResponse: [
|
|
423
|
+
(response, retryWithMergedOptions) => {
|
|
424
|
+
if (response.statusCode === 401) { // Unauthorized
|
|
425
|
+
const updatedOptions = {
|
|
426
|
+
headers: {
|
|
427
|
+
token: getNewToken() // Refresh the access token
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// Save for further requests
|
|
432
|
+
instance.defaults.options = got.mergeOptions(instance.defaults.options, updatedOptions);
|
|
433
|
+
|
|
434
|
+
// Make a new retry
|
|
435
|
+
return retryWithMergedOptions(updatedOptions);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// No changes otherwise
|
|
439
|
+
return response;
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
mutableDefaults: true
|
|
444
|
+
});
|
|
445
|
+
```
|
|
334
446
|
|
|
335
447
|
#### Response
|
|
336
448
|
|
|
@@ -472,7 +584,7 @@ Sets `options.method` to the method name and makes a request.
|
|
|
472
584
|
|
|
473
585
|
#### got.extend([options])
|
|
474
586
|
|
|
475
|
-
Configure a new `got` instance with default `options`. `options` are merged with the parent instance's `defaults.options` using [`got.mergeOptions`](#gotmergeoptionsparentoptions-newoptions).
|
|
587
|
+
Configure a new `got` instance with default `options`. The `options` are merged with the parent instance's `defaults.options` using [`got.mergeOptions`](#gotmergeoptionsparentoptions-newoptions). You can access the resolved options with the `.defaults` property on the instance.
|
|
476
588
|
|
|
477
589
|
```js
|
|
478
590
|
const client = got.extend({
|
|
@@ -538,9 +650,15 @@ Options are deeply merged to a new object. The value of each key is determined a
|
|
|
538
650
|
- If the new property is an `Array`, it overwrites the old one with a deep clone of the new property.
|
|
539
651
|
- Otherwise, the new value is assigned to the key.
|
|
540
652
|
|
|
653
|
+
#### got.defaults
|
|
654
|
+
|
|
655
|
+
Type: `Object`
|
|
656
|
+
|
|
657
|
+
The default Got options.
|
|
658
|
+
|
|
541
659
|
## Errors
|
|
542
660
|
|
|
543
|
-
Each error contains (if available) `statusCode`, `statusMessage`, `host`, `hostname`, `method`, `path`, `protocol` and `url` properties to make debugging easier.
|
|
661
|
+
Each error contains (if available) `body`, `statusCode`, `statusMessage`, `host`, `hostname`, `method`, `path`, `protocol` and `url` properties to make debugging easier.
|
|
544
662
|
|
|
545
663
|
In Promise mode, the `response` is attached to the error.
|
|
546
664
|
|
|
@@ -670,7 +788,7 @@ You can use the [`tunnel`](https://github.com/koichik/node-tunnel) package with
|
|
|
670
788
|
|
|
671
789
|
```js
|
|
672
790
|
const got = require('got');
|
|
673
|
-
const tunnel = require('tunnel
|
|
791
|
+
const tunnel = require('tunnel');
|
|
674
792
|
|
|
675
793
|
got('sindresorhus.com', {
|
|
676
794
|
agent: tunnel.httpOverHttp({
|
|
@@ -910,7 +1028,7 @@ const h2got = got.extend({request});
|
|
|
910
1028
|
| Browser support | ✖ | ✖ | ✔* | ✔ |
|
|
911
1029
|
| Electron support | ✔ | ✖ | ✖ | ✖ |
|
|
912
1030
|
| Promise API | ✔ | ✔ | ✔ | ✔ |
|
|
913
|
-
| Stream API | ✔ | ✔ |
|
|
1031
|
+
| Stream API | ✔ | ✔ | Node.js only | ✖ |
|
|
914
1032
|
| Request cancelation | ✔ | ✖ | ✖ | ✔ |
|
|
915
1033
|
| RFC compliant caching | ✔ | ✖ | ✖ | ✖ |
|
|
916
1034
|
| Cookies (out-of-box) | ✔ | ✔ | ✖ | ✖ |
|
package/source/as-promise.js
CHANGED
|
@@ -5,43 +5,16 @@ const is = require('@sindresorhus/is');
|
|
|
5
5
|
const PCancelable = require('p-cancelable');
|
|
6
6
|
const requestAsEventEmitter = require('./request-as-event-emitter');
|
|
7
7
|
const {HTTPError, ParseError, ReadError} = require('./errors');
|
|
8
|
+
const {options: mergeOptions} = require('./merge');
|
|
9
|
+
const {reNormalize} = require('./normalize-arguments');
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
const asPromise = options => {
|
|
10
12
|
const proxy = new EventEmitter();
|
|
11
13
|
|
|
12
14
|
const promise = new PCancelable((resolve, reject, onCancel) => {
|
|
13
15
|
const emitter = requestAsEventEmitter(options);
|
|
14
|
-
let cancelOnRequest = false;
|
|
15
16
|
|
|
16
|
-
onCancel(
|
|
17
|
-
cancelOnRequest = true;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
emitter.on('request', request => {
|
|
21
|
-
if (cancelOnRequest) {
|
|
22
|
-
request.abort();
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
proxy.emit('request', request);
|
|
27
|
-
|
|
28
|
-
const uploadComplete = () => {
|
|
29
|
-
request.emit('upload-complete');
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
onCancel(() => {
|
|
33
|
-
request.abort();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
if (is.nodeStream(options.body)) {
|
|
37
|
-
options.body.once('end', uploadComplete);
|
|
38
|
-
options.body.pipe(request);
|
|
39
|
-
options.body = undefined;
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
request.end(options.body, uploadComplete);
|
|
44
|
-
});
|
|
17
|
+
onCancel(emitter.abort);
|
|
45
18
|
|
|
46
19
|
emitter.on('response', async response => {
|
|
47
20
|
proxy.emit('response', response);
|
|
@@ -56,11 +29,34 @@ module.exports = options => {
|
|
|
56
29
|
return;
|
|
57
30
|
}
|
|
58
31
|
|
|
59
|
-
const {statusCode} = response;
|
|
60
32
|
const limitStatusCode = options.followRedirect ? 299 : 399;
|
|
61
33
|
|
|
62
34
|
response.body = data;
|
|
63
35
|
|
|
36
|
+
try {
|
|
37
|
+
for (const [index, hook] of Object.entries(options.hooks.afterResponse)) {
|
|
38
|
+
// eslint-disable-next-line no-await-in-loop
|
|
39
|
+
response = await hook(response, updatedOptions => {
|
|
40
|
+
updatedOptions = reNormalize(mergeOptions(options, {
|
|
41
|
+
...updatedOptions,
|
|
42
|
+
retry: 0,
|
|
43
|
+
throwHttpErrors: false
|
|
44
|
+
}));
|
|
45
|
+
|
|
46
|
+
// Remove any further hooks for that request, because we we'll call them anyway.
|
|
47
|
+
// The loop continues. We don't want duplicates (asPromise recursion).
|
|
48
|
+
updatedOptions.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
|
|
49
|
+
|
|
50
|
+
return asPromise(updatedOptions);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
} catch (error) {
|
|
54
|
+
reject(error);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const {statusCode} = response;
|
|
59
|
+
|
|
64
60
|
if (options.json && response.body) {
|
|
65
61
|
try {
|
|
66
62
|
response.body = JSON.parse(response.body);
|
|
@@ -69,23 +65,22 @@ module.exports = options => {
|
|
|
69
65
|
const parseError = new ParseError(error, statusCode, options, data);
|
|
70
66
|
Object.defineProperty(parseError, 'response', {value: response});
|
|
71
67
|
reject(parseError);
|
|
68
|
+
return;
|
|
72
69
|
}
|
|
73
70
|
}
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
if (statusCode !== 304 && (statusCode < 200 || statusCode > limitStatusCode)) {
|
|
77
|
-
const error = new HTTPError(
|
|
74
|
+
const error = new HTTPError(response, options);
|
|
78
75
|
Object.defineProperty(error, 'response', {value: response});
|
|
79
|
-
emitter.
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
resolve(response);
|
|
76
|
+
if (emitter.retry(error) === false) {
|
|
77
|
+
if (options.throwHttpErrors) {
|
|
78
|
+
reject(error);
|
|
79
|
+
return;
|
|
87
80
|
}
|
|
88
|
-
|
|
81
|
+
|
|
82
|
+
resolve(response);
|
|
83
|
+
}
|
|
89
84
|
return;
|
|
90
85
|
}
|
|
91
86
|
|
|
@@ -94,6 +89,7 @@ module.exports = options => {
|
|
|
94
89
|
|
|
95
90
|
emitter.once('error', reject);
|
|
96
91
|
[
|
|
92
|
+
'request',
|
|
97
93
|
'redirect',
|
|
98
94
|
'uploadProgress',
|
|
99
95
|
'downloadProgress'
|
|
@@ -107,3 +103,5 @@ module.exports = options => {
|
|
|
107
103
|
|
|
108
104
|
return promise;
|
|
109
105
|
};
|
|
106
|
+
|
|
107
|
+
module.exports = asPromise;
|
package/source/as-stream.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
const {PassThrough} = require('stream');
|
|
3
3
|
const duplexer3 = require('duplexer3');
|
|
4
|
-
const is = require('@sindresorhus/is');
|
|
5
4
|
const requestAsEventEmitter = require('./request-as-event-emitter');
|
|
6
5
|
const {HTTPError, ReadError} = require('./errors');
|
|
7
6
|
|
|
@@ -12,7 +11,7 @@ module.exports = options => {
|
|
|
12
11
|
const piped = new Set();
|
|
13
12
|
let isFinished = false;
|
|
14
13
|
|
|
15
|
-
options.
|
|
14
|
+
options.retry.retries = () => 0;
|
|
16
15
|
|
|
17
16
|
if (options.body) {
|
|
18
17
|
proxy.write = () => {
|
|
@@ -20,33 +19,10 @@ module.exports = options => {
|
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
const emitter = requestAsEventEmitter(options);
|
|
22
|
+
const emitter = requestAsEventEmitter(options, input);
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const uploadComplete = () => {
|
|
28
|
-
request.emit('upload-complete');
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
if (is.nodeStream(options.body)) {
|
|
32
|
-
options.body.once('end', uploadComplete);
|
|
33
|
-
options.body.pipe(request);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (options.body) {
|
|
38
|
-
request.end(options.body, uploadComplete);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH') {
|
|
43
|
-
input.once('end', uploadComplete);
|
|
44
|
-
input.pipe(request);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
request.end(uploadComplete);
|
|
49
|
-
});
|
|
24
|
+
// Cancels the request
|
|
25
|
+
proxy._destroy = emitter.abort;
|
|
50
26
|
|
|
51
27
|
emitter.on('response', response => {
|
|
52
28
|
const {statusCode} = response;
|
|
@@ -56,7 +32,7 @@ module.exports = options => {
|
|
|
56
32
|
});
|
|
57
33
|
|
|
58
34
|
if (options.throwHttpErrors && statusCode !== 304 && (statusCode < 200 || statusCode > 299)) {
|
|
59
|
-
proxy.emit('error', new HTTPError(
|
|
35
|
+
proxy.emit('error', new HTTPError(response, options), null, response);
|
|
60
36
|
return;
|
|
61
37
|
}
|
|
62
38
|
|
|
@@ -70,8 +46,8 @@ module.exports = options => {
|
|
|
70
46
|
}
|
|
71
47
|
|
|
72
48
|
for (const [key, value] of Object.entries(response.headers)) {
|
|
73
|
-
// Got gives *
|
|
74
|
-
// It's not possible to decompress
|
|
49
|
+
// Got gives *decompressed* data. Overriding `content-encoding` header would result in an error.
|
|
50
|
+
// It's not possible to decompress already decompressed data, is it?
|
|
75
51
|
const allowed = options.decompress ? key !== 'content-encoding' : true;
|
|
76
52
|
if (allowed) {
|
|
77
53
|
destination.setHeader(key, value);
|
|
@@ -86,6 +62,7 @@ module.exports = options => {
|
|
|
86
62
|
|
|
87
63
|
[
|
|
88
64
|
'error',
|
|
65
|
+
'request',
|
|
89
66
|
'redirect',
|
|
90
67
|
'uploadProgress',
|
|
91
68
|
'downloadProgress'
|
package/source/create.js
CHANGED
|
@@ -4,11 +4,9 @@ const asStream = require('./as-stream');
|
|
|
4
4
|
const asPromise = require('./as-promise');
|
|
5
5
|
const normalizeArguments = require('./normalize-arguments');
|
|
6
6
|
const merge = require('./merge');
|
|
7
|
-
const deepFreeze = require('./deep-freeze');
|
|
8
|
-
const mergeInstances = require('./merge-instances');
|
|
7
|
+
const deepFreeze = require('./utils/deep-freeze');
|
|
9
8
|
|
|
10
9
|
const getPromiseOrStream = options => options.stream ? asStream(options) : asPromise(options);
|
|
11
|
-
const mergeOptions = (defaults, options = {}) => merge({}, defaults, options);
|
|
12
10
|
|
|
13
11
|
const aliases = [
|
|
14
12
|
'get',
|
|
@@ -21,7 +19,8 @@ const aliases = [
|
|
|
21
19
|
|
|
22
20
|
const create = defaults => {
|
|
23
21
|
defaults = merge({}, defaults);
|
|
24
|
-
|
|
22
|
+
normalizeArguments.preNormalize(defaults.options);
|
|
23
|
+
|
|
25
24
|
if (!defaults.handler) {
|
|
26
25
|
// This can't be getPromiseOrStream, because when merging
|
|
27
26
|
// the chain would stop at this point and no further handlers would be called.
|
|
@@ -41,12 +40,23 @@ const create = defaults => {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
got.create = create;
|
|
44
|
-
got.extend = options =>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
got.extend = options => {
|
|
44
|
+
let mutableDefaults;
|
|
45
|
+
if (options && Reflect.has(options, 'mutableDefaults')) {
|
|
46
|
+
mutableDefaults = options.mutableDefaults;
|
|
47
|
+
delete options.mutableDefaults;
|
|
48
|
+
} else {
|
|
49
|
+
mutableDefaults = defaults.mutableDefaults;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return create({
|
|
53
|
+
options: merge.options(defaults.options, options),
|
|
54
|
+
handler: defaults.handler,
|
|
55
|
+
mutableDefaults
|
|
56
|
+
});
|
|
57
|
+
};
|
|
48
58
|
|
|
49
|
-
got.mergeInstances = (...args) => create(
|
|
59
|
+
got.mergeInstances = (...args) => create(merge.instances(args));
|
|
50
60
|
|
|
51
61
|
got.stream = (url, options) => got(url, {...options, stream: true});
|
|
52
62
|
|
|
@@ -55,12 +65,12 @@ const create = defaults => {
|
|
|
55
65
|
got.stream[method] = (url, options) => got.stream(url, {...options, method});
|
|
56
66
|
}
|
|
57
67
|
|
|
58
|
-
Object.assign(got, {...errors, mergeOptions});
|
|
68
|
+
Object.assign(got, {...errors, mergeOptions: merge.options});
|
|
59
69
|
Object.defineProperty(got, 'defaults', {
|
|
60
|
-
value: deepFreeze(defaults),
|
|
61
|
-
writable:
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
value: defaults.mutableDefaults ? defaults : deepFreeze(defaults),
|
|
71
|
+
writable: defaults.mutableDefaults,
|
|
72
|
+
configurable: defaults.mutableDefaults,
|
|
73
|
+
enumerable: true
|
|
64
74
|
});
|
|
65
75
|
|
|
66
76
|
return got;
|
package/source/errors.js
CHANGED
|
@@ -59,7 +59,10 @@ module.exports.ParseError = class extends GotError {
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
module.exports.HTTPError = class extends GotError {
|
|
62
|
-
constructor(
|
|
62
|
+
constructor(response, opts) {
|
|
63
|
+
const {statusCode} = response;
|
|
64
|
+
let {statusMessage} = response;
|
|
65
|
+
|
|
63
66
|
if (statusMessage) {
|
|
64
67
|
statusMessage = statusMessage.replace(/\r?\n/g, ' ').trim();
|
|
65
68
|
} else {
|
|
@@ -69,7 +72,8 @@ module.exports.HTTPError = class extends GotError {
|
|
|
69
72
|
this.name = 'HTTPError';
|
|
70
73
|
this.statusCode = statusCode;
|
|
71
74
|
this.statusMessage = statusMessage;
|
|
72
|
-
this.headers = headers;
|
|
75
|
+
this.headers = response.headers;
|
|
76
|
+
this.body = response.body;
|
|
73
77
|
}
|
|
74
78
|
};
|
|
75
79
|
|
|
@@ -91,10 +95,10 @@ module.exports.UnsupportedProtocolError = class extends GotError {
|
|
|
91
95
|
};
|
|
92
96
|
|
|
93
97
|
module.exports.TimeoutError = class extends GotError {
|
|
94
|
-
constructor(
|
|
95
|
-
super(
|
|
98
|
+
constructor(error, opts) {
|
|
99
|
+
super(error.message, {code: 'ETIMEDOUT'}, opts);
|
|
96
100
|
this.name = 'TimeoutError';
|
|
97
|
-
this.event = event;
|
|
101
|
+
this.event = error.event;
|
|
98
102
|
}
|
|
99
103
|
};
|
|
100
104
|
|
package/source/get-response.js
CHANGED
|
@@ -1,44 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const {Transform} = require('stream');
|
|
3
2
|
const decompressResponse = require('decompress-response');
|
|
4
3
|
const is = require('@sindresorhus/is');
|
|
5
4
|
const mimicResponse = require('mimic-response');
|
|
5
|
+
const progress = require('./progress');
|
|
6
6
|
|
|
7
|
-
module.exports = (response, options, emitter
|
|
7
|
+
module.exports = (response, options, emitter) => {
|
|
8
8
|
const downloadBodySize = Number(response.headers['content-length']) || null;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const progressStream = new Transform({
|
|
12
|
-
transform(chunk, encoding, callback) {
|
|
13
|
-
downloaded += chunk.length;
|
|
14
|
-
|
|
15
|
-
const percent = downloadBodySize ? downloaded / downloadBodySize : 0;
|
|
16
|
-
|
|
17
|
-
// Let `flush()` be responsible for emitting the last event
|
|
18
|
-
if (percent < 1) {
|
|
19
|
-
emitter.emit('downloadProgress', {
|
|
20
|
-
percent,
|
|
21
|
-
transferred: downloaded,
|
|
22
|
-
total: downloadBodySize
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
callback(null, chunk);
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
flush(callback) {
|
|
30
|
-
emitter.emit('downloadProgress', {
|
|
31
|
-
percent: 1,
|
|
32
|
-
transferred: downloaded,
|
|
33
|
-
total: downloadBodySize
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
callback();
|
|
37
|
-
}
|
|
38
|
-
});
|
|
9
|
+
|
|
10
|
+
const progressStream = progress.download(response, emitter, downloadBodySize);
|
|
39
11
|
|
|
40
12
|
mimicResponse(response, progressStream);
|
|
41
|
-
progressStream.redirectUrls = redirects;
|
|
42
13
|
|
|
43
14
|
const newResponse = options.decompress === true &&
|
|
44
15
|
is.function(decompressResponse) &&
|
package/source/index.js
CHANGED
|
@@ -24,17 +24,25 @@ const defaults = {
|
|
|
24
24
|
504
|
|
25
25
|
]
|
|
26
26
|
},
|
|
27
|
-
cache: false,
|
|
28
|
-
decompress: true,
|
|
29
|
-
useElectronNet: false,
|
|
30
|
-
throwHttpErrors: true,
|
|
31
27
|
headers: {
|
|
32
28
|
'user-agent': `${pkg.name}/${pkg.version} (https://github.com/sindresorhus/got)`
|
|
33
29
|
},
|
|
34
30
|
hooks: {
|
|
35
|
-
beforeRequest: []
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
beforeRequest: [],
|
|
32
|
+
beforeRedirect: [],
|
|
33
|
+
beforeRetry: [],
|
|
34
|
+
afterResponse: []
|
|
35
|
+
},
|
|
36
|
+
decompress: true,
|
|
37
|
+
throwHttpErrors: true,
|
|
38
|
+
followRedirect: true,
|
|
39
|
+
stream: false,
|
|
40
|
+
form: false,
|
|
41
|
+
json: false,
|
|
42
|
+
cache: false,
|
|
43
|
+
useElectronNet: false
|
|
44
|
+
},
|
|
45
|
+
mutableDefaults: false
|
|
38
46
|
};
|
|
39
47
|
|
|
40
48
|
const got = create(defaults);
|