got 5.5.0 → 5.7.1
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/index.js +35 -20
- package/package.json +10 -9
- package/readme.md +62 -5
package/index.js
CHANGED
|
@@ -18,7 +18,6 @@ var PinkiePromise = require('pinkie-promise');
|
|
|
18
18
|
var unzipResponse = require('unzip-response');
|
|
19
19
|
var createErrorClass = require('create-error-class');
|
|
20
20
|
var nodeStatusCodes = require('node-status-codes');
|
|
21
|
-
var isPlainObj = require('is-plain-obj');
|
|
22
21
|
var parseJson = require('parse-json');
|
|
23
22
|
var isRetryAllowed = require('is-retry-allowed');
|
|
24
23
|
var pkg = require('./package.json');
|
|
@@ -27,8 +26,10 @@ function requestAsEventEmitter(opts) {
|
|
|
27
26
|
opts = opts || {};
|
|
28
27
|
|
|
29
28
|
var ee = new EventEmitter();
|
|
29
|
+
var requestUrl = opts.href || urlLib.resolve(urlLib.format(opts), opts.path);
|
|
30
30
|
var redirectCount = 0;
|
|
31
31
|
var retryCount = 0;
|
|
32
|
+
var redirectUrl;
|
|
32
33
|
|
|
33
34
|
var get = function (opts) {
|
|
34
35
|
var fn = opts.protocol === 'https:' ? https : http;
|
|
@@ -36,7 +37,7 @@ function requestAsEventEmitter(opts) {
|
|
|
36
37
|
var req = fn.request(opts, function (res) {
|
|
37
38
|
var statusCode = res.statusCode;
|
|
38
39
|
|
|
39
|
-
if (isRedirect(statusCode) && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) {
|
|
40
|
+
if (isRedirect(statusCode) && opts.followRedirect && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) {
|
|
40
41
|
res.resume();
|
|
41
42
|
|
|
42
43
|
if (++redirectCount > 10) {
|
|
@@ -44,7 +45,7 @@ function requestAsEventEmitter(opts) {
|
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
redirectUrl = urlLib.resolve(urlLib.format(opts), res.headers.location);
|
|
48
49
|
var redirectOpts = objectAssign({}, opts, urlLib.parse(redirectUrl));
|
|
49
50
|
|
|
50
51
|
ee.emit('redirect', res, redirectOpts);
|
|
@@ -55,7 +56,11 @@ function requestAsEventEmitter(opts) {
|
|
|
55
56
|
|
|
56
57
|
// do not write ee.bind(...) instead of function - it will break gzip in Node.js 0.10
|
|
57
58
|
setImmediate(function () {
|
|
58
|
-
|
|
59
|
+
var response = typeof unzipResponse === 'function' && req.method !== 'HEAD' ? unzipResponse(res) : res;
|
|
60
|
+
response.url = redirectUrl || requestUrl;
|
|
61
|
+
response.requestUrl = requestUrl;
|
|
62
|
+
|
|
63
|
+
ee.emit('response', response);
|
|
59
64
|
});
|
|
60
65
|
});
|
|
61
66
|
|
|
@@ -94,28 +99,29 @@ function asCallback(opts, cb) {
|
|
|
94
99
|
});
|
|
95
100
|
|
|
96
101
|
ee.on('response', function (res) {
|
|
97
|
-
readAllStream(res, opts.encoding, function (
|
|
102
|
+
readAllStream(res, opts.encoding, function (error, data) {
|
|
98
103
|
var statusCode = res.statusCode;
|
|
104
|
+
var limitStatusCode = opts.followRedirect ? 299 : 399;
|
|
99
105
|
|
|
100
|
-
if (
|
|
101
|
-
cb(new got.ReadError(
|
|
106
|
+
if (error) {
|
|
107
|
+
cb(new got.ReadError(error, opts), null, res);
|
|
102
108
|
return;
|
|
103
109
|
}
|
|
104
110
|
|
|
105
|
-
if (statusCode < 200 || statusCode >
|
|
106
|
-
|
|
111
|
+
if (statusCode < 200 || statusCode > limitStatusCode) {
|
|
112
|
+
error = new got.HTTPError(statusCode, opts);
|
|
107
113
|
}
|
|
108
114
|
|
|
109
115
|
if (opts.json && data) {
|
|
110
116
|
try {
|
|
111
117
|
data = parseJson(data);
|
|
112
|
-
} catch (
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
} catch (err) {
|
|
119
|
+
err.fileName = urlLib.format(opts);
|
|
120
|
+
error = new got.ParseError(err, statusCode, opts);
|
|
115
121
|
}
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
cb(
|
|
124
|
+
cb(error, data, res);
|
|
119
125
|
});
|
|
120
126
|
});
|
|
121
127
|
|
|
@@ -183,10 +189,11 @@ function asStream(opts) {
|
|
|
183
189
|
|
|
184
190
|
ee.on('response', function (res) {
|
|
185
191
|
var statusCode = res.statusCode;
|
|
192
|
+
var limitStatusCode = opts.followRedirect ? 299 : 399;
|
|
186
193
|
|
|
187
194
|
res.pipe(output);
|
|
188
195
|
|
|
189
|
-
if (statusCode < 200 || statusCode >
|
|
196
|
+
if (statusCode < 200 || statusCode > limitStatusCode) {
|
|
190
197
|
proxy.emit('error', new got.HTTPError(statusCode, opts), null, res);
|
|
191
198
|
return;
|
|
192
199
|
}
|
|
@@ -207,6 +214,7 @@ function normalizeArguments(url, opts) {
|
|
|
207
214
|
}
|
|
208
215
|
|
|
209
216
|
if (typeof url === 'string') {
|
|
217
|
+
url = url.replace(/^unix:/, 'http://$&');
|
|
210
218
|
url = urlParseLax(url);
|
|
211
219
|
|
|
212
220
|
if (url.auth) {
|
|
@@ -243,13 +251,16 @@ function normalizeArguments(url, opts) {
|
|
|
243
251
|
var body = opts.body;
|
|
244
252
|
|
|
245
253
|
if (body) {
|
|
246
|
-
if (typeof body !== 'string' && !
|
|
254
|
+
if (typeof body !== 'string' && !(body !== null && typeof body === 'object')) {
|
|
247
255
|
throw new Error('options.body must be a ReadableStream, string, Buffer or plain Object');
|
|
248
256
|
}
|
|
249
257
|
|
|
250
258
|
opts.method = opts.method || 'POST';
|
|
251
259
|
|
|
252
|
-
if (
|
|
260
|
+
if (isStream(body) && typeof body.getBoundary === 'function') {
|
|
261
|
+
// Special case for https://github.com/form-data/form-data
|
|
262
|
+
opts.headers['content-type'] = opts.headers['content-type'] || 'multipart/form-data; boundary=' + body.getBoundary();
|
|
263
|
+
} else if (body !== null && typeof body === 'object' && !Buffer.isBuffer(body) && !isStream(body)) {
|
|
253
264
|
opts.headers['content-type'] = opts.headers['content-type'] || 'application/x-www-form-urlencoded';
|
|
254
265
|
body = opts.body = querystring.stringify(body);
|
|
255
266
|
}
|
|
@@ -265,7 +276,7 @@ function normalizeArguments(url, opts) {
|
|
|
265
276
|
opts.method = opts.method.toUpperCase();
|
|
266
277
|
|
|
267
278
|
if (opts.hostname === 'unix') {
|
|
268
|
-
var matches = /(.+)
|
|
279
|
+
var matches = /(.+):(.+)/.exec(opts.path);
|
|
269
280
|
|
|
270
281
|
if (matches) {
|
|
271
282
|
opts.socketPath = matches[1];
|
|
@@ -282,10 +293,14 @@ function normalizeArguments(url, opts) {
|
|
|
282
293
|
}
|
|
283
294
|
|
|
284
295
|
var noise = Math.random() * 100;
|
|
285
|
-
return (1 << iter) * 1000 + noise;
|
|
296
|
+
return ((1 << iter) * 1000) + noise;
|
|
286
297
|
};
|
|
287
298
|
}
|
|
288
299
|
|
|
300
|
+
if (opts.followRedirect === undefined) {
|
|
301
|
+
opts.followRedirect = true;
|
|
302
|
+
}
|
|
303
|
+
|
|
289
304
|
return opts;
|
|
290
305
|
}
|
|
291
306
|
|
|
@@ -302,8 +317,8 @@ function got(url, opts, cb) {
|
|
|
302
317
|
|
|
303
318
|
try {
|
|
304
319
|
return asPromise(normalizeArguments(url, opts));
|
|
305
|
-
} catch (
|
|
306
|
-
return PinkiePromise.reject(
|
|
320
|
+
} catch (err) {
|
|
321
|
+
return PinkiePromise.reject(err);
|
|
307
322
|
}
|
|
308
323
|
}
|
|
309
324
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "got",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.1",
|
|
4
4
|
"description": "Simplified HTTP/HTTPS requests",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/got",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
19
|
"engines": {
|
|
20
|
-
"node": ">=0.10.0"
|
|
20
|
+
"node": ">=0.10.0 <7"
|
|
21
21
|
},
|
|
22
22
|
"browser": {
|
|
23
23
|
"unzip-response": false
|
|
@@ -45,9 +45,8 @@
|
|
|
45
45
|
"fetch"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"create-error-class": "^
|
|
48
|
+
"create-error-class": "^3.0.1",
|
|
49
49
|
"duplexer2": "^0.1.4",
|
|
50
|
-
"is-plain-obj": "^1.0.0",
|
|
51
50
|
"is-redirect": "^1.0.0",
|
|
52
51
|
"is-retry-allowed": "^1.0.0",
|
|
53
52
|
"is-stream": "^1.0.0",
|
|
@@ -58,20 +57,22 @@
|
|
|
58
57
|
"pinkie-promise": "^2.0.0",
|
|
59
58
|
"read-all-stream": "^3.0.0",
|
|
60
59
|
"readable-stream": "^2.0.5",
|
|
61
|
-
"timed-out": "^
|
|
62
|
-
"unzip-response": "^1.0.
|
|
60
|
+
"timed-out": "^3.0.0",
|
|
61
|
+
"unzip-response": "^1.0.2",
|
|
63
62
|
"url-parse-lax": "^1.0.0"
|
|
64
63
|
},
|
|
65
64
|
"devDependencies": {
|
|
66
|
-
"ava": "^0.
|
|
65
|
+
"ava": "^0.16.0",
|
|
67
66
|
"coveralls": "^2.11.4",
|
|
67
|
+
"form-data": "^2.1.1",
|
|
68
68
|
"get-port": "^2.0.0",
|
|
69
|
+
"get-stream": "^2.3.0",
|
|
69
70
|
"into-stream": "^2.0.0",
|
|
70
|
-
"nyc": "^
|
|
71
|
+
"nyc": "^8.1.0",
|
|
71
72
|
"pem": "^1.4.4",
|
|
72
73
|
"pify": "^2.3.0",
|
|
73
74
|
"tempfile": "^1.1.1",
|
|
74
|
-
"xo": "
|
|
75
|
+
"xo": "0.16.x"
|
|
75
76
|
},
|
|
76
77
|
"xo": {
|
|
77
78
|
"ignores": [
|
package/readme.md
CHANGED
|
@@ -60,6 +60,10 @@ It's a `GET` request by default, but can be changed in `options`.
|
|
|
60
60
|
|
|
61
61
|
#### got(url, [options], [callback])
|
|
62
62
|
|
|
63
|
+
Returns a Promise for a `response` object with a `body` property, a `url` property with the request URL or the final URL after redirects, and a `requestUrl` property with the original request URL.
|
|
64
|
+
|
|
65
|
+
Otherwise calls callback with `response` object (same as in previous case).
|
|
66
|
+
|
|
63
67
|
##### url
|
|
64
68
|
|
|
65
69
|
Type: `string`, `object`
|
|
@@ -121,12 +125,19 @@ Milliseconds after which the request will be aborted and an error event with `ET
|
|
|
121
125
|
Type: `number`, `function`
|
|
122
126
|
Default: `5`
|
|
123
127
|
|
|
124
|
-
Number of request retries when network errors happens. Delays between retries counts with function `Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 0).
|
|
125
|
-
|
|
126
|
-
**Note:** `ENOTFOUND` and `ENETUNREACH` error will not be retried (see full list in [`is-retry-allowed`](https://github.com/floatdrop/is-retry-allowed/blob/master/index.js#L12) module).
|
|
128
|
+
Number of request retries when network errors happens. Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 0).
|
|
127
129
|
|
|
128
130
|
Option accepts `function` with `retry` and `error` arguments. Function must return delay in milliseconds (`0` return value cancels retry).
|
|
129
131
|
|
|
132
|
+
**Note:** if `retries` is `number`, `ENOTFOUND` and `ENETUNREACH` error will not be retried (see full list in [`is-retry-allowed`](https://github.com/floatdrop/is-retry-allowed/blob/master/index.js#L12) module).
|
|
133
|
+
|
|
134
|
+
###### followRedirect
|
|
135
|
+
|
|
136
|
+
Type: `boolean`<br>
|
|
137
|
+
Default: `true`
|
|
138
|
+
|
|
139
|
+
Defines if redirect responses should be followed automatically.
|
|
140
|
+
|
|
130
141
|
##### callback(error, data, response)
|
|
131
142
|
|
|
132
143
|
Function to be called when error or data are received. If omitted, a promise will be returned.
|
|
@@ -135,8 +146,6 @@ Function to be called when error or data are received. If omitted, a promise wil
|
|
|
135
146
|
|
|
136
147
|
`Error` object with HTTP status code as `statusCode` property.
|
|
137
148
|
|
|
138
|
-
###### data
|
|
139
|
-
|
|
140
149
|
The data you requested.
|
|
141
150
|
|
|
142
151
|
###### response
|
|
@@ -239,6 +248,54 @@ got('google.com', {
|
|
|
239
248
|
```
|
|
240
249
|
|
|
241
250
|
|
|
251
|
+
## Form data
|
|
252
|
+
|
|
253
|
+
You can use the [`form-data`](https://github.com/form-data/form-data) module to create POST request with form data:
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
const fs = require('fs');
|
|
257
|
+
const got = require('got');
|
|
258
|
+
const FormData = require('form-data');
|
|
259
|
+
const form = new FormData();
|
|
260
|
+
|
|
261
|
+
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
|
|
262
|
+
|
|
263
|
+
got.post('google.com', {
|
|
264
|
+
body: form
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
## OAuth
|
|
270
|
+
|
|
271
|
+
You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) module to create a signed OAuth request:
|
|
272
|
+
|
|
273
|
+
```js
|
|
274
|
+
const got = require('got');
|
|
275
|
+
const OAuth = require('oauth-1.0a');
|
|
276
|
+
|
|
277
|
+
const oauth = OAuth({
|
|
278
|
+
consumer: {
|
|
279
|
+
public: process.env.CONSUMER_KEY,
|
|
280
|
+
secret: process.env.CONSUMER_SECRET
|
|
281
|
+
},
|
|
282
|
+
signature_method: 'HMAC-SHA1'
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const token = {
|
|
286
|
+
public: process.env.ACCESS_TOKEN,
|
|
287
|
+
secret: process.env.ACCESS_TOKEN_SECRET
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
|
|
291
|
+
|
|
292
|
+
got(url, {
|
|
293
|
+
headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
|
|
294
|
+
json: true
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
|
|
242
299
|
## Unix Domain Sockets
|
|
243
300
|
|
|
244
301
|
Requests can also be sent via [unix domain sockets](http://serverfault.com/questions/124517/whats-the-difference-between-unix-socket-and-tcp-ip-socket). Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`.
|