npm got 16.0.0

4 hours ago

Breaking changes

  • Rewrite HTTP/2 support and drop the http2-wrapper dependency (#2464) 1e157c4
    • Got now has a built-in HTTP/2 client: ALPN negotiation, a pooled session cache with multiplexing, GOAWAY retirement, request and response trailers, informational (1xx) responses, abort signals, response caching, IPv6 authorities, and h2c through h2session.
    • agent.http2 is no longer an agent slot. It is only an opt-out flag now: pass false to skip session pooling. Passing an agent instance throws.
    • Response headers no longer contain HTTP/2 pseudo-headers. Use response.statusCode instead of response.headers[':status'].
    • A custom agent.https combined with http2: true makes Got use the native HTTP/1.1 path, because the built-in session pool does not support custom HTTPS agents.
    • HTTP/2 proxy support is gone. It came from http2-wrapper. It was very buggy anyway.
    • If options.request returns a request or response, it controls the transport and the HTTP/2 client is bypassed. Return undefined to fall back to Got's own transport.
  • Rewrite DNS cache and drop the cacheable-lookup dependency (#2463) bfc400b
    • dnsCache: true now uses Got's own cache. The option accepts any object with a lookup function and an optional clear(hostname?) function, so an existing CacheableLookup instance still works if you keep the dependency yourself.
    • The built-in cache resolves A and AAAA records separately, so it cannot preserve OS-specific verbatim address ordering from dns.lookup().
  • A beforeRequest hook, an afterResponse retry, or a pagination step that moves the request to a different origin now strips credentials and drops the body (#2465) dd3b295
    • authorization, cookie, cookie2, host, and proxy-authorization are removed, URL credentials are dropped, and an unchanged body is cleared. Set the headers or body explicitly inside the hook if you want them to cross the origin boundary.
    • This applies whether the origin changes through url or through prefixUrl.
  • copyPipedHeaders no longer copies credentials 1d233ba
    • authorization, cookie, cookie2, set-cookie, and set-cookie2 are now omitted along with host, the hop-by-hop headers, and anything nominated by Connection / Proxy-Connection. Pass credentials explicitly in headers when the upstream is trusted.
  • Remove the deprecated searchParameters, followRedirects, and auth option stubs 1d233ba
    • They only existed to throw a guidance message. Passing them now throws Unexpected option: ….
  • Remove the OptionsOfUnknownResponseBody type 1d233ba
    • It was a pure alias for StrictOptions.

Improvements

  • Add support for the QUERY HTTP method (#2466) e3924aa
    • Adds got.query() and got.stream.query(). QUERY is safe and idempotent, so it is retried by default and keeps a replayable body across 301 and 302 redirects as well as 307 and 308. It is not stored by the built-in cache, because correct QUERY caching needs cache keys that include the request content.
  • allowGetBody now also works over HTTP/2 1e157c4
  • timeout.socket now applies during HTTP/2 TLS negotiation and session setup c6bbb8a
    • It was previously folded into the connection setup timeout and reported as a request timeout. It now produces a real socket timeout and no longer counts DNS lookup time.
  • Two fewer dependencies: cacheable-lookup and http2-wrapper bfc400b 1e157c4

Fixes

  • Retry on connection errors reported by request.end() instead of failing the request (#2470) 67919b2
  • Retry immediately when the server answers with Retry-After: 0 instead of falling back to the backoff delay (#2471) d35ce87
  • Preserve the response body when a cookie jar write throws c6bbb8a
    • error.response.body is now complete, decompressed, and decoded with the configured encoding, and a decoding failure no longer masks the original error.
  • Wait for async cookie jar writes on terminal redirect responses, for example with followRedirect: false c6bbb8a
  • Only buffer the response body for cookie handling when the response actually sends set-cookie c6bbb8a
  • Fix got.stream finalizing the response before the response event and before piped server response headers are set c6bbb8a
  • Fix strictContentLength counting bytes from responses that were not actually decompressed c6bbb8a
  • Freeze hooks.beforeCache along with the other hook arrays on non-mutable defaults 1d233ba
  • Keep URL credentials when prefixUrl is changed to a same-origin value, and treat credentials in prefixUrl as explicit dd3b295

Migration guide

HTTP/2

Remove http2-wrapper from your code. Got's HTTP/2 client is built in.

Before:

import http2wrapper from 'http2-wrapper';

const {headers} = await got(url, {
	http2: true,
	request: http2wrapper.auto,
	agent: {
		http2: new http2wrapper.Agent()
	}
});

console.log(headers[':status']);

After:

const {statusCode} = await got(url, {http2: true});

console.log(statusCode);

To opt out of HTTP/2 session pooling for a request, set agent.http2 to false.

If you need an HTTP/2 proxy, keep using http2-wrapper through the request option. Returning a request from request bypasses Got's HTTP/2 client.

h2c

The h2session hook example no longer needs request or http2.

Before:

import http2 from 'http2-wrapper';

got.extend({
	hooks: {
		beforeRequest: [
			options => {
				options.h2session = getSession(options.url);
				options.http2 = true;
				options.request = http2.request;
			}
		]
	}
});

After:

got.extend({
	hooks: {
		beforeRequest: [
			options => {
				options.h2session = getSession(options.url);
			}
		]
	}
});

dnsCache

dnsCache: true keeps working and now uses Got's built-in cache. If you depend on cacheable-lookup specific options, install it yourself and pass the instance:

import CacheableLookup from 'cacheable-lookup';

const dnsCache = new CacheableLookup({maxTtl: 60});

await got(url, {dnsCache});

Cross-origin hooks

If a beforeRequest hook, an afterResponse retry, or a pagination step sends the request to a different origin, set the headers and body you want to keep explicitly:

got.extend({
	hooks: {
		beforeRequest: [
			options => {
				options.url = new URL('https://other.example.com/path');
				options.headers.authorization = 'Bearer …';
			}
		]
	}
});

copyPipedHeaders

Credentials are no longer forwarded from a piped request. Pass them explicitly when the upstream is trusted:

got.stream(url, {
	copyPipedHeaders: true,
	headers: {
		authorization: request.headers.authorization
	}
});

v15.1.0...v16.0.0

Don't miss a new got release

NewReleases is sending notifications on new releases.