undici 5.25.3 → 5.26.0

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.
@@ -24,7 +24,7 @@ Returns: `Client`
24
24
  * **keepAliveMaxTimeout** `number | null` (optional) - Default: `600e3` - The maximum allowed `keepAliveTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Defaults to 10 minutes.
25
25
  * **keepAliveTimeout** `number | null` (optional) - Default: `4e3` - The timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. See [MDN: HTTP - Headers - Keep-Alive directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive#directives) for more details. Defaults to 4 seconds.
26
26
  * **keepAliveTimeoutThreshold** `number | null` (optional) - Default: `1e3` - A number of milliseconds subtracted from server *keep-alive* hints when overriding `keepAliveTimeout` to account for timing inaccuracies caused by e.g. transport latency. Defaults to 1 second.
27
- * **maxHeaderSize** `number | null` (optional) - Default: `16384` - The maximum length of request headers in bytes. Defaults to 16KiB.
27
+ * **maxHeaderSize** `number | null` (optional) - Default: `--max-http-header-size` or `16384` - The maximum length of request headers in bytes. Defaults to Node.js' --max-http-header-size or 16KiB.
28
28
  * **maxResponseSize** `number | null` (optional) - Default: `-1` - The maximum length of response body in bytes. Set to `-1` to disable.
29
29
  * **pipelining** `number | null` (optional) - Default: `1` - The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Carefully consider your workload and environment before enabling concurrent requests as pipelining may reduce performance if used incorrectly. Pipelining is sensitive to network stack settings as well as head of line blocking caused by e.g. long running requests. Set to `0` to disable keep-alive connections.
30
30
  * **connect** `ConnectOptions | Function | null` (optional) - Default: `null`.
package/lib/client.js CHANGED
@@ -6,6 +6,7 @@
6
6
 
7
7
  const assert = require('assert')
8
8
  const net = require('net')
9
+ const http = require('http')
9
10
  const { pipeline } = require('stream')
10
11
  const util = require('./core/util')
11
12
  const timers = require('./timers')
@@ -93,6 +94,7 @@ const {
93
94
  HTTP2_HEADER_AUTHORITY,
94
95
  HTTP2_HEADER_METHOD,
95
96
  HTTP2_HEADER_PATH,
97
+ HTTP2_HEADER_SCHEME,
96
98
  HTTP2_HEADER_CONTENT_LENGTH,
97
99
  HTTP2_HEADER_EXPECT,
98
100
  HTTP2_HEADER_STATUS
@@ -269,7 +271,7 @@ class Client extends DispatcherBase {
269
271
  this[kConnector] = connect
270
272
  this[kSocket] = null
271
273
  this[kPipelining] = pipelining != null ? pipelining : 1
272
- this[kMaxHeadersSize] = maxHeaderSize || 16384
274
+ this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize
273
275
  this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout
274
276
  this[kKeepAliveMaxTimeout] = keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout
275
277
  this[kKeepAliveTimeoutThreshold] = keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold
@@ -1689,7 +1691,7 @@ function writeH2 (client, session, request) {
1689
1691
  const h2State = client[kHTTP2SessionState]
1690
1692
 
1691
1693
  headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost]
1692
- headers[HTTP2_HEADER_PATH] = path
1694
+ headers[HTTP2_HEADER_METHOD] = method
1693
1695
 
1694
1696
  if (method === 'CONNECT') {
1695
1697
  session.ref()
@@ -1716,10 +1718,14 @@ function writeH2 (client, session, request) {
1716
1718
  })
1717
1719
 
1718
1720
  return true
1719
- } else {
1720
- headers[HTTP2_HEADER_METHOD] = method
1721
1721
  }
1722
1722
 
1723
+ // https://tools.ietf.org/html/rfc7540#section-8.3
1724
+ // :path and :scheme headers must be omited when sending CONNECT
1725
+
1726
+ headers[HTTP2_HEADER_PATH] = path
1727
+ headers[HTTP2_HEADER_SCHEME] = 'https'
1728
+
1723
1729
  // https://tools.ietf.org/html/rfc7231#section-4.3.1
1724
1730
  // https://tools.ietf.org/html/rfc7231#section-4.3.2
1725
1731
  // https://tools.ietf.org/html/rfc7231#section-4.3.5
@@ -1856,6 +1862,7 @@ function writeH2 (client, session, request) {
1856
1862
  stream.cork()
1857
1863
  stream.write(body)
1858
1864
  stream.uncork()
1865
+ stream.end()
1859
1866
  request.onBodySent(body)
1860
1867
  request.onRequestSent()
1861
1868
  } else if (util.isBlobLike(body)) {
@@ -2090,13 +2097,17 @@ async function writeIterable ({ h2stream, body, client, request, socket, content
2090
2097
  throw socket[kError]
2091
2098
  }
2092
2099
 
2093
- if (!h2stream.write(chunk)) {
2100
+ const res = h2stream.write(chunk)
2101
+ request.onBodySent(chunk)
2102
+ if (!res) {
2094
2103
  await waitForDrain()
2095
2104
  }
2096
2105
  }
2097
2106
  } catch (err) {
2098
2107
  h2stream.destroy(err)
2099
2108
  } finally {
2109
+ request.onRequestSent()
2110
+ h2stream.end()
2100
2111
  h2stream
2101
2112
  .off('close', onDrain)
2102
2113
  .off('drain', onDrain)
@@ -22,11 +22,13 @@ class CompatFinalizer {
22
22
  }
23
23
 
24
24
  register (dispatcher, key) {
25
- dispatcher.on('disconnect', () => {
26
- if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
27
- this.finalizer(key)
28
- }
29
- })
25
+ if (dispatcher.on) {
26
+ dispatcher.on('disconnect', () => {
27
+ if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) {
28
+ this.finalizer(key)
29
+ }
30
+ })
31
+ }
30
32
  }
31
33
  }
32
34
 
@@ -13,7 +13,9 @@ let tls // include tls conditionally since it is not always available
13
13
  // re-use is enabled.
14
14
 
15
15
  let SessionCache
16
- if (global.FinalizationRegistry) {
16
+ // FIXME: remove workaround when the Node bug is fixed
17
+ // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308
18
+ if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) {
17
19
  SessionCache = class WeakSessionCache {
18
20
  constructor (maxCachedSessions) {
19
21
  this._maxCachedSessions = maxCachedSessions
@@ -381,7 +381,8 @@ function processHeader (request, key, val, skipAppend = false) {
381
381
  key.toLowerCase() === 'content-type'
382
382
  ) {
383
383
  request.contentType = val
384
- request.headers += processHeaderValue(key, val)
384
+ if (skipAppend) request.headers[key] = processHeaderValue(key, val, skipAppend)
385
+ else request.headers += processHeaderValue(key, val)
385
386
  } else if (
386
387
  key.length === 17 &&
387
388
  key.toLowerCase() === 'transfer-encoding'
@@ -1344,7 +1344,7 @@ async function httpNetworkOrCacheFetch (
1344
1344
  // user agents should append `User-Agent`/default `User-Agent` value to
1345
1345
  // httpRequest’s header list.
1346
1346
  if (!httpRequest.headersList.contains('user-agent')) {
1347
- httpRequest.headersList.append('user-agent', 'undici')
1347
+ httpRequest.headersList.append('user-agent', __filename.endsWith('index.js') ? 'undici' : 'node')
1348
1348
  }
1349
1349
 
1350
1350
  // 15. If httpRequest’s cache mode is "default" and httpRequest’s header
@@ -1406,6 +1406,8 @@ async function httpNetworkOrCacheFetch (
1406
1406
  }
1407
1407
  }
1408
1408
 
1409
+ httpRequest.headersList.delete('host')
1410
+
1409
1411
  // 20. If includeCredentials is true, then:
1410
1412
  if (includeCredentials) {
1411
1413
  // 1. If the user agent is not configured to block cookies for httpRequest
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "undici",
3
- "version": "5.25.3",
3
+ "version": "5.26.0",
4
4
  "description": "An HTTP/1.1 client, written from scratch for Node.js",
5
5
  "homepage": "https://undici.nodejs.org",
6
6
  "bugs": {
@@ -75,7 +75,7 @@
75
75
  "build:wasm": "node build/wasm.js --docker",
76
76
  "lint": "standard | snazzy",
77
77
  "lint:fix": "standard --fix | snazzy",
78
- "test": "npm run test:tap && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:wpt && npm run test:websocket && npm run test:jest && npm run test:typescript",
78
+ "test": "node scripts/generate-pem && npm run test:tap && npm run test:node-fetch && npm run test:fetch && npm run test:cookies && npm run test:wpt && npm run test:websocket && npm run test:jest && npm run test:typescript",
79
79
  "test:cookies": "node scripts/verifyVersion 16 || tap test/cookie/*.js",
80
80
  "test:node-fetch": "node scripts/verifyVersion.js 16 || mocha --exit test/node-fetch",
81
81
  "test:fetch": "node scripts/verifyVersion.js 16 || (npm run build:node && tap --expose-gc test/fetch/*.js && tap test/webidl/*.js)",
@@ -93,7 +93,6 @@
93
93
  "bench:run": "CONNECTIONS=1 node benchmarks/benchmark.js; CONNECTIONS=50 node benchmarks/benchmark.js",
94
94
  "serve:website": "docsify serve .",
95
95
  "prepare": "husky install",
96
- "postpublish": "node scripts/update-undici-types-version.js && cd types && npm publish",
97
96
  "fuzz": "jsfuzz test/fuzzing/fuzz.js corpus"
98
97
  },
99
98
  "devDependencies": {
@@ -123,7 +122,8 @@
123
122
  "pre-commit": "^1.2.2",
124
123
  "proxy": "^1.0.2",
125
124
  "proxyquire": "^2.1.3",
126
- "sinon": "^15.0.0",
125
+ "semver": "^7.5.4",
126
+ "sinon": "^16.1.0",
127
127
  "snazzy": "^9.0.0",
128
128
  "standard": "^17.0.0",
129
129
  "table": "^6.8.0",
package/types/agent.d.ts CHANGED
@@ -17,7 +17,7 @@ declare class Agent extends Dispatcher{
17
17
  declare namespace Agent {
18
18
  export interface Options extends Pool.Options {
19
19
  /** Default: `(origin, opts) => new Pool(origin, opts)`. */
20
- factory?(origin: URL, opts: Object): Dispatcher;
20
+ factory?(origin: string | URL, opts: Object): Dispatcher;
21
21
  /** Integer. Default: `0` */
22
22
  maxRedirections?: number;
23
23
 
package/types/client.d.ts CHANGED
@@ -23,7 +23,7 @@ export declare namespace Client {
23
23
  export interface Options {
24
24
  /** TODO */
25
25
  interceptors?: OptionsInterceptors;
26
- /** The maximum length of request headers in bytes. Default: `16384` (16KiB). */
26
+ /** The maximum length of request headers in bytes. Default: Node.js' `--max-http-header-size` or `16384` (16KiB). */
27
27
  maxHeaderSize?: number;
28
28
  /** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */
29
29
  headersTimeout?: number;
@@ -6,6 +6,7 @@ declare function buildConnector (options?: buildConnector.BuildOptions): buildCo
6
6
 
7
7
  declare namespace buildConnector {
8
8
  export type BuildOptions = (ConnectionOptions | TcpNetConnectOpts | IpcNetConnectOpts) & {
9
+ allowH2?: boolean;
9
10
  maxCachedSessions?: number | null;
10
11
  socketPath?: string | null;
11
12
  timeout?: number | null;
@@ -1,55 +0,0 @@
1
- {
2
- "name": "undici-types",
3
- "version": "5.25.1",
4
- "description": "A stand-alone types package for Undici",
5
- "homepage": "https://undici.nodejs.org",
6
- "bugs": {
7
- "url": "https://github.com/nodejs/undici/issues"
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/nodejs/undici.git"
12
- },
13
- "license": "MIT",
14
- "types": "index.d.ts",
15
- "files": [
16
- "*.d.ts"
17
- ],
18
- "contributors": [
19
- {
20
- "name": "Daniele Belardi",
21
- "url": "https://github.com/dnlup",
22
- "author": true
23
- },
24
- {
25
- "name": "Ethan Arrowood",
26
- "url": "https://github.com/ethan-arrowood",
27
- "author": true
28
- },
29
- {
30
- "name": "Matteo Collina",
31
- "url": "https://github.com/mcollina",
32
- "author": true
33
- },
34
- {
35
- "name": "Matthew Aitken",
36
- "url": "https://github.com/KhafraDev",
37
- "author": true
38
- },
39
- {
40
- "name": "Robert Nagy",
41
- "url": "https://github.com/ronag",
42
- "author": true
43
- },
44
- {
45
- "name": "Szymon Marczak",
46
- "url": "https://github.com/szmarczak",
47
- "author": true
48
- },
49
- {
50
- "name": "Tomas Della Vedova",
51
- "url": "https://github.com/delvedor",
52
- "author": true
53
- }
54
- ]
55
- }