Breaking changes
- Rewrite HTTP/2 support and drop the
http2-wrapperdependency (#2464) 1e157c4- Got now has a built-in HTTP/2 client: ALPN negotiation, a pooled session cache with multiplexing,
GOAWAYretirement, request and response trailers, informational (1xx) responses, abort signals, response caching, IPv6 authorities, andh2cthroughh2session. agent.http2is no longer an agent slot. It is only an opt-out flag now: passfalseto skip session pooling. Passing an agent instance throws.- Response headers no longer contain HTTP/2 pseudo-headers. Use
response.statusCodeinstead ofresponse.headers[':status']. - A custom
agent.httpscombined withhttp2: truemakes 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.requestreturns a request or response, it controls the transport and the HTTP/2 client is bypassed. Returnundefinedto fall back to Got's own transport.
- Got now has a built-in HTTP/2 client: ALPN negotiation, a pooled session cache with multiplexing,
- Rewrite DNS cache and drop the
cacheable-lookupdependency (#2463) bfc400bdnsCache: truenow uses Got's own cache. The option accepts any object with alookupfunction and an optionalclear(hostname?)function, so an existingCacheableLookupinstance still works if you keep the dependency yourself.- The built-in cache resolves A and AAAA records separately, so it cannot preserve OS-specific
verbatimaddress ordering fromdns.lookup().
- A
beforeRequesthook, anafterResponseretry, or a pagination step that moves the request to a different origin now strips credentials and drops the body (#2465) dd3b295authorization,cookie,cookie2,host, andproxy-authorizationare 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
urlor throughprefixUrl.
copyPipedHeadersno longer copies credentials 1d233baauthorization,cookie,cookie2,set-cookie, andset-cookie2are now omitted along withhost, the hop-by-hop headers, and anything nominated byConnection/Proxy-Connection. Pass credentials explicitly inheaderswhen the upstream is trusted.
- Remove the deprecated
searchParameters,followRedirects, andauthoption stubs 1d233ba- They only existed to throw a guidance message. Passing them now throws
Unexpected option: ….
- They only existed to throw a guidance message. Passing them now throws
- Remove the
OptionsOfUnknownResponseBodytype 1d233ba- It was a pure alias for
StrictOptions.
- It was a pure alias for
Improvements
- Add support for the
QUERYHTTP method (#2466) e3924aa- Adds
got.query()andgot.stream.query().QUERYis safe and idempotent, so it is retried by default and keeps a replayable body across301and302redirects as well as307and308. It is not stored by the built-in cache, because correctQUERYcaching needs cache keys that include the request content.
- Adds
allowGetBodynow also works over HTTP/2 1e157c4timeout.socketnow applies during HTTP/2 TLS negotiation and session setup c6bbb8a- It was previously folded into the connection setup timeout and reported as a
requesttimeout. It now produces a realsockettimeout and no longer counts DNS lookup time.
- It was previously folded into the connection setup timeout and reported as a
- Two fewer dependencies:
cacheable-lookupandhttp2-wrapperbfc400b 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: 0instead of falling back to the backoff delay (#2471) d35ce87 - Preserve the response body when a cookie jar write throws c6bbb8a
error.response.bodyis now complete, decompressed, and decoded with the configuredencoding, and a decoding failure no longer masks the original error.
- Wait for async cookie jar writes on terminal redirect responses, for example with
followRedirect: falsec6bbb8a - Only buffer the response body for cookie handling when the response actually sends
set-cookiec6bbb8a - Fix
got.streamfinalizing the response before theresponseevent and before piped server response headers are set c6bbb8a - Fix
strictContentLengthcounting bytes from responses that were not actually decompressed c6bbb8a - Freeze
hooks.beforeCachealong with the other hook arrays on non-mutable defaults 1d233ba - Keep URL credentials when
prefixUrlis changed to a same-origin value, and treat credentials inprefixUrlas 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
}
});