Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

got

Package Overview
Dependencies
Maintainers
5
Versions
178
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

got - npm Package Compare versions

Comparing version 9.1.0 to 9.2.0

4

package.json
{
"name": "got",
"version": "9.1.0",
"version": "9.2.0",
"description": "Simplified HTTP requests",

@@ -38,2 +38,3 @@ "license": "MIT",

"@sindresorhus/is": "^0.11.0",
"@szmarczak/http-timer": "^1.1.0",
"cacheable-request": "^4.0.1",

@@ -62,2 +63,3 @@ "decompress-response": "^3.3.0",

"tempy": "^0.2.1",
"tough-cookie": "^2.4.3",
"xo": "^0.22.0"

@@ -64,0 +66,0 @@ },

@@ -92,8 +92,4 @@ <div align="center">

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.
Returns a Promise for a [`response` object](#response) or a [stream](#streams-1) if `options.stream` is set to true.
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.
The response will also have a `fromCache` property set with a boolean value.
##### url

@@ -167,2 +163,10 @@

###### cookieJar
Type: [`tough.CookieJar` instance](https://github.com/salesforce/tough-cookie#cookiejar)
Cookie support. You don't have to care about parsing or how to store them. [Example.](#cookies)
**Note:** `options.headers.cookie` will be overridden.
###### encoding

@@ -271,2 +275,9 @@

###### request
Type: `Function`<br>
Default: `http.request` `https.request` *(depending on the protocol)*
Custom request function. The main purpose of this is to [support HTTP2 using a wrapper](#experimental-http2-support).
###### useElectronNet

@@ -288,2 +299,21 @@

###### agent
Same as the [`agent` option](https://nodejs.org/api/http.html#http_http_request_url_options_callback) for `http.request`, but with an extra feature:
If you require different agents for different protocols, you can pass a map of agents to the `agent` option. This is necessary because a request to one protocol might redirect to another. In such a scenario, Got will switch over to the right protocol agent for you.
```js
const got = require('got');
const HttpAgent = require('agentkeepalive');
const {HttpsAgent} = HttpAgent;
got('sindresorhus.com', {
agent: {
http: new HttpAgent(),
https: new HttpsAgent()
}
});
```
###### hooks

@@ -307,2 +337,67 @@

#### Response
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.
##### body
Type: `string` `Object` *(depending on `options.json`)*
The result of the request.
##### url
Type: `string`
The request URL or the final URL after redirects.
##### requestUrl
Type: `string`
The original request URL.
##### timings
Type: `Object`
The object contains the following properties:
- `start` - Time when the request started.
- `socket` - Time when a socket was assigned to the request.
- `lookup` - Time when the DNS lookup finished.
- `connect` - Time when the socket successfully connected.
- `upload` - Time when the request finished uploading.
- `response` - Time when the request fired the `response` event.
- `end` - Time when the response fired the `end` event.
- `error` - Time when the request fired the `error` event.
- `phases`
- `wait` - `timings.socket - timings.start`
- `dns` - `timings.lookup - timings.socket`
- `tcp` - `timings.connect - timings.lookup`
- `request` - `timings.upload - timings.connect`
- `firstByte` - `timings.response - timings.upload`
- `download` - `timings.end - timings.response`
- `total` - `timings.end - timings.start` or `timings.error - timings.start`
**Note**: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
##### fromCache
Type: `boolean`
Whether the response was retrieved from the cache.
##### redirectUrls
Type: `Array`
The redirect URLs.
##### retryCount
Type: `number`
The number of times the request was retried.
#### Streams

@@ -316,3 +411,3 @@

Returna a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex) with additional events:
Returns a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex) with additional events:

@@ -578,3 +673,3 @@ ##### .on('request', request)

You can use the [`tunnel`](https://github.com/koichik/node-tunnel) module with the `agent` option to work with proxies:
You can use the [`tunnel`](https://github.com/koichik/node-tunnel) package with the `agent` option to work with proxies:

@@ -594,17 +689,2 @@ ```js

If you require different agents for different protocols, you can pass a map of agents to the `agent` option. This is necessary because a request to one protocol might redirect to another. In such a scenario, `got` will switch over to the right protocol agent for you.
```js
const got = require('got');
const HttpAgent = require('agentkeepalive');
const HttpsAgent = HttpAgent.HttpsAgent;
got('sindresorhus.com', {
agent: {
http: new HttpAgent(),
https: new HttpsAgent()
}
});
```
Check out [`global-tunnel`](https://github.com/np-maintain/global-tunnel) if you want to configure proxy support for all HTTP/HTTPS traffic in your app.

@@ -615,22 +695,12 @@

You can use the [`cookie`](https://github.com/jshttp/cookie) module to include cookies in a request:
You can use the [`tough-cookie`](https://github.com/salesforce/tough-cookie) package:
```js
const got = require('got');
const cookie = require('cookie');
const {CookieJar} = require('tough-cookie');
got('google.com', {
headers: {
cookie: cookie.serialize('foo', 'bar')
}
});
const cookieJar = new CookieJar();
cookieJar.setCookie('foo=bar', 'https://www.google.com');
got('google.com', {
headers: {
cookie: [
cookie.serialize('foo', 'bar'),
cookie.serialize('fizz', 'buzz')
].join(';')
}
});
got('google.com', {cookieJar});
```

@@ -641,3 +711,3 @@

You can use the [`form-data`](https://github.com/form-data/form-data) module to create POST request with form data:
You can use the [`form-data`](https://github.com/form-data/form-data) package to create POST request with form data:

@@ -660,3 +730,3 @@ ```js

You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) module to create a signed OAuth request:
You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) package to create a signed OAuth request:

@@ -739,3 +809,3 @@ ```js

You can test your requests by using the [`nock`](https://github.com/node-nock/nock) module to mock an endpoint:
You can test your requests by using the [`nock`](https://github.com/node-nock/nock) package to mock an endpoint:

@@ -788,3 +858,3 @@ ```js

headers: {
'user-agent': `my-module/${pkg.version} (https://github.com/username/my-module)`
'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
}

@@ -818,3 +888,3 @@ });

