deepv-code 1.0.182 → 1.0.185
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.
- package/bundle/dvcode.js +757 -753
- package/package.json +1 -1
- package/bundle/assets/help/README.md +0 -113
- package/bundle/assets/sounds/README.md +0 -74
- package/bundle/node_modules/undici/LICENSE +0 -21
- package/bundle/node_modules/undici/README.md +0 -472
- package/bundle/node_modules/undici/docs/docs/api/Agent.md +0 -83
- package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
- package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
- package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +0 -151
- package/bundle/node_modules/undici/docs/docs/api/Client.md +0 -281
- package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
- package/bundle/node_modules/undici/docs/docs/api/Connector.md +0 -115
- package/bundle/node_modules/undici/docs/docs/api/ContentType.md +0 -57
- package/bundle/node_modules/undici/docs/docs/api/Cookies.md +0 -101
- package/bundle/node_modules/undici/docs/docs/api/Debug.md +0 -62
- package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -204
- package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1200
- package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
- package/bundle/node_modules/undici/docs/docs/api/Errors.md +0 -49
- package/bundle/node_modules/undici/docs/docs/api/EventSource.md +0 -45
- package/bundle/node_modules/undici/docs/docs/api/Fetch.md +0 -52
- package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +0 -262
- package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
- package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
- package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
- package/bundle/node_modules/undici/docs/docs/api/MockClient.md +0 -77
- package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
- package/bundle/node_modules/undici/docs/docs/api/MockPool.md +0 -548
- package/bundle/node_modules/undici/docs/docs/api/Pool.md +0 -84
- package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
- package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -227
- package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -96
- package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +0 -45
- package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +0 -117
- package/bundle/node_modules/undici/docs/docs/api/Util.md +0 -25
- package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +0 -85
- package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
- package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
- package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
- package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
- package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -20
- package/bundle/node_modules/undici/index-fetch.js +0 -35
- package/bundle/node_modules/undici/index.d.ts +0 -3
- package/bundle/node_modules/undici/index.js +0 -183
- package/bundle/node_modules/undici/lib/api/abort-signal.js +0 -59
- package/bundle/node_modules/undici/lib/api/api-connect.js +0 -110
- package/bundle/node_modules/undici/lib/api/api-pipeline.js +0 -252
- package/bundle/node_modules/undici/lib/api/api-request.js +0 -199
- package/bundle/node_modules/undici/lib/api/api-stream.js +0 -209
- package/bundle/node_modules/undici/lib/api/api-upgrade.js +0 -110
- package/bundle/node_modules/undici/lib/api/index.js +0 -7
- package/bundle/node_modules/undici/lib/api/readable.js +0 -558
- package/bundle/node_modules/undici/lib/api/util.js +0 -95
- package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
- package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
- package/bundle/node_modules/undici/lib/core/connect.js +0 -164
- package/bundle/node_modules/undici/lib/core/constants.js +0 -143
- package/bundle/node_modules/undici/lib/core/diagnostics.js +0 -196
- package/bundle/node_modules/undici/lib/core/errors.js +0 -244
- package/bundle/node_modules/undici/lib/core/request.js +0 -397
- package/bundle/node_modules/undici/lib/core/symbols.js +0 -68
- package/bundle/node_modules/undici/lib/core/tree.js +0 -160
- package/bundle/node_modules/undici/lib/core/util.js +0 -988
- package/bundle/node_modules/undici/lib/dispatcher/agent.js +0 -135
- package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -206
- package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +0 -1615
- package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +0 -798
- package/bundle/node_modules/undici/lib/dispatcher/client.js +0 -614
- package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -161
- package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
- package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -151
- package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -159
- package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +0 -122
- package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +0 -191
- package/bundle/node_modules/undici/lib/dispatcher/pool.js +0 -118
- package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -275
- package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
- package/bundle/node_modules/undici/lib/global.js +0 -32
- package/bundle/node_modules/undici/lib/handler/cache-handler.js +0 -448
- package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
- package/bundle/node_modules/undici/lib/handler/decorator-handler.js +0 -67
- package/bundle/node_modules/undici/lib/handler/redirect-handler.js +0 -227
- package/bundle/node_modules/undici/lib/handler/retry-handler.js +0 -342
- package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +0 -96
- package/bundle/node_modules/undici/lib/handler/wrap-handler.js +0 -95
- package/bundle/node_modules/undici/lib/interceptor/cache.js +0 -372
- package/bundle/node_modules/undici/lib/interceptor/dns.js +0 -432
- package/bundle/node_modules/undici/lib/interceptor/dump.js +0 -111
- package/bundle/node_modules/undici/lib/interceptor/redirect.js +0 -21
- package/bundle/node_modules/undici/lib/interceptor/response-error.js +0 -95
- package/bundle/node_modules/undici/lib/interceptor/retry.js +0 -19
- package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +0 -97
- package/bundle/node_modules/undici/lib/llhttp/constants.js +0 -498
- package/bundle/node_modules/undici/lib/llhttp/constants.js.map +0 -1
- package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
- package/bundle/node_modules/undici/lib/llhttp/utils.js +0 -15
- package/bundle/node_modules/undici/lib/llhttp/utils.js.map +0 -1
- package/bundle/node_modules/undici/lib/mock/mock-agent.js +0 -224
- package/bundle/node_modules/undici/lib/mock/mock-call-history.js +0 -248
- package/bundle/node_modules/undici/lib/mock/mock-client.js +0 -64
- package/bundle/node_modules/undici/lib/mock/mock-errors.js +0 -19
- package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
- package/bundle/node_modules/undici/lib/mock/mock-pool.js +0 -64
- package/bundle/node_modules/undici/lib/mock/mock-symbols.js +0 -31
- package/bundle/node_modules/undici/lib/mock/mock-utils.js +0 -433
- package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
- package/bundle/node_modules/undici/lib/util/cache.js +0 -368
- package/bundle/node_modules/undici/lib/util/date.js +0 -259
- package/bundle/node_modules/undici/lib/util/stats.js +0 -32
- package/bundle/node_modules/undici/lib/util/timers.js +0 -423
- package/bundle/node_modules/undici/lib/web/cache/cache.js +0 -862
- package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
- package/bundle/node_modules/undici/lib/web/cache/util.js +0 -45
- package/bundle/node_modules/undici/lib/web/cookies/constants.js +0 -12
- package/bundle/node_modules/undici/lib/web/cookies/index.js +0 -199
- package/bundle/node_modules/undici/lib/web/cookies/parse.js +0 -322
- package/bundle/node_modules/undici/lib/web/cookies/util.js +0 -282
- package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
- package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +0 -484
- package/bundle/node_modules/undici/lib/web/eventsource/util.js +0 -37
- package/bundle/node_modules/undici/lib/web/fetch/LICENSE +0 -21
- package/bundle/node_modules/undici/lib/web/fetch/body.js +0 -532
- package/bundle/node_modules/undici/lib/web/fetch/constants.js +0 -131
- package/bundle/node_modules/undici/lib/web/fetch/data-url.js +0 -744
- package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +0 -46
- package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -501
- package/bundle/node_modules/undici/lib/web/fetch/formdata.js +0 -263
- package/bundle/node_modules/undici/lib/web/fetch/global.js +0 -40
- package/bundle/node_modules/undici/lib/web/fetch/headers.js +0 -719
- package/bundle/node_modules/undici/lib/web/fetch/index.js +0 -2258
- package/bundle/node_modules/undici/lib/web/fetch/request.js +0 -1099
- package/bundle/node_modules/undici/lib/web/fetch/response.js +0 -636
- package/bundle/node_modules/undici/lib/web/fetch/util.js +0 -1782
- package/bundle/node_modules/undici/lib/web/fetch/webidl.js +0 -740
- package/bundle/node_modules/undici/lib/web/websocket/connection.js +0 -325
- package/bundle/node_modules/undici/lib/web/websocket/constants.js +0 -126
- package/bundle/node_modules/undici/lib/web/websocket/events.js +0 -331
- package/bundle/node_modules/undici/lib/web/websocket/frame.js +0 -138
- package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -70
- package/bundle/node_modules/undici/lib/web/websocket/receiver.js +0 -454
- package/bundle/node_modules/undici/lib/web/websocket/sender.js +0 -109
- package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -83
- package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -485
- package/bundle/node_modules/undici/lib/web/websocket/util.js +0 -338
- package/bundle/node_modules/undici/lib/web/websocket/websocket.js +0 -686
- package/bundle/node_modules/undici/package.json +0 -149
- package/bundle/node_modules/undici/scripts/strip-comments.js +0 -10
- package/bundle/node_modules/undici/types/README.md +0 -6
- package/bundle/node_modules/undici/types/agent.d.ts +0 -35
- package/bundle/node_modules/undici/types/api.d.ts +0 -43
- package/bundle/node_modules/undici/types/balanced-pool.d.ts +0 -29
- package/bundle/node_modules/undici/types/cache-interceptor.d.ts +0 -172
- package/bundle/node_modules/undici/types/cache.d.ts +0 -36
- package/bundle/node_modules/undici/types/client-stats.d.ts +0 -15
- package/bundle/node_modules/undici/types/client.d.ts +0 -110
- package/bundle/node_modules/undici/types/connector.d.ts +0 -34
- package/bundle/node_modules/undici/types/content-type.d.ts +0 -21
- package/bundle/node_modules/undici/types/cookies.d.ts +0 -30
- package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +0 -66
- package/bundle/node_modules/undici/types/dispatcher.d.ts +0 -281
- package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -21
- package/bundle/node_modules/undici/types/errors.d.ts +0 -171
- package/bundle/node_modules/undici/types/eventsource.d.ts +0 -61
- package/bundle/node_modules/undici/types/fetch.d.ts +0 -210
- package/bundle/node_modules/undici/types/formdata.d.ts +0 -108
- package/bundle/node_modules/undici/types/global-dispatcher.d.ts +0 -9
- package/bundle/node_modules/undici/types/global-origin.d.ts +0 -7
- package/bundle/node_modules/undici/types/h2c-client.d.ts +0 -75
- package/bundle/node_modules/undici/types/handlers.d.ts +0 -15
- package/bundle/node_modules/undici/types/header.d.ts +0 -160
- package/bundle/node_modules/undici/types/index.d.ts +0 -75
- package/bundle/node_modules/undici/types/interceptors.d.ts +0 -34
- package/bundle/node_modules/undici/types/mock-agent.d.ts +0 -68
- package/bundle/node_modules/undici/types/mock-call-history.d.ts +0 -111
- package/bundle/node_modules/undici/types/mock-client.d.ts +0 -25
- package/bundle/node_modules/undici/types/mock-errors.d.ts +0 -12
- package/bundle/node_modules/undici/types/mock-interceptor.d.ts +0 -93
- package/bundle/node_modules/undici/types/mock-pool.d.ts +0 -25
- package/bundle/node_modules/undici/types/patch.d.ts +0 -29
- package/bundle/node_modules/undici/types/pool-stats.d.ts +0 -19
- package/bundle/node_modules/undici/types/pool.d.ts +0 -41
- package/bundle/node_modules/undici/types/proxy-agent.d.ts +0 -29
- package/bundle/node_modules/undici/types/readable.d.ts +0 -68
- package/bundle/node_modules/undici/types/retry-agent.d.ts +0 -8
- package/bundle/node_modules/undici/types/retry-handler.d.ts +0 -116
- package/bundle/node_modules/undici/types/util.d.ts +0 -18
- package/bundle/node_modules/undici/types/utility.d.ts +0 -7
- package/bundle/node_modules/undici/types/webidl.d.ts +0 -266
- package/bundle/node_modules/undici/types/websocket.d.ts +0 -184
|
@@ -1,988 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const assert = require('node:assert')
|
|
4
|
-
const { kDestroyed, kBodyUsed, kListeners, kBody } = require('./symbols')
|
|
5
|
-
const { IncomingMessage } = require('node:http')
|
|
6
|
-
const stream = require('node:stream')
|
|
7
|
-
const net = require('node:net')
|
|
8
|
-
const { Blob } = require('node:buffer')
|
|
9
|
-
const nodeUtil = require('node:util')
|
|
10
|
-
const { stringify } = require('node:querystring')
|
|
11
|
-
const { EventEmitter: EE } = require('node:events')
|
|
12
|
-
const timers = require('../util/timers')
|
|
13
|
-
const { InvalidArgumentError, ConnectTimeoutError } = require('./errors')
|
|
14
|
-
const { headerNameLowerCasedRecord } = require('./constants')
|
|
15
|
-
const { tree } = require('./tree')
|
|
16
|
-
|
|
17
|
-
const [nodeMajor, nodeMinor] = process.versions.node.split('.', 2).map(v => Number(v))
|
|
18
|
-
|
|
19
|
-
class BodyAsyncIterable {
|
|
20
|
-
constructor (body) {
|
|
21
|
-
this[kBody] = body
|
|
22
|
-
this[kBodyUsed] = false
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async * [Symbol.asyncIterator] () {
|
|
26
|
-
assert(!this[kBodyUsed], 'disturbed')
|
|
27
|
-
this[kBodyUsed] = true
|
|
28
|
-
yield * this[kBody]
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function noop () {}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @param {*} body
|
|
36
|
-
* @returns {*}
|
|
37
|
-
*/
|
|
38
|
-
function wrapRequestBody (body) {
|
|
39
|
-
if (isStream(body)) {
|
|
40
|
-
// TODO (fix): Provide some way for the user to cache the file to e.g. /tmp
|
|
41
|
-
// so that it can be dispatched again?
|
|
42
|
-
// TODO (fix): Do we need 100-expect support to provide a way to do this properly?
|
|
43
|
-
if (bodyLength(body) === 0) {
|
|
44
|
-
body
|
|
45
|
-
.on('data', function () {
|
|
46
|
-
assert(false)
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (typeof body.readableDidRead !== 'boolean') {
|
|
51
|
-
body[kBodyUsed] = false
|
|
52
|
-
EE.prototype.on.call(body, 'data', function () {
|
|
53
|
-
this[kBodyUsed] = true
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return body
|
|
58
|
-
} else if (body && typeof body.pipeTo === 'function') {
|
|
59
|
-
// TODO (fix): We can't access ReadableStream internal state
|
|
60
|
-
// to determine whether or not it has been disturbed. This is just
|
|
61
|
-
// a workaround.
|
|
62
|
-
return new BodyAsyncIterable(body)
|
|
63
|
-
} else if (
|
|
64
|
-
body &&
|
|
65
|
-
typeof body !== 'string' &&
|
|
66
|
-
!ArrayBuffer.isView(body) &&
|
|
67
|
-
isIterable(body)
|
|
68
|
-
) {
|
|
69
|
-
// TODO: Should we allow re-using iterable if !this.opts.idempotent
|
|
70
|
-
// or through some other flag?
|
|
71
|
-
return new BodyAsyncIterable(body)
|
|
72
|
-
} else {
|
|
73
|
-
return body
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @param {*} obj
|
|
79
|
-
* @returns {obj is import('node:stream').Stream}
|
|
80
|
-
*/
|
|
81
|
-
function isStream (obj) {
|
|
82
|
-
return obj && typeof obj === 'object' && typeof obj.pipe === 'function' && typeof obj.on === 'function'
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @param {*} object
|
|
87
|
-
* @returns {object is Blob}
|
|
88
|
-
* based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License)
|
|
89
|
-
*/
|
|
90
|
-
function isBlobLike (object) {
|
|
91
|
-
if (object === null) {
|
|
92
|
-
return false
|
|
93
|
-
} else if (object instanceof Blob) {
|
|
94
|
-
return true
|
|
95
|
-
} else if (typeof object !== 'object') {
|
|
96
|
-
return false
|
|
97
|
-
} else {
|
|
98
|
-
const sTag = object[Symbol.toStringTag]
|
|
99
|
-
|
|
100
|
-
return (sTag === 'Blob' || sTag === 'File') && (
|
|
101
|
-
('stream' in object && typeof object.stream === 'function') ||
|
|
102
|
-
('arrayBuffer' in object && typeof object.arrayBuffer === 'function')
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @param {string} url The URL to add the query params to
|
|
109
|
-
* @param {import('node:querystring').ParsedUrlQueryInput} queryParams The object to serialize into a URL query string
|
|
110
|
-
* @returns {string} The URL with the query params added
|
|
111
|
-
*/
|
|
112
|
-
function serializePathWithQuery (url, queryParams) {
|
|
113
|
-
if (url.includes('?') || url.includes('#')) {
|
|
114
|
-
throw new Error('Query params cannot be passed when url already contains "?" or "#".')
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const stringified = stringify(queryParams)
|
|
118
|
-
|
|
119
|
-
if (stringified) {
|
|
120
|
-
url += '?' + stringified
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return url
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @param {number|string|undefined} port
|
|
128
|
-
* @returns {boolean}
|
|
129
|
-
*/
|
|
130
|
-
function isValidPort (port) {
|
|
131
|
-
const value = parseInt(port, 10)
|
|
132
|
-
return (
|
|
133
|
-
value === Number(port) &&
|
|
134
|
-
value >= 0 &&
|
|
135
|
-
value <= 65535
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Check if the value is a valid http or https prefixed string.
|
|
141
|
-
*
|
|
142
|
-
* @param {string} value
|
|
143
|
-
* @returns {boolean}
|
|
144
|
-
*/
|
|
145
|
-
function isHttpOrHttpsPrefixed (value) {
|
|
146
|
-
return (
|
|
147
|
-
value != null &&
|
|
148
|
-
value[0] === 'h' &&
|
|
149
|
-
value[1] === 't' &&
|
|
150
|
-
value[2] === 't' &&
|
|
151
|
-
value[3] === 'p' &&
|
|
152
|
-
(
|
|
153
|
-
value[4] === ':' ||
|
|
154
|
-
(
|
|
155
|
-
value[4] === 's' &&
|
|
156
|
-
value[5] === ':'
|
|
157
|
-
)
|
|
158
|
-
)
|
|
159
|
-
)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @param {string|URL|Record<string,string>} url
|
|
164
|
-
* @returns {URL}
|
|
165
|
-
*/
|
|
166
|
-
function parseURL (url) {
|
|
167
|
-
if (typeof url === 'string') {
|
|
168
|
-
/**
|
|
169
|
-
* @type {URL}
|
|
170
|
-
*/
|
|
171
|
-
url = new URL(url)
|
|
172
|
-
|
|
173
|
-
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
174
|
-
throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return url
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (!url || typeof url !== 'object') {
|
|
181
|
-
throw new InvalidArgumentError('Invalid URL: The URL argument must be a non-null object.')
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (!(url instanceof URL)) {
|
|
185
|
-
if (url.port != null && url.port !== '' && isValidPort(url.port) === false) {
|
|
186
|
-
throw new InvalidArgumentError('Invalid URL: port must be a valid integer or a string representation of an integer.')
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (url.path != null && typeof url.path !== 'string') {
|
|
190
|
-
throw new InvalidArgumentError('Invalid URL path: the path must be a string or null/undefined.')
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (url.pathname != null && typeof url.pathname !== 'string') {
|
|
194
|
-
throw new InvalidArgumentError('Invalid URL pathname: the pathname must be a string or null/undefined.')
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (url.hostname != null && typeof url.hostname !== 'string') {
|
|
198
|
-
throw new InvalidArgumentError('Invalid URL hostname: the hostname must be a string or null/undefined.')
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (url.origin != null && typeof url.origin !== 'string') {
|
|
202
|
-
throw new InvalidArgumentError('Invalid URL origin: the origin must be a string or null/undefined.')
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
206
|
-
throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const port = url.port != null
|
|
210
|
-
? url.port
|
|
211
|
-
: (url.protocol === 'https:' ? 443 : 80)
|
|
212
|
-
let origin = url.origin != null
|
|
213
|
-
? url.origin
|
|
214
|
-
: `${url.protocol || ''}//${url.hostname || ''}:${port}`
|
|
215
|
-
let path = url.path != null
|
|
216
|
-
? url.path
|
|
217
|
-
: `${url.pathname || ''}${url.search || ''}`
|
|
218
|
-
|
|
219
|
-
if (origin[origin.length - 1] === '/') {
|
|
220
|
-
origin = origin.slice(0, origin.length - 1)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (path && path[0] !== '/') {
|
|
224
|
-
path = `/${path}`
|
|
225
|
-
}
|
|
226
|
-
// new URL(path, origin) is unsafe when `path` contains an absolute URL
|
|
227
|
-
// From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL:
|
|
228
|
-
// If first parameter is a relative URL, second param is required, and will be used as the base URL.
|
|
229
|
-
// If first parameter is an absolute URL, a given second param will be ignored.
|
|
230
|
-
return new URL(`${origin}${path}`)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
234
|
-
throw new InvalidArgumentError('Invalid URL protocol: the URL must start with `http:` or `https:`.')
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return url
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* @param {string|URL|Record<string, string>} url
|
|
242
|
-
* @returns {URL}
|
|
243
|
-
*/
|
|
244
|
-
function parseOrigin (url) {
|
|
245
|
-
url = parseURL(url)
|
|
246
|
-
|
|
247
|
-
if (url.pathname !== '/' || url.search || url.hash) {
|
|
248
|
-
throw new InvalidArgumentError('invalid url')
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return url
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* @param {string} host
|
|
256
|
-
* @returns {string}
|
|
257
|
-
*/
|
|
258
|
-
function getHostname (host) {
|
|
259
|
-
if (host[0] === '[') {
|
|
260
|
-
const idx = host.indexOf(']')
|
|
261
|
-
|
|
262
|
-
assert(idx !== -1)
|
|
263
|
-
return host.substring(1, idx)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const idx = host.indexOf(':')
|
|
267
|
-
if (idx === -1) return host
|
|
268
|
-
|
|
269
|
-
return host.substring(0, idx)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* IP addresses are not valid server names per RFC6066
|
|
274
|
-
* Currently, the only server names supported are DNS hostnames
|
|
275
|
-
* @param {string|null} host
|
|
276
|
-
* @returns {string|null}
|
|
277
|
-
*/
|
|
278
|
-
function getServerName (host) {
|
|
279
|
-
if (!host) {
|
|
280
|
-
return null
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
assert(typeof host === 'string')
|
|
284
|
-
|
|
285
|
-
const servername = getHostname(host)
|
|
286
|
-
if (net.isIP(servername)) {
|
|
287
|
-
return ''
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return servername
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* @function
|
|
295
|
-
* @template T
|
|
296
|
-
* @param {T} obj
|
|
297
|
-
* @returns {T}
|
|
298
|
-
*/
|
|
299
|
-
function deepClone (obj) {
|
|
300
|
-
return JSON.parse(JSON.stringify(obj))
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* @param {*} obj
|
|
305
|
-
* @returns {obj is AsyncIterable}
|
|
306
|
-
*/
|
|
307
|
-
function isAsyncIterable (obj) {
|
|
308
|
-
return !!(obj != null && typeof obj[Symbol.asyncIterator] === 'function')
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* @param {*} obj
|
|
313
|
-
* @returns {obj is Iterable}
|
|
314
|
-
*/
|
|
315
|
-
function isIterable (obj) {
|
|
316
|
-
return !!(obj != null && (typeof obj[Symbol.iterator] === 'function' || typeof obj[Symbol.asyncIterator] === 'function'))
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* @param {Blob|Buffer|import ('stream').Stream} body
|
|
321
|
-
* @returns {number|null}
|
|
322
|
-
*/
|
|
323
|
-
function bodyLength (body) {
|
|
324
|
-
if (body == null) {
|
|
325
|
-
return 0
|
|
326
|
-
} else if (isStream(body)) {
|
|
327
|
-
const state = body._readableState
|
|
328
|
-
return state && state.objectMode === false && state.ended === true && Number.isFinite(state.length)
|
|
329
|
-
? state.length
|
|
330
|
-
: null
|
|
331
|
-
} else if (isBlobLike(body)) {
|
|
332
|
-
return body.size != null ? body.size : null
|
|
333
|
-
} else if (isBuffer(body)) {
|
|
334
|
-
return body.byteLength
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
return null
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* @param {import ('stream').Stream} body
|
|
342
|
-
* @returns {boolean}
|
|
343
|
-
*/
|
|
344
|
-
function isDestroyed (body) {
|
|
345
|
-
return body && !!(body.destroyed || body[kDestroyed] || (stream.isDestroyed?.(body)))
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* @param {import ('stream').Stream} stream
|
|
350
|
-
* @param {Error} [err]
|
|
351
|
-
* @returns {void}
|
|
352
|
-
*/
|
|
353
|
-
function destroy (stream, err) {
|
|
354
|
-
if (stream == null || !isStream(stream) || isDestroyed(stream)) {
|
|
355
|
-
return
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (typeof stream.destroy === 'function') {
|
|
359
|
-
if (Object.getPrototypeOf(stream).constructor === IncomingMessage) {
|
|
360
|
-
// See: https://github.com/nodejs/node/pull/38505/files
|
|
361
|
-
stream.socket = null
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
stream.destroy(err)
|
|
365
|
-
} else if (err) {
|
|
366
|
-
queueMicrotask(() => {
|
|
367
|
-
stream.emit('error', err)
|
|
368
|
-
})
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
if (stream.destroyed !== true) {
|
|
372
|
-
stream[kDestroyed] = true
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/
|
|
377
|
-
/**
|
|
378
|
-
* @param {string} val
|
|
379
|
-
* @returns {number | null}
|
|
380
|
-
*/
|
|
381
|
-
function parseKeepAliveTimeout (val) {
|
|
382
|
-
const m = val.match(KEEPALIVE_TIMEOUT_EXPR)
|
|
383
|
-
return m ? parseInt(m[1], 10) * 1000 : null
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Retrieves a header name and returns its lowercase value.
|
|
388
|
-
* @param {string | Buffer} value Header name
|
|
389
|
-
* @returns {string}
|
|
390
|
-
*/
|
|
391
|
-
function headerNameToString (value) {
|
|
392
|
-
return typeof value === 'string'
|
|
393
|
-
? headerNameLowerCasedRecord[value] ?? value.toLowerCase()
|
|
394
|
-
: tree.lookup(value) ?? value.toString('latin1').toLowerCase()
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Receive the buffer as a string and return its lowercase value.
|
|
399
|
-
* @param {Buffer} value Header name
|
|
400
|
-
* @returns {string}
|
|
401
|
-
*/
|
|
402
|
-
function bufferToLowerCasedHeaderName (value) {
|
|
403
|
-
return tree.lookup(value) ?? value.toString('latin1').toLowerCase()
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* @param {(Buffer | string)[]} headers
|
|
408
|
-
* @param {Record<string, string | string[]>} [obj]
|
|
409
|
-
* @returns {Record<string, string | string[]>}
|
|
410
|
-
*/
|
|
411
|
-
function parseHeaders (headers, obj) {
|
|
412
|
-
if (obj === undefined) obj = {}
|
|
413
|
-
|
|
414
|
-
for (let i = 0; i < headers.length; i += 2) {
|
|
415
|
-
const key = headerNameToString(headers[i])
|
|
416
|
-
let val = obj[key]
|
|
417
|
-
|
|
418
|
-
if (val) {
|
|
419
|
-
if (typeof val === 'string') {
|
|
420
|
-
val = [val]
|
|
421
|
-
obj[key] = val
|
|
422
|
-
}
|
|
423
|
-
val.push(headers[i + 1].toString('utf8'))
|
|
424
|
-
} else {
|
|
425
|
-
const headersValue = headers[i + 1]
|
|
426
|
-
if (typeof headersValue === 'string') {
|
|
427
|
-
obj[key] = headersValue
|
|
428
|
-
} else {
|
|
429
|
-
obj[key] = Array.isArray(headersValue) ? headersValue.map(x => x.toString('utf8')) : headersValue.toString('utf8')
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
// See https://github.com/nodejs/node/pull/46528
|
|
435
|
-
if ('content-length' in obj && 'content-disposition' in obj) {
|
|
436
|
-
obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1')
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
return obj
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* @param {Buffer[]} headers
|
|
444
|
-
* @returns {string[]}
|
|
445
|
-
*/
|
|
446
|
-
function parseRawHeaders (headers) {
|
|
447
|
-
const headersLength = headers.length
|
|
448
|
-
/**
|
|
449
|
-
* @type {string[]}
|
|
450
|
-
*/
|
|
451
|
-
const ret = new Array(headersLength)
|
|
452
|
-
|
|
453
|
-
let hasContentLength = false
|
|
454
|
-
let contentDispositionIdx = -1
|
|
455
|
-
let key
|
|
456
|
-
let val
|
|
457
|
-
let kLen = 0
|
|
458
|
-
|
|
459
|
-
for (let n = 0; n < headersLength; n += 2) {
|
|
460
|
-
key = headers[n]
|
|
461
|
-
val = headers[n + 1]
|
|
462
|
-
|
|
463
|
-
typeof key !== 'string' && (key = key.toString())
|
|
464
|
-
typeof val !== 'string' && (val = val.toString('utf8'))
|
|
465
|
-
|
|
466
|
-
kLen = key.length
|
|
467
|
-
if (kLen === 14 && key[7] === '-' && (key === 'content-length' || key.toLowerCase() === 'content-length')) {
|
|
468
|
-
hasContentLength = true
|
|
469
|
-
} else if (kLen === 19 && key[7] === '-' && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) {
|
|
470
|
-
contentDispositionIdx = n + 1
|
|
471
|
-
}
|
|
472
|
-
ret[n] = key
|
|
473
|
-
ret[n + 1] = val
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// See https://github.com/nodejs/node/pull/46528
|
|
477
|
-
if (hasContentLength && contentDispositionIdx !== -1) {
|
|
478
|
-
ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1')
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
return ret
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* @param {string[]} headers
|
|
486
|
-
* @param {Buffer[]} headers
|
|
487
|
-
*/
|
|
488
|
-
function encodeRawHeaders (headers) {
|
|
489
|
-
if (!Array.isArray(headers)) {
|
|
490
|
-
throw new TypeError('expected headers to be an array')
|
|
491
|
-
}
|
|
492
|
-
return headers.map(x => Buffer.from(x))
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* @param {*} buffer
|
|
497
|
-
* @returns {buffer is Buffer}
|
|
498
|
-
*/
|
|
499
|
-
function isBuffer (buffer) {
|
|
500
|
-
// See, https://github.com/mcollina/undici/pull/319
|
|
501
|
-
return buffer instanceof Uint8Array || Buffer.isBuffer(buffer)
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Asserts that the handler object is a request handler.
|
|
506
|
-
*
|
|
507
|
-
* @param {object} handler
|
|
508
|
-
* @param {string} method
|
|
509
|
-
* @param {string} [upgrade]
|
|
510
|
-
* @returns {asserts handler is import('../api/api-request').RequestHandler}
|
|
511
|
-
*/
|
|
512
|
-
function assertRequestHandler (handler, method, upgrade) {
|
|
513
|
-
if (!handler || typeof handler !== 'object') {
|
|
514
|
-
throw new InvalidArgumentError('handler must be an object')
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
if (typeof handler.onRequestStart === 'function') {
|
|
518
|
-
// TODO (fix): More checks...
|
|
519
|
-
return
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
if (typeof handler.onConnect !== 'function') {
|
|
523
|
-
throw new InvalidArgumentError('invalid onConnect method')
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
if (typeof handler.onError !== 'function') {
|
|
527
|
-
throw new InvalidArgumentError('invalid onError method')
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
if (typeof handler.onBodySent !== 'function' && handler.onBodySent !== undefined) {
|
|
531
|
-
throw new InvalidArgumentError('invalid onBodySent method')
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
if (upgrade || method === 'CONNECT') {
|
|
535
|
-
if (typeof handler.onUpgrade !== 'function') {
|
|
536
|
-
throw new InvalidArgumentError('invalid onUpgrade method')
|
|
537
|
-
}
|
|
538
|
-
} else {
|
|
539
|
-
if (typeof handler.onHeaders !== 'function') {
|
|
540
|
-
throw new InvalidArgumentError('invalid onHeaders method')
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
if (typeof handler.onData !== 'function') {
|
|
544
|
-
throw new InvalidArgumentError('invalid onData method')
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
if (typeof handler.onComplete !== 'function') {
|
|
548
|
-
throw new InvalidArgumentError('invalid onComplete method')
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* A body is disturbed if it has been read from and it cannot be re-used without
|
|
555
|
-
* losing state or data.
|
|
556
|
-
* @param {import('node:stream').Readable} body
|
|
557
|
-
* @returns {boolean}
|
|
558
|
-
*/
|
|
559
|
-
function isDisturbed (body) {
|
|
560
|
-
// TODO (fix): Why is body[kBodyUsed] needed?
|
|
561
|
-
return !!(body && (stream.isDisturbed(body) || body[kBodyUsed]))
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
/**
|
|
565
|
-
* @typedef {object} SocketInfo
|
|
566
|
-
* @property {string} [localAddress]
|
|
567
|
-
* @property {number} [localPort]
|
|
568
|
-
* @property {string} [remoteAddress]
|
|
569
|
-
* @property {number} [remotePort]
|
|
570
|
-
* @property {string} [remoteFamily]
|
|
571
|
-
* @property {number} [timeout]
|
|
572
|
-
* @property {number} bytesWritten
|
|
573
|
-
* @property {number} bytesRead
|
|
574
|
-
*/
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* @param {import('net').Socket} socket
|
|
578
|
-
* @returns {SocketInfo}
|
|
579
|
-
*/
|
|
580
|
-
function getSocketInfo (socket) {
|
|
581
|
-
return {
|
|
582
|
-
localAddress: socket.localAddress,
|
|
583
|
-
localPort: socket.localPort,
|
|
584
|
-
remoteAddress: socket.remoteAddress,
|
|
585
|
-
remotePort: socket.remotePort,
|
|
586
|
-
remoteFamily: socket.remoteFamily,
|
|
587
|
-
timeout: socket.timeout,
|
|
588
|
-
bytesWritten: socket.bytesWritten,
|
|
589
|
-
bytesRead: socket.bytesRead
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* @param {Iterable} iterable
|
|
595
|
-
* @returns {ReadableStream}
|
|
596
|
-
*/
|
|
597
|
-
function ReadableStreamFrom (iterable) {
|
|
598
|
-
// We cannot use ReadableStream.from here because it does not return a byte stream.
|
|
599
|
-
|
|
600
|
-
let iterator
|
|
601
|
-
return new ReadableStream(
|
|
602
|
-
{
|
|
603
|
-
async start () {
|
|
604
|
-
iterator = iterable[Symbol.asyncIterator]()
|
|
605
|
-
},
|
|
606
|
-
pull (controller) {
|
|
607
|
-
async function pull () {
|
|
608
|
-
const { done, value } = await iterator.next()
|
|
609
|
-
if (done) {
|
|
610
|
-
queueMicrotask(() => {
|
|
611
|
-
controller.close()
|
|
612
|
-
controller.byobRequest?.respond(0)
|
|
613
|
-
})
|
|
614
|
-
} else {
|
|
615
|
-
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value)
|
|
616
|
-
if (buf.byteLength) {
|
|
617
|
-
controller.enqueue(new Uint8Array(buf))
|
|
618
|
-
} else {
|
|
619
|
-
return await pull()
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
return pull()
|
|
625
|
-
},
|
|
626
|
-
async cancel () {
|
|
627
|
-
await iterator.return()
|
|
628
|
-
},
|
|
629
|
-
type: 'bytes'
|
|
630
|
-
}
|
|
631
|
-
)
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
/**
|
|
635
|
-
* The object should be a FormData instance and contains all the required
|
|
636
|
-
* methods.
|
|
637
|
-
* @param {*} object
|
|
638
|
-
* @returns {object is FormData}
|
|
639
|
-
*/
|
|
640
|
-
function isFormDataLike (object) {
|
|
641
|
-
return (
|
|
642
|
-
object &&
|
|
643
|
-
typeof object === 'object' &&
|
|
644
|
-
typeof object.append === 'function' &&
|
|
645
|
-
typeof object.delete === 'function' &&
|
|
646
|
-
typeof object.get === 'function' &&
|
|
647
|
-
typeof object.getAll === 'function' &&
|
|
648
|
-
typeof object.has === 'function' &&
|
|
649
|
-
typeof object.set === 'function' &&
|
|
650
|
-
object[Symbol.toStringTag] === 'FormData'
|
|
651
|
-
)
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
function addAbortListener (signal, listener) {
|
|
655
|
-
if ('addEventListener' in signal) {
|
|
656
|
-
signal.addEventListener('abort', listener, { once: true })
|
|
657
|
-
return () => signal.removeEventListener('abort', listener)
|
|
658
|
-
}
|
|
659
|
-
signal.once('abort', listener)
|
|
660
|
-
return () => signal.removeListener('abort', listener)
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
/**
|
|
664
|
-
* @function
|
|
665
|
-
* @param {string} value
|
|
666
|
-
* @returns {string}
|
|
667
|
-
*/
|
|
668
|
-
const toUSVString = (() => {
|
|
669
|
-
if (typeof String.prototype.toWellFormed === 'function') {
|
|
670
|
-
/**
|
|
671
|
-
* @param {string} value
|
|
672
|
-
* @returns {string}
|
|
673
|
-
*/
|
|
674
|
-
return (value) => `${value}`.toWellFormed()
|
|
675
|
-
} else {
|
|
676
|
-
/**
|
|
677
|
-
* @param {string} value
|
|
678
|
-
* @returns {string}
|
|
679
|
-
*/
|
|
680
|
-
return nodeUtil.toUSVString
|
|
681
|
-
}
|
|
682
|
-
})()
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
* @param {*} value
|
|
686
|
-
* @returns {boolean}
|
|
687
|
-
*/
|
|
688
|
-
// TODO: move this to webidl
|
|
689
|
-
const isUSVString = (() => {
|
|
690
|
-
if (typeof String.prototype.isWellFormed === 'function') {
|
|
691
|
-
/**
|
|
692
|
-
* @param {*} value
|
|
693
|
-
* @returns {boolean}
|
|
694
|
-
*/
|
|
695
|
-
return (value) => `${value}`.isWellFormed()
|
|
696
|
-
} else {
|
|
697
|
-
/**
|
|
698
|
-
* @param {*} value
|
|
699
|
-
* @returns {boolean}
|
|
700
|
-
*/
|
|
701
|
-
return (value) => toUSVString(value) === `${value}`
|
|
702
|
-
}
|
|
703
|
-
})()
|
|
704
|
-
|
|
705
|
-
/**
|
|
706
|
-
* @see https://tools.ietf.org/html/rfc7230#section-3.2.6
|
|
707
|
-
* @param {number} c
|
|
708
|
-
* @returns {boolean}
|
|
709
|
-
*/
|
|
710
|
-
function isTokenCharCode (c) {
|
|
711
|
-
switch (c) {
|
|
712
|
-
case 0x22:
|
|
713
|
-
case 0x28:
|
|
714
|
-
case 0x29:
|
|
715
|
-
case 0x2c:
|
|
716
|
-
case 0x2f:
|
|
717
|
-
case 0x3a:
|
|
718
|
-
case 0x3b:
|
|
719
|
-
case 0x3c:
|
|
720
|
-
case 0x3d:
|
|
721
|
-
case 0x3e:
|
|
722
|
-
case 0x3f:
|
|
723
|
-
case 0x40:
|
|
724
|
-
case 0x5b:
|
|
725
|
-
case 0x5c:
|
|
726
|
-
case 0x5d:
|
|
727
|
-
case 0x7b:
|
|
728
|
-
case 0x7d:
|
|
729
|
-
// DQUOTE and "(),/:;<=>?@[\]{}"
|
|
730
|
-
return false
|
|
731
|
-
default:
|
|
732
|
-
// VCHAR %x21-7E
|
|
733
|
-
return c >= 0x21 && c <= 0x7e
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
/**
|
|
738
|
-
* @param {string} characters
|
|
739
|
-
* @returns {boolean}
|
|
740
|
-
*/
|
|
741
|
-
function isValidHTTPToken (characters) {
|
|
742
|
-
if (characters.length === 0) {
|
|
743
|
-
return false
|
|
744
|
-
}
|
|
745
|
-
for (let i = 0; i < characters.length; ++i) {
|
|
746
|
-
if (!isTokenCharCode(characters.charCodeAt(i))) {
|
|
747
|
-
return false
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
return true
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
// headerCharRegex have been lifted from
|
|
754
|
-
// https://github.com/nodejs/node/blob/main/lib/_http_common.js
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Matches if val contains an invalid field-vchar
|
|
758
|
-
* field-value = *( field-content / obs-fold )
|
|
759
|
-
* field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
|
760
|
-
* field-vchar = VCHAR / obs-text
|
|
761
|
-
*/
|
|
762
|
-
const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* @param {string} characters
|
|
766
|
-
* @returns {boolean}
|
|
767
|
-
*/
|
|
768
|
-
function isValidHeaderValue (characters) {
|
|
769
|
-
return !headerCharRegex.test(characters)
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const rangeHeaderRegex = /^bytes (\d+)-(\d+)\/(\d+)?$/
|
|
773
|
-
|
|
774
|
-
/**
|
|
775
|
-
* @typedef {object} RangeHeader
|
|
776
|
-
* @property {number} start
|
|
777
|
-
* @property {number | null} end
|
|
778
|
-
* @property {number | null} size
|
|
779
|
-
*/
|
|
780
|
-
|
|
781
|
-
/**
|
|
782
|
-
* Parse accordingly to RFC 9110
|
|
783
|
-
* @see https://www.rfc-editor.org/rfc/rfc9110#field.content-range
|
|
784
|
-
* @param {string} [range]
|
|
785
|
-
* @returns {RangeHeader|null}
|
|
786
|
-
*/
|
|
787
|
-
function parseRangeHeader (range) {
|
|
788
|
-
if (range == null || range === '') return { start: 0, end: null, size: null }
|
|
789
|
-
|
|
790
|
-
const m = range ? range.match(rangeHeaderRegex) : null
|
|
791
|
-
return m
|
|
792
|
-
? {
|
|
793
|
-
start: parseInt(m[1]),
|
|
794
|
-
end: m[2] ? parseInt(m[2]) : null,
|
|
795
|
-
size: m[3] ? parseInt(m[3]) : null
|
|
796
|
-
}
|
|
797
|
-
: null
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* @template {import("events").EventEmitter} T
|
|
802
|
-
* @param {T} obj
|
|
803
|
-
* @param {string} name
|
|
804
|
-
* @param {(...args: any[]) => void} listener
|
|
805
|
-
* @returns {T}
|
|
806
|
-
*/
|
|
807
|
-
function addListener (obj, name, listener) {
|
|
808
|
-
const listeners = (obj[kListeners] ??= [])
|
|
809
|
-
listeners.push([name, listener])
|
|
810
|
-
obj.on(name, listener)
|
|
811
|
-
return obj
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
/**
|
|
815
|
-
* @template {import("events").EventEmitter} T
|
|
816
|
-
* @param {T} obj
|
|
817
|
-
* @returns {T}
|
|
818
|
-
*/
|
|
819
|
-
function removeAllListeners (obj) {
|
|
820
|
-
if (obj[kListeners] != null) {
|
|
821
|
-
for (const [name, listener] of obj[kListeners]) {
|
|
822
|
-
obj.removeListener(name, listener)
|
|
823
|
-
}
|
|
824
|
-
obj[kListeners] = null
|
|
825
|
-
}
|
|
826
|
-
return obj
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
/**
|
|
830
|
-
* @param {import ('../dispatcher/client')} client
|
|
831
|
-
* @param {import ('../core/request')} request
|
|
832
|
-
* @param {Error} err
|
|
833
|
-
*/
|
|
834
|
-
function errorRequest (client, request, err) {
|
|
835
|
-
try {
|
|
836
|
-
request.onError(err)
|
|
837
|
-
assert(request.aborted)
|
|
838
|
-
} catch (err) {
|
|
839
|
-
client.emit('error', err)
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* @param {WeakRef<net.Socket>} socketWeakRef
|
|
845
|
-
* @param {object} opts
|
|
846
|
-
* @param {number} opts.timeout
|
|
847
|
-
* @param {string} opts.hostname
|
|
848
|
-
* @param {number} opts.port
|
|
849
|
-
* @returns {() => void}
|
|
850
|
-
*/
|
|
851
|
-
const setupConnectTimeout = process.platform === 'win32'
|
|
852
|
-
? (socketWeakRef, opts) => {
|
|
853
|
-
if (!opts.timeout) {
|
|
854
|
-
return noop
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
let s1 = null
|
|
858
|
-
let s2 = null
|
|
859
|
-
const fastTimer = timers.setFastTimeout(() => {
|
|
860
|
-
// setImmediate is added to make sure that we prioritize socket error events over timeouts
|
|
861
|
-
s1 = setImmediate(() => {
|
|
862
|
-
// Windows needs an extra setImmediate probably due to implementation differences in the socket logic
|
|
863
|
-
s2 = setImmediate(() => onConnectTimeout(socketWeakRef.deref(), opts))
|
|
864
|
-
})
|
|
865
|
-
}, opts.timeout)
|
|
866
|
-
return () => {
|
|
867
|
-
timers.clearFastTimeout(fastTimer)
|
|
868
|
-
clearImmediate(s1)
|
|
869
|
-
clearImmediate(s2)
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
: (socketWeakRef, opts) => {
|
|
873
|
-
if (!opts.timeout) {
|
|
874
|
-
return noop
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
let s1 = null
|
|
878
|
-
const fastTimer = timers.setFastTimeout(() => {
|
|
879
|
-
// setImmediate is added to make sure that we prioritize socket error events over timeouts
|
|
880
|
-
s1 = setImmediate(() => {
|
|
881
|
-
onConnectTimeout(socketWeakRef.deref(), opts)
|
|
882
|
-
})
|
|
883
|
-
}, opts.timeout)
|
|
884
|
-
return () => {
|
|
885
|
-
timers.clearFastTimeout(fastTimer)
|
|
886
|
-
clearImmediate(s1)
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
/**
|
|
891
|
-
* @param {net.Socket} socket
|
|
892
|
-
* @param {object} opts
|
|
893
|
-
* @param {number} opts.timeout
|
|
894
|
-
* @param {string} opts.hostname
|
|
895
|
-
* @param {number} opts.port
|
|
896
|
-
*/
|
|
897
|
-
function onConnectTimeout (socket, opts) {
|
|
898
|
-
// The socket could be already garbage collected
|
|
899
|
-
if (socket == null) {
|
|
900
|
-
return
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
let message = 'Connect Timeout Error'
|
|
904
|
-
if (Array.isArray(socket.autoSelectFamilyAttemptedAddresses)) {
|
|
905
|
-
message += ` (attempted addresses: ${socket.autoSelectFamilyAttemptedAddresses.join(', ')},`
|
|
906
|
-
} else {
|
|
907
|
-
message += ` (attempted address: ${opts.hostname}:${opts.port},`
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
message += ` timeout: ${opts.timeout}ms)`
|
|
911
|
-
|
|
912
|
-
destroy(socket, new ConnectTimeoutError(message))
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
const kEnumerableProperty = Object.create(null)
|
|
916
|
-
kEnumerableProperty.enumerable = true
|
|
917
|
-
|
|
918
|
-
const normalizedMethodRecordsBase = {
|
|
919
|
-
delete: 'DELETE',
|
|
920
|
-
DELETE: 'DELETE',
|
|
921
|
-
get: 'GET',
|
|
922
|
-
GET: 'GET',
|
|
923
|
-
head: 'HEAD',
|
|
924
|
-
HEAD: 'HEAD',
|
|
925
|
-
options: 'OPTIONS',
|
|
926
|
-
OPTIONS: 'OPTIONS',
|
|
927
|
-
post: 'POST',
|
|
928
|
-
POST: 'POST',
|
|
929
|
-
put: 'PUT',
|
|
930
|
-
PUT: 'PUT'
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
const normalizedMethodRecords = {
|
|
934
|
-
...normalizedMethodRecordsBase,
|
|
935
|
-
patch: 'patch',
|
|
936
|
-
PATCH: 'PATCH'
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
|
|
940
|
-
Object.setPrototypeOf(normalizedMethodRecordsBase, null)
|
|
941
|
-
Object.setPrototypeOf(normalizedMethodRecords, null)
|
|
942
|
-
|
|
943
|
-
module.exports = {
|
|
944
|
-
kEnumerableProperty,
|
|
945
|
-
isDisturbed,
|
|
946
|
-
toUSVString,
|
|
947
|
-
isUSVString,
|
|
948
|
-
isBlobLike,
|
|
949
|
-
parseOrigin,
|
|
950
|
-
parseURL,
|
|
951
|
-
getServerName,
|
|
952
|
-
isStream,
|
|
953
|
-
isIterable,
|
|
954
|
-
isAsyncIterable,
|
|
955
|
-
isDestroyed,
|
|
956
|
-
headerNameToString,
|
|
957
|
-
bufferToLowerCasedHeaderName,
|
|
958
|
-
addListener,
|
|
959
|
-
removeAllListeners,
|
|
960
|
-
errorRequest,
|
|
961
|
-
parseRawHeaders,
|
|
962
|
-
encodeRawHeaders,
|
|
963
|
-
parseHeaders,
|
|
964
|
-
parseKeepAliveTimeout,
|
|
965
|
-
destroy,
|
|
966
|
-
bodyLength,
|
|
967
|
-
deepClone,
|
|
968
|
-
ReadableStreamFrom,
|
|
969
|
-
isBuffer,
|
|
970
|
-
assertRequestHandler,
|
|
971
|
-
getSocketInfo,
|
|
972
|
-
isFormDataLike,
|
|
973
|
-
serializePathWithQuery,
|
|
974
|
-
addAbortListener,
|
|
975
|
-
isValidHTTPToken,
|
|
976
|
-
isValidHeaderValue,
|
|
977
|
-
isTokenCharCode,
|
|
978
|
-
parseRangeHeader,
|
|
979
|
-
normalizedMethodRecordsBase,
|
|
980
|
-
normalizedMethodRecords,
|
|
981
|
-
isValidPort,
|
|
982
|
-
isHttpOrHttpsPrefixed,
|
|
983
|
-
nodeMajor,
|
|
984
|
-
nodeMinor,
|
|
985
|
-
safeHTTPMethods: Object.freeze(['GET', 'HEAD', 'OPTIONS', 'TRACE']),
|
|
986
|
-
wrapRequestBody,
|
|
987
|
-
setupConnectTimeout
|
|
988
|
-
}
|