Skip to content

Commit 20af3a6

Browse files
deps: update undici to 5.13.0
PR-URL: #45634 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com>
1 parent 1b550ba commit 20af3a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1080
-1341
lines changed

deps/undici/src/README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,6 @@ Implements [fetch](https://fetch.spec.whatwg.org/#fetch-method).
178178

179179
Only supported on Node 16.8+.
180180

181-
This is [experimental](https://nodejs.org/api/documentation.html#documentation_stability_index) and is not yet fully compliant with the Fetch Standard.
182-
We plan to ship breaking changes to this feature until it is out of experimental.
183-
Help us improve the test coverage by following instructions at [nodejs/undici/#951](https://github.com/nodejs/undici/issues/951).
184-
185181
Basic usage example:
186182

187183
```js
@@ -234,9 +230,15 @@ const data = {
234230
},
235231
}
236232

237-
await fetch('https://example.com', { body: data, method: 'POST' })
233+
await fetch('https://example.com', { body: data, method: 'POST', duplex: 'half' })
238234
```
239235

236+
#### `request.duplex`
237+
238+
- half
239+
240+
In this implementation of fetch, `request.duplex` must be set if `request.body` is `ReadableStream` or `Async Iterables`. And fetch requests are currently always be full duplex. More detail refer to [Fetch Standard.](https://fetch.spec.whatwg.org/#dom-requestinit-duplex)
241+
240242
#### `response.body`
241243

242244
Nodejs has two kinds of streams: [web streams](https://nodejs.org/dist/latest-v16.x/docs/api/webstreams.html), which follow the API of the WHATWG web standard found in browsers, and an older Node-specific [streams API](https://nodejs.org/api/stream.html). `response.body` returns a readable web stream. If you would prefer to work with a Node stream you can convert a web stream using `.fromWeb()`.
-28.6 KB
Loading

deps/undici/src/index.d.ts

+23-23
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import Dispatcher = require('./types/dispatcher')
1+
import Dispatcher from'./types/dispatcher'
22
import { setGlobalDispatcher, getGlobalDispatcher } from './types/global-dispatcher'
33
import { setGlobalOrigin, getGlobalOrigin } from './types/global-origin'
4-
import Pool = require('./types/pool')
4+
import Pool from'./types/pool'
55
import { RedirectHandler, DecoratorHandler } from './types/handlers'
66

7-
import BalancedPool = require('./types/balanced-pool')
8-
import Client = require('./types/client')
9-
import buildConnector = require('./types/connector')
10-
import errors = require('./types/errors')
11-
import Agent = require('./types/agent')
12-
import MockClient = require('./types/mock-client')
13-
import MockPool = require('./types/mock-pool')
14-
import MockAgent = require('./types/mock-agent')
15-
import mockErrors = require('./types/mock-errors')
16-
import ProxyAgent = require('./types/proxy-agent')
7+
import BalancedPool from './types/balanced-pool'
8+
import Client from'./types/client'
9+
import buildConnector from'./types/connector'
10+
import errors from'./types/errors'
11+
import Agent from'./types/agent'
12+
import MockClient from'./types/mock-client'
13+
import MockPool from'./types/mock-pool'
14+
import MockAgent from'./types/mock-agent'
15+
import mockErrors from'./types/mock-errors'
16+
import ProxyAgent from'./types/proxy-agent'
1717
import { request, pipeline, stream, connect, upgrade } from './types/api'
1818

1919
export * from './types/fetch'
@@ -27,26 +27,26 @@ export { Dispatcher, BalancedPool, Pool, Client, buildConnector, errors, Agent,
2727
export default Undici
2828

2929
declare namespace Undici {
30-
var Dispatcher: typeof import('./types/dispatcher')
31-
var Pool: typeof import('./types/pool');
30+
var Dispatcher: typeof import('./types/dispatcher').default
31+
var Pool: typeof import('./types/pool').default;
3232
var RedirectHandler: typeof import ('./types/handlers').RedirectHandler
3333
var DecoratorHandler: typeof import ('./types/handlers').DecoratorHandler
3434
var createRedirectInterceptor: typeof import ('./types/interceptors').createRedirectInterceptor
35-
var BalancedPool: typeof import('./types/balanced-pool');
36-
var Client: typeof import('./types/client');
37-
var buildConnector: typeof import('./types/connector');
38-
var errors: typeof import('./types/errors');
39-
var Agent: typeof import('./types/agent');
35+
var BalancedPool: typeof import('./types/balanced-pool').default;
36+
var Client: typeof import('./types/client').default;
37+
var buildConnector: typeof import('./types/connector').default;
38+
var errors: typeof import('./types/errors').default;
39+
var Agent: typeof import('./types/agent').default;
4040
var setGlobalDispatcher: typeof import('./types/global-dispatcher').setGlobalDispatcher;
4141
var getGlobalDispatcher: typeof import('./types/global-dispatcher').getGlobalDispatcher;
4242
var request: typeof import('./types/api').request;
4343
var stream: typeof import('./types/api').stream;
4444
var pipeline: typeof import('./types/api').pipeline;
4545
var connect: typeof import('./types/api').connect;
4646
var upgrade: typeof import('./types/api').upgrade;
47-
var MockClient: typeof import('./types/mock-client');
48-
var MockPool: typeof import('./types/mock-pool');
49-
var MockAgent: typeof import('./types/mock-agent');
50-
var mockErrors: typeof import('./types/mock-errors');
47+
var MockClient: typeof import('./types/mock-client').default;
48+
var MockPool: typeof import('./types/mock-pool').default;
49+
var MockAgent: typeof import('./types/mock-agent').default;
50+
var mockErrors: typeof import('./types/mock-errors').default;
5151
var fetch: typeof import('./types/fetch').fetch;
5252
}

deps/undici/src/lib/fetch/body.js

+18-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const Busboy = require('busboy')
44
const util = require('../core/util')
5-
const { ReadableStreamFrom, toUSVString, isBlobLike, isReadableStreamLike, readableStreamClose } = require('./util')
5+
const { ReadableStreamFrom, isBlobLike, isReadableStreamLike, readableStreamClose } = require('./util')
66
const { FormData } = require('./formdata')
77
const { kState } = require('./symbols')
88
const { webidl } = require('./webidl')
@@ -66,9 +66,13 @@ function extractBody (object, keepalive = false) {
6666
let type = null
6767

6868
// 10. Switch on object:
69-
if (object == null) {
70-
// Note: The IDL processor cannot handle this situation. See
71-
// https://crbug.com/335871.
69+
if (typeof object === 'string') {
70+
// Set source to the UTF-8 encoding of object.
71+
// Note: setting source to a Uint8Array here breaks some mocking assumptions.
72+
source = object
73+
74+
// Set type to `text/plain;charset=UTF-8`.
75+
type = 'text/plain;charset=UTF-8'
7276
} else if (object instanceof URLSearchParams) {
7377
// URLSearchParams
7478

@@ -126,7 +130,8 @@ function extractBody (object, keepalive = false) {
126130

127131
yield * value.stream()
128132

129-
yield enc.encode('\r\n')
133+
// '\r\n' encoded
134+
yield new Uint8Array([13, 10])
130135
}
131136
}
132137

@@ -157,6 +162,11 @@ function extractBody (object, keepalive = false) {
157162
if (object.type) {
158163
type = object.type
159164
}
165+
} else if (object instanceof Uint8Array) {
166+
// byte sequence
167+
168+
// Set source to object.
169+
source = object
160170
} else if (typeof object[Symbol.asyncIterator] === 'function') {
161171
// If keepalive is true, then throw a TypeError.
162172
if (keepalive) {
@@ -172,17 +182,10 @@ function extractBody (object, keepalive = false) {
172182

173183
stream =
174184
object instanceof ReadableStream ? object : ReadableStreamFrom(object)
175-
} else {
176-
// TODO: byte sequence?
177-
// TODO: scalar value string?
178-
// TODO: else?
179-
source = toUSVString(object)
180-
type = 'text/plain;charset=UTF-8'
181185
}
182186

183187
// 11. If source is a byte sequence, then set action to a
184188
// step that returns source and length to source’s length.
185-
// TODO: What is a "byte sequence?"
186189
if (typeof source === 'string' || util.isBuffer(source)) {
187190
length = Buffer.byteLength(source)
188191
}
@@ -329,9 +332,7 @@ function bodyMixinMethods (instance) {
329332
},
330333

331334
async formData () {
332-
if (!(this instanceof instance)) {
333-
throw new TypeError('Illegal invocation')
334-
}
335+
webidl.brandCheck(this, instance)
335336

336337
throwIfAborted(this[kState])
337338

@@ -433,7 +434,7 @@ function bodyMixinMethods (instance) {
433434
throwIfAborted(this[kState])
434435

435436
// Otherwise, throw a TypeError.
436-
webidl.errors.exception({
437+
throw webidl.errors.exception({
437438
header: `${instance.name}.formData`,
438439
message: 'Could not parse content as FormData.'
439440
})
@@ -450,11 +451,8 @@ function mixinBody (prototype) {
450451

451452
// https://fetch.spec.whatwg.org/#concept-body-consume-body
452453
async function specConsumeBody (object, type, instance) {
453-
if (!(object instanceof instance)) {
454-
throw new TypeError('Illegal invocation')
455-
}
454+
webidl.brandCheck(object, instance)
456455

457-
// TODO: why is this needed?
458456
throwIfAborted(object[kState])
459457

460458
// 1. If object is unusable, then return a promise rejected

deps/undici/src/lib/fetch/constants.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ const nullBodyStatus = [101, 204, 205, 304]
88

99
const redirectStatus = [301, 302, 303, 307, 308]
1010

11+
// https://fetch.spec.whatwg.org/#block-bad-port
12+
const badPorts = [
13+
'1', '7', '9', '11', '13', '15', '17', '19', '20', '21', '22', '23', '25', '37', '42', '43', '53', '69', '77', '79',
14+
'87', '95', '101', '102', '103', '104', '109', '110', '111', '113', '115', '117', '119', '123', '135', '137',
15+
'139', '143', '161', '179', '389', '427', '465', '512', '513', '514', '515', '526', '530', '531', '532',
16+
'540', '548', '554', '556', '563', '587', '601', '636', '989', '990', '993', '995', '1719', '1720', '1723',
17+
'2049', '3659', '4045', '5060', '5061', '6000', '6566', '6665', '6666', '6667', '6668', '6669', '6697',
18+
'10080'
19+
]
20+
21+
// https://w3c.github.io/webappsec-referrer-policy/#referrer-policies
1122
const referrerPolicy = [
1223
'',
1324
'no-referrer',
@@ -44,6 +55,11 @@ const requestBodyHeader = [
4455
'content-type'
4556
]
4657

58+
// https://fetch.spec.whatwg.org/#enumdef-requestduplex
59+
const requestDuplex = [
60+
'half'
61+
]
62+
4763
// http://fetch.spec.whatwg.org/#forbidden-method
4864
const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK']
4965

@@ -108,5 +124,7 @@ module.exports = {
108124
redirectStatus,
109125
corsSafeListedMethods,
110126
nullBodyStatus,
111-
safeMethods
127+
safeMethods,
128+
badPorts,
129+
requestDuplex
112130
}

deps/undici/src/lib/fetch/dataURL.js

+5-70
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const assert = require('assert')
22
const { atob } = require('buffer')
3-
const { isValidHTTPToken } = require('./util')
3+
const { format } = require('url')
4+
const { isValidHTTPToken, isomorphicDecode } = require('./util')
45

56
const encoder = new TextEncoder()
67

@@ -54,15 +55,15 @@ function dataURLProcessor (dataURL) {
5455
const encodedBody = input.slice(mimeTypeLength + 1)
5556

5657
// 10. Let body be the percent-decoding of encodedBody.
57-
/** @type {Uint8Array|string} */
5858
let body = stringPercentDecode(encodedBody)
5959

6060
// 11. If mimeType ends with U+003B (;), followed by
6161
// zero or more U+0020 SPACE, followed by an ASCII
6262
// case-insensitive match for "base64", then:
6363
if (/;(\u0020){0,}base64$/i.test(mimeType)) {
6464
// 1. Let stringBody be the isomorphic decode of body.
65-
const stringBody = decodeURIComponent(new TextDecoder('utf-8').decode(body))
65+
const stringBody = isomorphicDecode(body)
66+
6667
// 2. Set body to the forgiving-base64 decode of
6768
// stringBody.
6869
body = forgivingBase64(stringBody)
@@ -111,73 +112,7 @@ function dataURLProcessor (dataURL) {
111112
* @param {boolean} excludeFragment
112113
*/
113114
function URLSerializer (url, excludeFragment = false) {
114-
// 1. Let output be url’s scheme and U+003A (:) concatenated.
115-
let output = url.protocol
116-
117-
// 2. If url’s host is non-null:
118-
if (url.host.length > 0) {
119-
// 1. Append "//" to output.
120-
output += '//'
121-
122-
// 2. If url includes credentials, then:
123-
if (url.username.length > 0 || url.password.length > 0) {
124-
// 1. Append url’s username to output.
125-
output += url.username
126-
127-
// 2. If url’s password is not the empty string, then append U+003A (:),
128-
// followed by url’s password, to output.
129-
if (url.password.length > 0) {
130-
output += ':' + url.password
131-
}
132-
133-
// 3. Append U+0040 (@) to output.
134-
output += '@'
135-
}
136-
137-
// 3. Append url’s host, serialized, to output.
138-
output += decodeURIComponent(url.hostname)
139-
140-
// 4. If url’s port is non-null, append U+003A (:) followed by url’s port,
141-
// serialized, to output.
142-
if (url.port.length > 0) {
143-
output += ':' + url.port
144-
}
145-
}
146-
147-
// 3. If url’s host is null, url does not have an opaque path,
148-
// url’s path’s size is greater than 1, and url’s path[0]
149-
// is the empty string, then append U+002F (/) followed by
150-
// U+002E (.) to output.
151-
// Note: This prevents web+demo:/.//not-a-host/ or web+demo:/path/..//not-a-host/,
152-
// when parsed and then serialized, from ending up as web+demo://not-a-host/
153-
// (they end up as web+demo:/.//not-a-host/).
154-
// Undici implementation note: url's path[0] can never be an
155-
// empty string, so we have to slightly alter what the spec says.
156-
if (
157-
url.host.length === 0 &&
158-
url.pathname.length > 1 &&
159-
url.href.slice(url.protocol.length + 1)[0] === '.'
160-
) {
161-
output += '/.'
162-
}
163-
164-
// 4. Append the result of URL path serializing url to output.
165-
output += url.pathname
166-
167-
// 5. If url’s query is non-null, append U+003F (?),
168-
// followed by url’s query, to output.
169-
if (url.search.length > 0) {
170-
output += url.search
171-
}
172-
173-
// 6. If exclude fragment is false and url’s fragment is non-null,
174-
// then append U+0023 (#), followed by url’s fragment, to output.
175-
if (excludeFragment === false && url.hash.length > 0) {
176-
output += url.hash
177-
}
178-
179-
// 7. Return output.
180-
return output
115+
return format(url, { fragment: !excludeFragment })
181116
}
182117

183118
// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points

0 commit comments

Comments
 (0)