headers: {
'user-agent': `my-module/${pkg.version} (https://github.com/username/my-module)`
'user-agent': `my-package/${pkg.version} (https://github.com/username/my-package)`
}

@@ -831,33 +901,52 @@ });

### Experimental HTTP2 support
Got provides an experimental support for HTTP2 using the [`http2-wrapper`](https://github.com/szmarczak/http2-wrapper) package:
```js
const got = require('got');
const {request} = require('http2-wrapper');
const h2got = got.extend({request});
(async () => {
const {body} = await h2got('https://nghttp2.org/httpbin/headers');
console.log(body);
})();
```
## Comparison
| | `got` | `request` | `node-fetch` | `axios` |
|-----------------------|:-------:|:---------:|:------------:|:-------:|
| HTTP/2 support | ✖ | ✖ | ✖ | ✖ |
| Browser support | ✖ | ✖ | ✔* | ✔ |
| Electron support | ✔ | ✖ | ✖ | ✖ |
| Promise API | ✔ | ✔ | ✔ | ✔ |
| Stream API | ✔ | ✔ | ✖ | ✖ |
| Request cancelation | ✔ | ✖ | ✖ | ✔ |
| RFC compliant caching | ✔ | ✖ | ✖ | ✖ |
| Follows redirects | ✔ | ✔ | ✔ | ✔ |
| Retries on failure | ✔ | ✖ | ✖ | ✖ |
| Progress events | ✔ | ✖ | ✖ | ✔ |
| Handles gzip/deflate | ✔ | ✔ | ✔ | ✔ |
| Advanced timeouts | ✔ | ✖ | ✖ | ✖ |
| Errors with metadata | ✔ | ✖ | ✖ | ✔ |
| JSON mode | ✔ | ✖ | ✖ | ✔ |
| Custom defaults | ✔ | ✔ | ✖ | ✔ |
| Composable | ✔ | ✖ | ✖ | ✖ |
| Hooks | ✔ | ✖ | ✖ | ✔ |
| Issues open | ![][gio] | ![][rio] | ![][nio] | ![][aio] |
| Issues closed | ![][gic] | ![][ric] | ![][nic] | ![][aic] |
| Downloads | ![][gd] | ![][rd] | ![][nd] | ![][ad] |
| Coverage | ![][gc] | ![][rc] | ![][nc] | ![][ac] |
| Build | ![][gb] | ![][rb] | ![][nb] | ![][ab] |
| Dependents | ![][gdp] | ![][rdp] | ![][ndp] | ![][adp] |
| Install size | ![][gis] | ![][ris] | ![][nis] | ![][ais] |
| | `got` | `request` | `node-fetch` | `axios` |
|-----------------------|:------------:|:------------:|:------------:|:------------:|
| HTTP/2 support | ❔ | ✖ | ✖ | ✖ |
| Browser support | ✖ | ✖ | ✔* | ✔ |
| Electron support | ✔ | ✖ | ✖ | ✖ |
| Promise API | ✔ | ✔ | ✔ | ✔ |
| Stream API | ✔ | ✔ | ✖ | ✖ |
| Request cancelation | ✔ | ✖ | ✖ | ✔ |
| RFC compliant caching | ✔ | ✖ | ✖ | ✖ |
| Cookies (out-of-box) | ✔ | ✔ | ✖ | ✖ |
| Follows redirects | ✔ | ✔ | ✔ | ✔ |
| Retries on failure | ✔ | ✖ | ✖ | ✖ |
| Progress events | ✔ | ✖ | ✖ | Browser only |
| Handles gzip/deflate | ✔ | ✔ | ✔ | ✔ |
| Advanced timeouts | ✔ | ✖ | ✖ | ✖ |
| Timings | ✔ | ✔ | ✖ | ✖ |
| Errors with metadata | ✔ | ✖ | ✖ | ✔ |
| JSON mode | ✔ | ✔ | ✖ | ✔ |
| Custom defaults | ✔ | ✔ | ✖ | ✔ |
| Composable | ✔ | ✖ | ✖ | ✖ |
| Hooks | ✔ | ✖ | ✖ | ✔ |
| Issues open | ![][gio] | ![][rio] | ![][nio] | ![][aio] |
| Issues closed | ![][gic] | ![][ric] | ![][nic] | ![][aic] |
| Downloads | ![][gd] | ![][rd] | ![][nd] | ![][ad] |
| Coverage | ![][gc] | ![][rc] | ![][nc] | ![][ac] |
| Build | ![][gb] | ![][rb] | ![][nb] | ![][ab] |
| Bugs | ![][gbg] | ![][rbg] | ![][nbg] | ![][abg] |
| Dependents | ![][gdp] | ![][rdp] | ![][ndp] | ![][adp] |
| Install size | ![][gis] | ![][ris] | ![][nis] | ![][ais] |
\* It's almost API compatible with the browser `fetch` API.
\* It's almost API compatible with the browser `fetch` API.<br>
❔ Experimental support.

@@ -894,2 +983,8 @@ <!-- ISSUES OPEN -->

<!-- BUGS -->
[gbg]: https://badgen.net/github/label-issues/sindresorhus/got/bug/open
[rbg]: https://badgen.net/github/label-issues/request/request/Needs%20investigation/open
[nbg]: https://badgen.net/github/label-issues/bitinn/node-fetch/bug/open
[abg]: https://badgen.net/github/label-issues/axios/axios/bug/open
<!-- DEPENDENTS -->

@@ -896,0 +991,0 @@ [gdp]: https://badgen.net/npm/dependents/got

@@ -12,3 +12,3 @@ 'use strict';

const cancelable = new PCancelable((resolve, reject, onCancel) => {
const promise = new PCancelable((resolve, reject, onCancel) => {
const emitter = requestAsEventEmitter(options);

@@ -24,2 +24,3 @@ let cancelOnRequest = false;

request.abort();
return;
}

@@ -104,6 +105,2 @@

const promise = cancelable;
promise.cancel = cancelable.cancel.bind(cancelable);
promise.on = (name, fn) => {

@@ -110,0 +107,0 @@ proxy.on(name, fn);

@@ -31,6 +31,5 @@ 'use strict';

try {
options = mergeOptions(defaults.options, options);
return defaults.handler(normalizeArguments(url, options, defaults), next);
} catch (error) {
if (options.stream) {
if (options && options.stream) {
throw error;

@@ -44,3 +43,3 @@ } else {

got.create = create;
got.extend = (options = {}) => create({
got.extend = options => create({
options: mergeOptions(defaults.options, options),

@@ -53,5 +52,3 @@ handler: defaults.handler

got.stream = (url, options) => {
options = mergeOptions(defaults.options, options);
options.stream = true;
return defaults.handler(normalizeArguments(url, options, defaults), next);
return defaults.handler(normalizeArguments(url, {...options, stream: true}, defaults), next);
};

@@ -58,0 +55,0 @@

'use strict';
/* istanbul ignore next: compatibility reason */
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL; // TODO: Use the `URL` global when targeting Node.js 10
/* istanbul ignore next: compatibility reason */
const URLSearchParamsGlobal = typeof URLSearchParams === 'undefined' ? require('url').URLSearchParams : URLSearchParams;
const {URL, URLSearchParams} = require('url'); // TODO: Use the `URL` global when targeting Node.js 10
const is = require('@sindresorhus/is');

@@ -13,2 +10,3 @@ const toReadableStream = require('to-readable-stream');

const knownHookEvents = require('./known-hook-events');
const merge = require('./merge');

@@ -61,2 +59,4 @@ const retryAfterStatusCodes = new Set([413, 429, 503]);

module.exports = (url, options, defaults) => {
options = merge({}, defaults.options, options ? preNormalize(options) : {});
if (Reflect.has(options, 'url') || (is.object(url) && Reflect.has(url, 'url'))) {

@@ -70,4 +70,2 @@ throw new TypeError('Parameter `url` is not an option. Use got(url, options)');

options = preNormalize(options);
if (is.string(url)) {

@@ -79,3 +77,3 @@ if (options.baseUrl) {

url = urlToOptions(new URLGlobal(url, options.baseUrl));
url = urlToOptions(new URL(url, options.baseUrl));
} else {

@@ -115,5 +113,7 @@ url = url.replace(/^unix:/, 'http://$&');

const {query} = options;
if (!is.empty(query) || query instanceof URLSearchParamsGlobal) {
const queryParams = new URLSearchParamsGlobal(query);
options.path = `${options.path.split('?')[0]}?${queryParams.toString()}`;
if (!is.empty(query) || query instanceof URLSearchParams) {
if (!is.string(query)) {
options.query = (new URLSearchParams(query)).toString();
}
options.path = `${options.path.split('?')[0]}?${options.query}`;
delete options.query;

@@ -159,3 +159,3 @@ }

headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded';
options.body = (new URLSearchParamsGlobal(body)).toString();
options.body = (new URLSearchParams(body)).toString();
} else if (options.json) {

@@ -162,0 +162,0 @@ headers['content-type'] = headers['content-type'] || 'application/json';

'use strict';
module.exports = {

@@ -31,8 +32,2 @@ upload(request, emitter, uploadBodySize) {

progressInterval = setInterval(() => {
/* istanbul ignore next: hard to test */
if (socket.destroyed) {
clearInterval(progressInterval);
return;
}
const lastUploaded = uploaded;

@@ -63,5 +58,6 @@ /* istanbul ignore next: see #490 (occurs randomly!) */

/* istanbul ignore next: hard to test */
if (socket.connecting) {
socket.once('connect', onSocketConnect);
} else {
} else if (socket.writable) {
// The socket is being reused from pool,

@@ -68,0 +64,0 @@ // so the connect event will not be emitted

'use strict';
/* istanbul ignore next: compatibility reason */
const URLGlobal = typeof URL === 'undefined' ? require('url').URL : URL; // TODO: Use the `URL` global when targeting Node.js 10
const {URL} = require('url'); // TODO: Use the `URL` global when targeting Node.js 10
const util = require('util');
const EventEmitter = require('events');

@@ -10,2 +10,3 @@ const http = require('http');

const is = require('@sindresorhus/is');
const timer = require('@szmarczak/http-timer');
const timedOut = require('./timed-out');

@@ -22,3 +23,3 @@ const getBodySize = require('./get-body-size');

const emitter = new EventEmitter();
const requestUrl = options.href || (new URLGlobal(options.path, urlLib.format(options))).toString();
const requestUrl = options.href || (new URL(options.path, urlLib.format(options))).toString();
const redirects = [];

@@ -31,3 +32,8 @@ const agents = is.object(options.agent) ? options.agent : null;

const get = options => {
const setCookie = options.cookieJar ? util.promisify(options.cookieJar.setCookie.bind(options.cookieJar)) : null;
const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
const get = async options => {
const currentUrl = redirectUrl || requestUrl;
if (options.protocol !== 'http:' && options.protocol !== 'https:') {

@@ -38,3 +44,8 @@ emitter.emit('error', new UnsupportedProtocolError(options));

let fn = options.protocol === 'https:' ? https : http;
let fn;
if (is.function(options.request)) {
fn = {request: options.request};
} else {
fn = options.protocol === 'https:' ? https : http;
}

@@ -48,13 +59,51 @@ if (agents) {

if (options.useElectronNet && process.versions.electron) {
const electron = global['require']('electron'); // eslint-disable-line dot-notation
const r = ({x: require})['yx'.slice(1)]; // Trick webpack
const electron = r('electron');
fn = electron.net || electron.remote.net;
}
if (options.cookieJar) {
try {
const cookieString = await getCookieString(currentUrl, {});
if (!is.empty(cookieString)) {
options.headers.cookie = cookieString;
}
} catch (error) {
emitter.emit('error', error);
}
}
let timings;
const cacheableRequest = new CacheableRequest(fn.request, options.cache);
const cacheReq = cacheableRequest(options, response => {
const cacheReq = cacheableRequest(options, async response => {
/* istanbul ignore next: fixes https://github.com/electron/electron/blob/cbb460d47628a7a146adf4419ed48550a98b2923/lib/browser/api/net.js#L59-L65 */
if (options.useElectronNet) {
response = new Proxy(response, {
get: (target, name) => {
if (name === 'trailers' || name === 'rawTrailers') {
return [];
}
const value = target[name];
return is.function(value) ? value.bind(target) : value;
}
});
}
const {statusCode} = response;
response.url = currentUrl;
response.requestUrl = requestUrl;
response.retryCount = retryCount;
response.url = redirectUrl || requestUrl;
response.requestUrl = requestUrl;
response.timings = timings;
const rawCookies = response.headers['set-cookie'];
if (options.cookieJar && rawCookies) {
try {
await Promise.all(rawCookies.map(rawCookie => setCookie(rawCookie, response.url)));
} catch (error) {
emitter.emit('error', error);
}
}
const followRedirect = options.followRedirect && 'location' in response.headers;

@@ -79,3 +128,3 @@ const redirectGet = followRedirect && getMethodRedirectCodes.has(statusCode);

const bufferString = Buffer.from(response.headers.location, 'binary').toString();
redirectUrl = (new URLGlobal(bufferString, urlLib.format(options))).toString();
redirectUrl = (new URL(bufferString, urlLib.format(options))).toString();

@@ -98,3 +147,3 @@ try {

get(redirectOpts);
await get(redirectOpts);
return;

@@ -139,2 +188,4 @@ }

timings = timer(request);
progress.upload(request, emitter, uploadBodySize);

@@ -173,8 +224,6 @@

if (
uploadBodySize > 0 &&
is.undefined(options.headers['content-length']) &&
is.undefined(options.headers['transfer-encoding'])
) {
options.headers['content-length'] = uploadBodySize;
if (is.undefined(options.headers['content-length']) && is.undefined(options.headers['transfer-encoding'])) {
if (uploadBodySize > 0 || options.method === 'PUT') {
options.headers['content-length'] = uploadBodySize;
}
}

@@ -187,3 +236,3 @@

get(options);
await get(options);
} catch (error) {

@@ -190,0 +239,0 @@ emitter.emit('error', error);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc