deepv-code 1.0.182 → 1.0.183

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.
Files changed (193) hide show
  1. package/bundle/dvcode.js +635 -635
  2. package/package.json +1 -1
  3. package/bundle/assets/help/README.md +0 -113
  4. package/bundle/assets/sounds/README.md +0 -74
  5. package/bundle/node_modules/undici/LICENSE +0 -21
  6. package/bundle/node_modules/undici/README.md +0 -472
  7. package/bundle/node_modules/undici/docs/docs/api/Agent.md +0 -83
  8. package/bundle/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
  9. package/bundle/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
  10. package/bundle/node_modules/undici/docs/docs/api/CacheStore.md +0 -151
  11. package/bundle/node_modules/undici/docs/docs/api/Client.md +0 -281
  12. package/bundle/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
  13. package/bundle/node_modules/undici/docs/docs/api/Connector.md +0 -115
  14. package/bundle/node_modules/undici/docs/docs/api/ContentType.md +0 -57
  15. package/bundle/node_modules/undici/docs/docs/api/Cookies.md +0 -101
  16. package/bundle/node_modules/undici/docs/docs/api/Debug.md +0 -62
  17. package/bundle/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -204
  18. package/bundle/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1200
  19. package/bundle/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
  20. package/bundle/node_modules/undici/docs/docs/api/Errors.md +0 -49
  21. package/bundle/node_modules/undici/docs/docs/api/EventSource.md +0 -45
  22. package/bundle/node_modules/undici/docs/docs/api/Fetch.md +0 -52
  23. package/bundle/node_modules/undici/docs/docs/api/H2CClient.md +0 -262
  24. package/bundle/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
  25. package/bundle/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
  26. package/bundle/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
  27. package/bundle/node_modules/undici/docs/docs/api/MockClient.md +0 -77
  28. package/bundle/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
  29. package/bundle/node_modules/undici/docs/docs/api/MockPool.md +0 -548
  30. package/bundle/node_modules/undici/docs/docs/api/Pool.md +0 -84
  31. package/bundle/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
  32. package/bundle/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -227
  33. package/bundle/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -96
  34. package/bundle/node_modules/undici/docs/docs/api/RetryAgent.md +0 -45
  35. package/bundle/node_modules/undici/docs/docs/api/RetryHandler.md +0 -117
  36. package/bundle/node_modules/undici/docs/docs/api/Util.md +0 -25
  37. package/bundle/node_modules/undici/docs/docs/api/WebSocket.md +0 -85
  38. package/bundle/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
  39. package/bundle/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
  40. package/bundle/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
  41. package/bundle/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
  42. package/bundle/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -20
  43. package/bundle/node_modules/undici/index-fetch.js +0 -35
  44. package/bundle/node_modules/undici/index.d.ts +0 -3
  45. package/bundle/node_modules/undici/index.js +0 -183
  46. package/bundle/node_modules/undici/lib/api/abort-signal.js +0 -59
  47. package/bundle/node_modules/undici/lib/api/api-connect.js +0 -110
  48. package/bundle/node_modules/undici/lib/api/api-pipeline.js +0 -252
  49. package/bundle/node_modules/undici/lib/api/api-request.js +0 -199
  50. package/bundle/node_modules/undici/lib/api/api-stream.js +0 -209
  51. package/bundle/node_modules/undici/lib/api/api-upgrade.js +0 -110
  52. package/bundle/node_modules/undici/lib/api/index.js +0 -7
  53. package/bundle/node_modules/undici/lib/api/readable.js +0 -558
  54. package/bundle/node_modules/undici/lib/api/util.js +0 -95
  55. package/bundle/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
  56. package/bundle/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
  57. package/bundle/node_modules/undici/lib/core/connect.js +0 -164
  58. package/bundle/node_modules/undici/lib/core/constants.js +0 -143
  59. package/bundle/node_modules/undici/lib/core/diagnostics.js +0 -196
  60. package/bundle/node_modules/undici/lib/core/errors.js +0 -244
  61. package/bundle/node_modules/undici/lib/core/request.js +0 -397
  62. package/bundle/node_modules/undici/lib/core/symbols.js +0 -68
  63. package/bundle/node_modules/undici/lib/core/tree.js +0 -160
  64. package/bundle/node_modules/undici/lib/core/util.js +0 -988
  65. package/bundle/node_modules/undici/lib/dispatcher/agent.js +0 -135
  66. package/bundle/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -206
  67. package/bundle/node_modules/undici/lib/dispatcher/client-h1.js +0 -1615
  68. package/bundle/node_modules/undici/lib/dispatcher/client-h2.js +0 -798
  69. package/bundle/node_modules/undici/lib/dispatcher/client.js +0 -614
  70. package/bundle/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -161
  71. package/bundle/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
  72. package/bundle/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -151
  73. package/bundle/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -159
  74. package/bundle/node_modules/undici/lib/dispatcher/h2c-client.js +0 -122
  75. package/bundle/node_modules/undici/lib/dispatcher/pool-base.js +0 -191
  76. package/bundle/node_modules/undici/lib/dispatcher/pool.js +0 -118
  77. package/bundle/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -275
  78. package/bundle/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
  79. package/bundle/node_modules/undici/lib/global.js +0 -32
  80. package/bundle/node_modules/undici/lib/handler/cache-handler.js +0 -448
  81. package/bundle/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
  82. package/bundle/node_modules/undici/lib/handler/decorator-handler.js +0 -67
  83. package/bundle/node_modules/undici/lib/handler/redirect-handler.js +0 -227
  84. package/bundle/node_modules/undici/lib/handler/retry-handler.js +0 -342
  85. package/bundle/node_modules/undici/lib/handler/unwrap-handler.js +0 -96
  86. package/bundle/node_modules/undici/lib/handler/wrap-handler.js +0 -95
  87. package/bundle/node_modules/undici/lib/interceptor/cache.js +0 -372
  88. package/bundle/node_modules/undici/lib/interceptor/dns.js +0 -432
  89. package/bundle/node_modules/undici/lib/interceptor/dump.js +0 -111
  90. package/bundle/node_modules/undici/lib/interceptor/redirect.js +0 -21
  91. package/bundle/node_modules/undici/lib/interceptor/response-error.js +0 -95
  92. package/bundle/node_modules/undici/lib/interceptor/retry.js +0 -19
  93. package/bundle/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  94. package/bundle/node_modules/undici/lib/llhttp/constants.d.ts +0 -97
  95. package/bundle/node_modules/undici/lib/llhttp/constants.js +0 -498
  96. package/bundle/node_modules/undici/lib/llhttp/constants.js.map +0 -1
  97. package/bundle/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
  98. package/bundle/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
  99. package/bundle/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
  100. package/bundle/node_modules/undici/lib/llhttp/utils.js +0 -15
  101. package/bundle/node_modules/undici/lib/llhttp/utils.js.map +0 -1
  102. package/bundle/node_modules/undici/lib/mock/mock-agent.js +0 -224
  103. package/bundle/node_modules/undici/lib/mock/mock-call-history.js +0 -248
  104. package/bundle/node_modules/undici/lib/mock/mock-client.js +0 -64
  105. package/bundle/node_modules/undici/lib/mock/mock-errors.js +0 -19
  106. package/bundle/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
  107. package/bundle/node_modules/undici/lib/mock/mock-pool.js +0 -64
  108. package/bundle/node_modules/undici/lib/mock/mock-symbols.js +0 -31
  109. package/bundle/node_modules/undici/lib/mock/mock-utils.js +0 -433
  110. package/bundle/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
  111. package/bundle/node_modules/undici/lib/util/cache.js +0 -368
  112. package/bundle/node_modules/undici/lib/util/date.js +0 -259
  113. package/bundle/node_modules/undici/lib/util/stats.js +0 -32
  114. package/bundle/node_modules/undici/lib/util/timers.js +0 -423
  115. package/bundle/node_modules/undici/lib/web/cache/cache.js +0 -862
  116. package/bundle/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
  117. package/bundle/node_modules/undici/lib/web/cache/util.js +0 -45
  118. package/bundle/node_modules/undici/lib/web/cookies/constants.js +0 -12
  119. package/bundle/node_modules/undici/lib/web/cookies/index.js +0 -199
  120. package/bundle/node_modules/undici/lib/web/cookies/parse.js +0 -322
  121. package/bundle/node_modules/undici/lib/web/cookies/util.js +0 -282
  122. package/bundle/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
  123. package/bundle/node_modules/undici/lib/web/eventsource/eventsource.js +0 -484
  124. package/bundle/node_modules/undici/lib/web/eventsource/util.js +0 -37
  125. package/bundle/node_modules/undici/lib/web/fetch/LICENSE +0 -21
  126. package/bundle/node_modules/undici/lib/web/fetch/body.js +0 -532
  127. package/bundle/node_modules/undici/lib/web/fetch/constants.js +0 -131
  128. package/bundle/node_modules/undici/lib/web/fetch/data-url.js +0 -744
  129. package/bundle/node_modules/undici/lib/web/fetch/dispatcher-weakref.js +0 -46
  130. package/bundle/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -501
  131. package/bundle/node_modules/undici/lib/web/fetch/formdata.js +0 -263
  132. package/bundle/node_modules/undici/lib/web/fetch/global.js +0 -40
  133. package/bundle/node_modules/undici/lib/web/fetch/headers.js +0 -719
  134. package/bundle/node_modules/undici/lib/web/fetch/index.js +0 -2258
  135. package/bundle/node_modules/undici/lib/web/fetch/request.js +0 -1099
  136. package/bundle/node_modules/undici/lib/web/fetch/response.js +0 -636
  137. package/bundle/node_modules/undici/lib/web/fetch/util.js +0 -1782
  138. package/bundle/node_modules/undici/lib/web/fetch/webidl.js +0 -740
  139. package/bundle/node_modules/undici/lib/web/websocket/connection.js +0 -325
  140. package/bundle/node_modules/undici/lib/web/websocket/constants.js +0 -126
  141. package/bundle/node_modules/undici/lib/web/websocket/events.js +0 -331
  142. package/bundle/node_modules/undici/lib/web/websocket/frame.js +0 -138
  143. package/bundle/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -70
  144. package/bundle/node_modules/undici/lib/web/websocket/receiver.js +0 -454
  145. package/bundle/node_modules/undici/lib/web/websocket/sender.js +0 -109
  146. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -83
  147. package/bundle/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -485
  148. package/bundle/node_modules/undici/lib/web/websocket/util.js +0 -338
  149. package/bundle/node_modules/undici/lib/web/websocket/websocket.js +0 -686
  150. package/bundle/node_modules/undici/package.json +0 -149
  151. package/bundle/node_modules/undici/scripts/strip-comments.js +0 -10
  152. package/bundle/node_modules/undici/types/README.md +0 -6
  153. package/bundle/node_modules/undici/types/agent.d.ts +0 -35
  154. package/bundle/node_modules/undici/types/api.d.ts +0 -43
  155. package/bundle/node_modules/undici/types/balanced-pool.d.ts +0 -29
  156. package/bundle/node_modules/undici/types/cache-interceptor.d.ts +0 -172
  157. package/bundle/node_modules/undici/types/cache.d.ts +0 -36
  158. package/bundle/node_modules/undici/types/client-stats.d.ts +0 -15
  159. package/bundle/node_modules/undici/types/client.d.ts +0 -110
  160. package/bundle/node_modules/undici/types/connector.d.ts +0 -34
  161. package/bundle/node_modules/undici/types/content-type.d.ts +0 -21
  162. package/bundle/node_modules/undici/types/cookies.d.ts +0 -30
  163. package/bundle/node_modules/undici/types/diagnostics-channel.d.ts +0 -66
  164. package/bundle/node_modules/undici/types/dispatcher.d.ts +0 -281
  165. package/bundle/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -21
  166. package/bundle/node_modules/undici/types/errors.d.ts +0 -171
  167. package/bundle/node_modules/undici/types/eventsource.d.ts +0 -61
  168. package/bundle/node_modules/undici/types/fetch.d.ts +0 -210
  169. package/bundle/node_modules/undici/types/formdata.d.ts +0 -108
  170. package/bundle/node_modules/undici/types/global-dispatcher.d.ts +0 -9
  171. package/bundle/node_modules/undici/types/global-origin.d.ts +0 -7
  172. package/bundle/node_modules/undici/types/h2c-client.d.ts +0 -75
  173. package/bundle/node_modules/undici/types/handlers.d.ts +0 -15
  174. package/bundle/node_modules/undici/types/header.d.ts +0 -160
  175. package/bundle/node_modules/undici/types/index.d.ts +0 -75
  176. package/bundle/node_modules/undici/types/interceptors.d.ts +0 -34
  177. package/bundle/node_modules/undici/types/mock-agent.d.ts +0 -68
  178. package/bundle/node_modules/undici/types/mock-call-history.d.ts +0 -111
  179. package/bundle/node_modules/undici/types/mock-client.d.ts +0 -25
  180. package/bundle/node_modules/undici/types/mock-errors.d.ts +0 -12
  181. package/bundle/node_modules/undici/types/mock-interceptor.d.ts +0 -93
  182. package/bundle/node_modules/undici/types/mock-pool.d.ts +0 -25
  183. package/bundle/node_modules/undici/types/patch.d.ts +0 -29
  184. package/bundle/node_modules/undici/types/pool-stats.d.ts +0 -19
  185. package/bundle/node_modules/undici/types/pool.d.ts +0 -41
  186. package/bundle/node_modules/undici/types/proxy-agent.d.ts +0 -29
  187. package/bundle/node_modules/undici/types/readable.d.ts +0 -68
  188. package/bundle/node_modules/undici/types/retry-agent.d.ts +0 -8
  189. package/bundle/node_modules/undici/types/retry-handler.d.ts +0 -116
  190. package/bundle/node_modules/undici/types/util.d.ts +0 -18
  191. package/bundle/node_modules/undici/types/utility.d.ts +0 -7
  192. package/bundle/node_modules/undici/types/webidl.d.ts +0 -266
  193. package/bundle/node_modules/undici/types/websocket.d.ts +0 -184
@@ -1,1615 +0,0 @@
1
- 'use strict'
2
-
3
- /* global WebAssembly */
4
-
5
- const assert = require('node:assert')
6
- const util = require('../core/util.js')
7
- const { channels } = require('../core/diagnostics.js')
8
- const timers = require('../util/timers.js')
9
- const {
10
- RequestContentLengthMismatchError,
11
- ResponseContentLengthMismatchError,
12
- RequestAbortedError,
13
- HeadersTimeoutError,
14
- HeadersOverflowError,
15
- SocketError,
16
- InformationalError,
17
- BodyTimeoutError,
18
- HTTPParserError,
19
- ResponseExceededMaxSizeError
20
- } = require('../core/errors.js')
21
- const {
22
- kUrl,
23
- kReset,
24
- kClient,
25
- kParser,
26
- kBlocking,
27
- kRunning,
28
- kPending,
29
- kSize,
30
- kWriting,
31
- kQueue,
32
- kNoRef,
33
- kKeepAliveDefaultTimeout,
34
- kHostHeader,
35
- kPendingIdx,
36
- kRunningIdx,
37
- kError,
38
- kPipelining,
39
- kSocket,
40
- kKeepAliveTimeoutValue,
41
- kMaxHeadersSize,
42
- kKeepAliveMaxTimeout,
43
- kKeepAliveTimeoutThreshold,
44
- kHeadersTimeout,
45
- kBodyTimeout,
46
- kStrictContentLength,
47
- kMaxRequests,
48
- kCounter,
49
- kMaxResponseSize,
50
- kOnError,
51
- kResume,
52
- kHTTPContext,
53
- kClosed
54
- } = require('../core/symbols.js')
55
-
56
- const constants = require('../llhttp/constants.js')
57
- const EMPTY_BUF = Buffer.alloc(0)
58
- const FastBuffer = Buffer[Symbol.species]
59
- const removeAllListeners = util.removeAllListeners
60
-
61
- let extractBody
62
-
63
- async function lazyllhttp () {
64
- const llhttpWasmData = process.env.JEST_WORKER_ID ? require('../llhttp/llhttp-wasm.js') : undefined
65
-
66
- let mod
67
- try {
68
- mod = await WebAssembly.compile(require('../llhttp/llhttp_simd-wasm.js'))
69
- } catch (e) {
70
- /* istanbul ignore next */
71
-
72
- // We could check if the error was caused by the simd option not
73
- // being enabled, but the occurring of this other error
74
- // * https://github.com/emscripten-core/emscripten/issues/11495
75
- // got me to remove that check to avoid breaking Node 12.
76
- mod = await WebAssembly.compile(llhttpWasmData || require('../llhttp/llhttp-wasm.js'))
77
- }
78
-
79
- return await WebAssembly.instantiate(mod, {
80
- env: {
81
- /**
82
- * @param {number} p
83
- * @param {number} at
84
- * @param {number} len
85
- * @returns {number}
86
- */
87
- wasm_on_url: (p, at, len) => {
88
- /* istanbul ignore next */
89
- return 0
90
- },
91
- /**
92
- * @param {number} p
93
- * @param {number} at
94
- * @param {number} len
95
- * @returns {number}
96
- */
97
- wasm_on_status: (p, at, len) => {
98
- assert(currentParser.ptr === p)
99
- const start = at - currentBufferPtr + currentBufferRef.byteOffset
100
- return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len))
101
- },
102
- /**
103
- * @param {number} p
104
- * @returns {number}
105
- */
106
- wasm_on_message_begin: (p) => {
107
- assert(currentParser.ptr === p)
108
- return currentParser.onMessageBegin()
109
- },
110
- /**
111
- * @param {number} p
112
- * @param {number} at
113
- * @param {number} len
114
- * @returns {number}
115
- */
116
- wasm_on_header_field: (p, at, len) => {
117
- assert(currentParser.ptr === p)
118
- const start = at - currentBufferPtr + currentBufferRef.byteOffset
119
- return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len))
120
- },
121
- /**
122
- * @param {number} p
123
- * @param {number} at
124
- * @param {number} len
125
- * @returns {number}
126
- */
127
- wasm_on_header_value: (p, at, len) => {
128
- assert(currentParser.ptr === p)
129
- const start = at - currentBufferPtr + currentBufferRef.byteOffset
130
- return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len))
131
- },
132
- /**
133
- * @param {number} p
134
- * @param {number} statusCode
135
- * @param {0|1} upgrade
136
- * @param {0|1} shouldKeepAlive
137
- * @returns {number}
138
- */
139
- wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
140
- assert(currentParser.ptr === p)
141
- return currentParser.onHeadersComplete(statusCode, upgrade === 1, shouldKeepAlive === 1)
142
- },
143
- /**
144
- * @param {number} p
145
- * @param {number} at
146
- * @param {number} len
147
- * @returns {number}
148
- */
149
- wasm_on_body: (p, at, len) => {
150
- assert(currentParser.ptr === p)
151
- const start = at - currentBufferPtr + currentBufferRef.byteOffset
152
- return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len))
153
- },
154
- /**
155
- * @param {number} p
156
- * @returns {number}
157
- */
158
- wasm_on_message_complete: (p) => {
159
- assert(currentParser.ptr === p)
160
- return currentParser.onMessageComplete()
161
- }
162
-
163
- }
164
- })
165
- }
166
-
167
- let llhttpInstance = null
168
- /**
169
- * @type {Promise<WebAssembly.Instance>|null}
170
- */
171
- let llhttpPromise = lazyllhttp()
172
- llhttpPromise.catch()
173
-
174
- /**
175
- * @type {Parser|null}
176
- */
177
- let currentParser = null
178
- let currentBufferRef = null
179
- /**
180
- * @type {number}
181
- */
182
- let currentBufferSize = 0
183
- let currentBufferPtr = null
184
-
185
- const USE_NATIVE_TIMER = 0
186
- const USE_FAST_TIMER = 1
187
-
188
- // Use fast timers for headers and body to take eventual event loop
189
- // latency into account.
190
- const TIMEOUT_HEADERS = 2 | USE_FAST_TIMER
191
- const TIMEOUT_BODY = 4 | USE_FAST_TIMER
192
-
193
- // Use native timers to ignore event loop latency for keep-alive
194
- // handling.
195
- const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER
196
-
197
- class Parser {
198
- /**
199
- * @param {import('./client.js')} client
200
- * @param {import('net').Socket} socket
201
- * @param {*} llhttp
202
- */
203
- constructor (client, socket, { exports }) {
204
- this.llhttp = exports
205
- this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE)
206
- this.client = client
207
- /**
208
- * @type {import('net').Socket}
209
- */
210
- this.socket = socket
211
- this.timeout = null
212
- this.timeoutValue = null
213
- this.timeoutType = null
214
- this.statusCode = 0
215
- this.statusText = ''
216
- this.upgrade = false
217
- this.headers = []
218
- this.headersSize = 0
219
- this.headersMaxSize = client[kMaxHeadersSize]
220
- this.shouldKeepAlive = false
221
- this.paused = false
222
- this.resume = this.resume.bind(this)
223
-
224
- this.bytesRead = 0
225
-
226
- this.keepAlive = ''
227
- this.contentLength = ''
228
- this.connection = ''
229
- this.maxResponseSize = client[kMaxResponseSize]
230
- }
231
-
232
- setTimeout (delay, type) {
233
- // If the existing timer and the new timer are of different timer type
234
- // (fast or native) or have different delay, we need to clear the existing
235
- // timer and set a new one.
236
- if (
237
- delay !== this.timeoutValue ||
238
- (type & USE_FAST_TIMER) ^ (this.timeoutType & USE_FAST_TIMER)
239
- ) {
240
- // If a timeout is already set, clear it with clearTimeout of the fast
241
- // timer implementation, as it can clear fast and native timers.
242
- if (this.timeout) {
243
- timers.clearTimeout(this.timeout)
244
- this.timeout = null
245
- }
246
-
247
- if (delay) {
248
- if (type & USE_FAST_TIMER) {
249
- this.timeout = timers.setFastTimeout(onParserTimeout, delay, new WeakRef(this))
250
- } else {
251
- this.timeout = setTimeout(onParserTimeout, delay, new WeakRef(this))
252
- this.timeout.unref()
253
- }
254
- }
255
-
256
- this.timeoutValue = delay
257
- } else if (this.timeout) {
258
- // istanbul ignore else: only for jest
259
- if (this.timeout.refresh) {
260
- this.timeout.refresh()
261
- }
262
- }
263
-
264
- this.timeoutType = type
265
- }
266
-
267
- resume () {
268
- if (this.socket.destroyed || !this.paused) {
269
- return
270
- }
271
-
272
- assert(this.ptr != null)
273
- assert(currentParser === null)
274
-
275
- this.llhttp.llhttp_resume(this.ptr)
276
-
277
- assert(this.timeoutType === TIMEOUT_BODY)
278
- if (this.timeout) {
279
- // istanbul ignore else: only for jest
280
- if (this.timeout.refresh) {
281
- this.timeout.refresh()
282
- }
283
- }
284
-
285
- this.paused = false
286
- this.execute(this.socket.read() || EMPTY_BUF) // Flush parser.
287
- this.readMore()
288
- }
289
-
290
- readMore () {
291
- while (!this.paused && this.ptr) {
292
- const chunk = this.socket.read()
293
- if (chunk === null) {
294
- break
295
- }
296
- this.execute(chunk)
297
- }
298
- }
299
-
300
- /**
301
- * @param {Buffer} chunk
302
- */
303
- execute (chunk) {
304
- assert(currentParser === null)
305
- assert(this.ptr != null)
306
- assert(!this.paused)
307
-
308
- const { socket, llhttp } = this
309
-
310
- // Allocate a new buffer if the current buffer is too small.
311
- if (chunk.length > currentBufferSize) {
312
- if (currentBufferPtr) {
313
- llhttp.free(currentBufferPtr)
314
- }
315
- // Allocate a buffer that is a multiple of 4096 bytes.
316
- currentBufferSize = Math.ceil(chunk.length / 4096) * 4096
317
- currentBufferPtr = llhttp.malloc(currentBufferSize)
318
- }
319
-
320
- new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(chunk)
321
-
322
- // Call `execute` on the wasm parser.
323
- // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
324
- // and finally the length of bytes to parse.
325
- // The return value is an error code or `constants.ERROR.OK`.
326
- try {
327
- let ret
328
-
329
- try {
330
- currentBufferRef = chunk
331
- currentParser = this
332
- ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, chunk.length)
333
- /* eslint-disable-next-line no-useless-catch */
334
- } catch (err) {
335
- /* istanbul ignore next: difficult to make a test case for */
336
- throw err
337
- } finally {
338
- currentParser = null
339
- currentBufferRef = null
340
- }
341
-
342
- if (ret !== constants.ERROR.OK) {
343
- const data = chunk.subarray(llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr)
344
-
345
- if (ret === constants.ERROR.PAUSED_UPGRADE) {
346
- this.onUpgrade(data)
347
- } else if (ret === constants.ERROR.PAUSED) {
348
- this.paused = true
349
- socket.unshift(data)
350
- } else {
351
- const ptr = llhttp.llhttp_get_error_reason(this.ptr)
352
- let message = ''
353
- /* istanbul ignore else: difficult to make a test case for */
354
- if (ptr) {
355
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
356
- message =
357
- 'Response does not match the HTTP/1.1 protocol (' +
358
- Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
359
- ')'
360
- }
361
- throw new HTTPParserError(message, constants.ERROR[ret], data)
362
- }
363
- }
364
- } catch (err) {
365
- util.destroy(socket, err)
366
- }
367
- }
368
-
369
- destroy () {
370
- assert(currentParser === null)
371
- assert(this.ptr != null)
372
-
373
- this.llhttp.llhttp_free(this.ptr)
374
- this.ptr = null
375
-
376
- this.timeout && timers.clearTimeout(this.timeout)
377
- this.timeout = null
378
- this.timeoutValue = null
379
- this.timeoutType = null
380
-
381
- this.paused = false
382
- }
383
-
384
- /**
385
- * @param {Buffer} buf
386
- * @returns {0}
387
- */
388
- onStatus (buf) {
389
- this.statusText = buf.toString()
390
- return 0
391
- }
392
-
393
- /**
394
- * @returns {0|-1}
395
- */
396
- onMessageBegin () {
397
- const { socket, client } = this
398
-
399
- /* istanbul ignore next: difficult to make a test case for */
400
- if (socket.destroyed) {
401
- return -1
402
- }
403
-
404
- const request = client[kQueue][client[kRunningIdx]]
405
- if (!request) {
406
- return -1
407
- }
408
- request.onResponseStarted()
409
-
410
- return 0
411
- }
412
-
413
- /**
414
- * @param {Buffer} buf
415
- * @returns {number}
416
- */
417
- onHeaderField (buf) {
418
- const len = this.headers.length
419
-
420
- if ((len & 1) === 0) {
421
- this.headers.push(buf)
422
- } else {
423
- this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
424
- }
425
-
426
- this.trackHeader(buf.length)
427
-
428
- return 0
429
- }
430
-
431
- /**
432
- * @param {Buffer} buf
433
- * @returns {number}
434
- */
435
- onHeaderValue (buf) {
436
- let len = this.headers.length
437
-
438
- if ((len & 1) === 1) {
439
- this.headers.push(buf)
440
- len += 1
441
- } else {
442
- this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf])
443
- }
444
-
445
- const key = this.headers[len - 2]
446
- if (key.length === 10) {
447
- const headerName = util.bufferToLowerCasedHeaderName(key)
448
- if (headerName === 'keep-alive') {
449
- this.keepAlive += buf.toString()
450
- } else if (headerName === 'connection') {
451
- this.connection += buf.toString()
452
- }
453
- } else if (key.length === 14 && util.bufferToLowerCasedHeaderName(key) === 'content-length') {
454
- this.contentLength += buf.toString()
455
- }
456
-
457
- this.trackHeader(buf.length)
458
-
459
- return 0
460
- }
461
-
462
- /**
463
- * @param {number} len
464
- */
465
- trackHeader (len) {
466
- this.headersSize += len
467
- if (this.headersSize >= this.headersMaxSize) {
468
- util.destroy(this.socket, new HeadersOverflowError())
469
- }
470
- }
471
-
472
- /**
473
- * @param {Buffer} head
474
- */
475
- onUpgrade (head) {
476
- const { upgrade, client, socket, headers, statusCode } = this
477
-
478
- assert(upgrade)
479
- assert(client[kSocket] === socket)
480
- assert(!socket.destroyed)
481
- assert(!this.paused)
482
- assert((headers.length & 1) === 0)
483
-
484
- const request = client[kQueue][client[kRunningIdx]]
485
- assert(request)
486
- assert(request.upgrade || request.method === 'CONNECT')
487
-
488
- this.statusCode = 0
489
- this.statusText = ''
490
- this.shouldKeepAlive = false
491
-
492
- this.headers = []
493
- this.headersSize = 0
494
-
495
- socket.unshift(head)
496
-
497
- socket[kParser].destroy()
498
- socket[kParser] = null
499
-
500
- socket[kClient] = null
501
- socket[kError] = null
502
-
503
- removeAllListeners(socket)
504
-
505
- client[kSocket] = null
506
- client[kHTTPContext] = null // TODO (fix): This is hacky...
507
- client[kQueue][client[kRunningIdx]++] = null
508
- client.emit('disconnect', client[kUrl], [client], new InformationalError('upgrade'))
509
-
510
- try {
511
- request.onUpgrade(statusCode, headers, socket)
512
- } catch (err) {
513
- util.destroy(socket, err)
514
- }
515
-
516
- client[kResume]()
517
- }
518
-
519
- /**
520
- * @param {number} statusCode
521
- * @param {boolean} upgrade
522
- * @param {boolean} shouldKeepAlive
523
- * @returns {number}
524
- */
525
- onHeadersComplete (statusCode, upgrade, shouldKeepAlive) {
526
- const { client, socket, headers, statusText } = this
527
-
528
- /* istanbul ignore next: difficult to make a test case for */
529
- if (socket.destroyed) {
530
- return -1
531
- }
532
-
533
- const request = client[kQueue][client[kRunningIdx]]
534
-
535
- /* istanbul ignore next: difficult to make a test case for */
536
- if (!request) {
537
- return -1
538
- }
539
-
540
- assert(!this.upgrade)
541
- assert(this.statusCode < 200)
542
-
543
- if (statusCode === 100) {
544
- util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
545
- return -1
546
- }
547
-
548
- /* this can only happen if server is misbehaving */
549
- if (upgrade && !request.upgrade) {
550
- util.destroy(socket, new SocketError('bad upgrade', util.getSocketInfo(socket)))
551
- return -1
552
- }
553
-
554
- assert(this.timeoutType === TIMEOUT_HEADERS)
555
-
556
- this.statusCode = statusCode
557
- this.shouldKeepAlive = (
558
- shouldKeepAlive ||
559
- // Override llhttp value which does not allow keepAlive for HEAD.
560
- (request.method === 'HEAD' && !socket[kReset] && this.connection.toLowerCase() === 'keep-alive')
561
- )
562
-
563
- if (this.statusCode >= 200) {
564
- const bodyTimeout = request.bodyTimeout != null
565
- ? request.bodyTimeout
566
- : client[kBodyTimeout]
567
- this.setTimeout(bodyTimeout, TIMEOUT_BODY)
568
- } else if (this.timeout) {
569
- // istanbul ignore else: only for jest
570
- if (this.timeout.refresh) {
571
- this.timeout.refresh()
572
- }
573
- }
574
-
575
- if (request.method === 'CONNECT') {
576
- assert(client[kRunning] === 1)
577
- this.upgrade = true
578
- return 2
579
- }
580
-
581
- if (upgrade) {
582
- assert(client[kRunning] === 1)
583
- this.upgrade = true
584
- return 2
585
- }
586
-
587
- assert((this.headers.length & 1) === 0)
588
- this.headers = []
589
- this.headersSize = 0
590
-
591
- if (this.shouldKeepAlive && client[kPipelining]) {
592
- const keepAliveTimeout = this.keepAlive ? util.parseKeepAliveTimeout(this.keepAlive) : null
593
-
594
- if (keepAliveTimeout != null) {
595
- const timeout = Math.min(
596
- keepAliveTimeout - client[kKeepAliveTimeoutThreshold],
597
- client[kKeepAliveMaxTimeout]
598
- )
599
- if (timeout <= 0) {
600
- socket[kReset] = true
601
- } else {
602
- client[kKeepAliveTimeoutValue] = timeout
603
- }
604
- } else {
605
- client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout]
606
- }
607
- } else {
608
- // Stop more requests from being dispatched.
609
- socket[kReset] = true
610
- }
611
-
612
- const pause = request.onHeaders(statusCode, headers, this.resume, statusText) === false
613
-
614
- if (request.aborted) {
615
- return -1
616
- }
617
-
618
- if (request.method === 'HEAD') {
619
- return 1
620
- }
621
-
622
- if (statusCode < 200) {
623
- return 1
624
- }
625
-
626
- if (socket[kBlocking]) {
627
- socket[kBlocking] = false
628
- client[kResume]()
629
- }
630
-
631
- return pause ? constants.ERROR.PAUSED : 0
632
- }
633
-
634
- /**
635
- * @param {Buffer} buf
636
- * @returns {number}
637
- */
638
- onBody (buf) {
639
- const { client, socket, statusCode, maxResponseSize } = this
640
-
641
- if (socket.destroyed) {
642
- return -1
643
- }
644
-
645
- const request = client[kQueue][client[kRunningIdx]]
646
- assert(request)
647
-
648
- assert(this.timeoutType === TIMEOUT_BODY)
649
- if (this.timeout) {
650
- // istanbul ignore else: only for jest
651
- if (this.timeout.refresh) {
652
- this.timeout.refresh()
653
- }
654
- }
655
-
656
- assert(statusCode >= 200)
657
-
658
- if (maxResponseSize > -1 && this.bytesRead + buf.length > maxResponseSize) {
659
- util.destroy(socket, new ResponseExceededMaxSizeError())
660
- return -1
661
- }
662
-
663
- this.bytesRead += buf.length
664
-
665
- if (request.onData(buf) === false) {
666
- return constants.ERROR.PAUSED
667
- }
668
-
669
- return 0
670
- }
671
-
672
- /**
673
- * @returns {number}
674
- */
675
- onMessageComplete () {
676
- const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this
677
-
678
- if (socket.destroyed && (!statusCode || shouldKeepAlive)) {
679
- return -1
680
- }
681
-
682
- if (upgrade) {
683
- return 0
684
- }
685
-
686
- assert(statusCode >= 100)
687
- assert((this.headers.length & 1) === 0)
688
-
689
- const request = client[kQueue][client[kRunningIdx]]
690
- assert(request)
691
-
692
- this.statusCode = 0
693
- this.statusText = ''
694
- this.bytesRead = 0
695
- this.contentLength = ''
696
- this.keepAlive = ''
697
- this.connection = ''
698
-
699
- this.headers = []
700
- this.headersSize = 0
701
-
702
- if (statusCode < 200) {
703
- return 0
704
- }
705
-
706
- /* istanbul ignore next: should be handled by llhttp? */
707
- if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) {
708
- util.destroy(socket, new ResponseContentLengthMismatchError())
709
- return -1
710
- }
711
-
712
- request.onComplete(headers)
713
-
714
- client[kQueue][client[kRunningIdx]++] = null
715
-
716
- if (socket[kWriting]) {
717
- assert(client[kRunning] === 0)
718
- // Response completed before request.
719
- util.destroy(socket, new InformationalError('reset'))
720
- return constants.ERROR.PAUSED
721
- } else if (!shouldKeepAlive) {
722
- util.destroy(socket, new InformationalError('reset'))
723
- return constants.ERROR.PAUSED
724
- } else if (socket[kReset] && client[kRunning] === 0) {
725
- // Destroy socket once all requests have completed.
726
- // The request at the tail of the pipeline is the one
727
- // that requested reset and no further requests should
728
- // have been queued since then.
729
- util.destroy(socket, new InformationalError('reset'))
730
- return constants.ERROR.PAUSED
731
- } else if (client[kPipelining] == null || client[kPipelining] === 1) {
732
- // We must wait a full event loop cycle to reuse this socket to make sure
733
- // that non-spec compliant servers are not closing the connection even if they
734
- // said they won't.
735
- setImmediate(() => client[kResume]())
736
- } else {
737
- client[kResume]()
738
- }
739
-
740
- return 0
741
- }
742
- }
743
-
744
- function onParserTimeout (parser) {
745
- const { socket, timeoutType, client, paused } = parser.deref()
746
-
747
- /* istanbul ignore else */
748
- if (timeoutType === TIMEOUT_HEADERS) {
749
- if (!socket[kWriting] || socket.writableNeedDrain || client[kRunning] > 1) {
750
- assert(!paused, 'cannot be paused while waiting for headers')
751
- util.destroy(socket, new HeadersTimeoutError())
752
- }
753
- } else if (timeoutType === TIMEOUT_BODY) {
754
- if (!paused) {
755
- util.destroy(socket, new BodyTimeoutError())
756
- }
757
- } else if (timeoutType === TIMEOUT_KEEP_ALIVE) {
758
- assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue])
759
- util.destroy(socket, new InformationalError('socket idle timeout'))
760
- }
761
- }
762
-
763
- /**
764
- * @param {import ('./client.js')} client
765
- * @param {import('net').Socket} socket
766
- * @returns
767
- */
768
- async function connectH1 (client, socket) {
769
- client[kSocket] = socket
770
-
771
- if (!llhttpInstance) {
772
- const noop = () => {}
773
- socket.on('error', noop)
774
- llhttpInstance = await llhttpPromise
775
- llhttpPromise = null
776
- socket.off('error', noop)
777
- }
778
-
779
- if (socket.errored) {
780
- throw socket.errored
781
- }
782
-
783
- if (socket.destroyed) {
784
- throw new SocketError('destroyed')
785
- }
786
-
787
- socket[kNoRef] = false
788
- socket[kWriting] = false
789
- socket[kReset] = false
790
- socket[kBlocking] = false
791
- socket[kParser] = new Parser(client, socket, llhttpInstance)
792
-
793
- util.addListener(socket, 'error', onHttpSocketError)
794
- util.addListener(socket, 'readable', onHttpSocketReadable)
795
- util.addListener(socket, 'end', onHttpSocketEnd)
796
- util.addListener(socket, 'close', onHttpSocketClose)
797
-
798
- socket[kClosed] = false
799
- socket.on('close', onSocketClose)
800
-
801
- return {
802
- version: 'h1',
803
- defaultPipelining: 1,
804
- write (request) {
805
- return writeH1(client, request)
806
- },
807
- resume () {
808
- resumeH1(client)
809
- },
810
- /**
811
- * @param {Error|undefined} err
812
- * @param {() => void} callback
813
- */
814
- destroy (err, callback) {
815
- if (socket[kClosed]) {
816
- queueMicrotask(callback)
817
- } else {
818
- socket.on('close', callback)
819
- socket.destroy(err)
820
- }
821
- },
822
- /**
823
- * @returns {boolean}
824
- */
825
- get destroyed () {
826
- return socket.destroyed
827
- },
828
- /**
829
- * @param {import('../core/request.js')} request
830
- * @returns {boolean}
831
- */
832
- busy (request) {
833
- if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
834
- return true
835
- }
836
-
837
- if (request) {
838
- if (client[kRunning] > 0 && !request.idempotent) {
839
- // Non-idempotent request cannot be retried.
840
- // Ensure that no other requests are inflight and
841
- // could cause failure.
842
- return true
843
- }
844
-
845
- if (client[kRunning] > 0 && (request.upgrade || request.method === 'CONNECT')) {
846
- // Don't dispatch an upgrade until all preceding requests have completed.
847
- // A misbehaving server might upgrade the connection before all pipelined
848
- // request has completed.
849
- return true
850
- }
851
-
852
- if (client[kRunning] > 0 && util.bodyLength(request.body) !== 0 &&
853
- (util.isStream(request.body) || util.isAsyncIterable(request.body) || util.isFormDataLike(request.body))) {
854
- // Request with stream or iterator body can error while other requests
855
- // are inflight and indirectly error those as well.
856
- // Ensure this doesn't happen by waiting for inflight
857
- // to complete before dispatching.
858
-
859
- // Request with stream or iterator body cannot be retried.
860
- // Ensure that no other requests are inflight and
861
- // could cause failure.
862
- return true
863
- }
864
- }
865
-
866
- return false
867
- }
868
- }
869
- }
870
-
871
- function onHttpSocketError (err) {
872
- assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID')
873
-
874
- const parser = this[kParser]
875
-
876
- // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
877
- // to the user.
878
- if (err.code === 'ECONNRESET' && parser.statusCode && !parser.shouldKeepAlive) {
879
- // We treat all incoming data so for as a valid response.
880
- parser.onMessageComplete()
881
- return
882
- }
883
-
884
- this[kError] = err
885
-
886
- this[kClient][kOnError](err)
887
- }
888
-
889
- function onHttpSocketReadable () {
890
- this[kParser]?.readMore()
891
- }
892
-
893
- function onHttpSocketEnd () {
894
- const parser = this[kParser]
895
-
896
- if (parser.statusCode && !parser.shouldKeepAlive) {
897
- // We treat all incoming data so far as a valid response.
898
- parser.onMessageComplete()
899
- return
900
- }
901
-
902
- util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this)))
903
- }
904
-
905
- function onHttpSocketClose () {
906
- const parser = this[kParser]
907
-
908
- if (parser) {
909
- if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
910
- // We treat all incoming data so far as a valid response.
911
- parser.onMessageComplete()
912
- }
913
-
914
- this[kParser].destroy()
915
- this[kParser] = null
916
- }
917
-
918
- const err = this[kError] || new SocketError('closed', util.getSocketInfo(this))
919
-
920
- const client = this[kClient]
921
-
922
- client[kSocket] = null
923
- client[kHTTPContext] = null // TODO (fix): This is hacky...
924
-
925
- if (client.destroyed) {
926
- assert(client[kPending] === 0)
927
-
928
- // Fail entire queue.
929
- const requests = client[kQueue].splice(client[kRunningIdx])
930
- for (let i = 0; i < requests.length; i++) {
931
- const request = requests[i]
932
- util.errorRequest(client, request, err)
933
- }
934
- } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') {
935
- // Fail head of pipeline.
936
- const request = client[kQueue][client[kRunningIdx]]
937
- client[kQueue][client[kRunningIdx]++] = null
938
-
939
- util.errorRequest(client, request, err)
940
- }
941
-
942
- client[kPendingIdx] = client[kRunningIdx]
943
-
944
- assert(client[kRunning] === 0)
945
-
946
- client.emit('disconnect', client[kUrl], [client], err)
947
-
948
- client[kResume]()
949
- }
950
-
951
- function onSocketClose () {
952
- this[kClosed] = true
953
- }
954
-
955
- /**
956
- * @param {import('./client.js')} client
957
- */
958
- function resumeH1 (client) {
959
- const socket = client[kSocket]
960
-
961
- if (socket && !socket.destroyed) {
962
- if (client[kSize] === 0) {
963
- if (!socket[kNoRef] && socket.unref) {
964
- socket.unref()
965
- socket[kNoRef] = true
966
- }
967
- } else if (socket[kNoRef] && socket.ref) {
968
- socket.ref()
969
- socket[kNoRef] = false
970
- }
971
-
972
- if (client[kSize] === 0) {
973
- if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
974
- socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
975
- }
976
- } else if (client[kRunning] > 0 && socket[kParser].statusCode < 200) {
977
- if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) {
978
- const request = client[kQueue][client[kRunningIdx]]
979
- const headersTimeout = request.headersTimeout != null
980
- ? request.headersTimeout
981
- : client[kHeadersTimeout]
982
- socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS)
983
- }
984
- }
985
- }
986
- }
987
-
988
- // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2
989
- function shouldSendContentLength (method) {
990
- return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT'
991
- }
992
-
993
- /**
994
- * @param {import('./client.js')} client
995
- * @param {import('../core/request.js')} request
996
- * @returns
997
- */
998
- function writeH1 (client, request) {
999
- const { method, path, host, upgrade, blocking, reset } = request
1000
-
1001
- let { body, headers, contentLength } = request
1002
-
1003
- // https://tools.ietf.org/html/rfc7231#section-4.3.1
1004
- // https://tools.ietf.org/html/rfc7231#section-4.3.2
1005
- // https://tools.ietf.org/html/rfc7231#section-4.3.5
1006
-
1007
- // Sending a payload body on a request that does not
1008
- // expect it can cause undefined behavior on some
1009
- // servers and corrupt connection state. Do not
1010
- // re-use the connection for further requests.
1011
-
1012
- const expectsPayload = (
1013
- method === 'PUT' ||
1014
- method === 'POST' ||
1015
- method === 'PATCH' ||
1016
- method === 'QUERY' ||
1017
- method === 'PROPFIND' ||
1018
- method === 'PROPPATCH'
1019
- )
1020
-
1021
- if (util.isFormDataLike(body)) {
1022
- if (!extractBody) {
1023
- extractBody = require('../web/fetch/body.js').extractBody
1024
- }
1025
-
1026
- const [bodyStream, contentType] = extractBody(body)
1027
- if (request.contentType == null) {
1028
- headers.push('content-type', contentType)
1029
- }
1030
- body = bodyStream.stream
1031
- contentLength = bodyStream.length
1032
- } else if (util.isBlobLike(body) && request.contentType == null && body.type) {
1033
- headers.push('content-type', body.type)
1034
- }
1035
-
1036
- if (body && typeof body.read === 'function') {
1037
- // Try to read EOF in order to get length.
1038
- body.read(0)
1039
- }
1040
-
1041
- const bodyLength = util.bodyLength(body)
1042
-
1043
- contentLength = bodyLength ?? contentLength
1044
-
1045
- if (contentLength === null) {
1046
- contentLength = request.contentLength
1047
- }
1048
-
1049
- if (contentLength === 0 && !expectsPayload) {
1050
- // https://tools.ietf.org/html/rfc7230#section-3.3.2
1051
- // A user agent SHOULD NOT send a Content-Length header field when
1052
- // the request message does not contain a payload body and the method
1053
- // semantics do not anticipate such a body.
1054
-
1055
- contentLength = null
1056
- }
1057
-
1058
- // https://github.com/nodejs/undici/issues/2046
1059
- // A user agent may send a Content-Length header with 0 value, this should be allowed.
1060
- if (shouldSendContentLength(method) && contentLength > 0 && request.contentLength !== null && request.contentLength !== contentLength) {
1061
- if (client[kStrictContentLength]) {
1062
- util.errorRequest(client, request, new RequestContentLengthMismatchError())
1063
- return false
1064
- }
1065
-
1066
- process.emitWarning(new RequestContentLengthMismatchError())
1067
- }
1068
-
1069
- const socket = client[kSocket]
1070
-
1071
- /**
1072
- * @param {Error} [err]
1073
- * @returns {void}
1074
- */
1075
- const abort = (err) => {
1076
- if (request.aborted || request.completed) {
1077
- return
1078
- }
1079
-
1080
- util.errorRequest(client, request, err || new RequestAbortedError())
1081
-
1082
- util.destroy(body)
1083
- util.destroy(socket, new InformationalError('aborted'))
1084
- }
1085
-
1086
- try {
1087
- request.onConnect(abort)
1088
- } catch (err) {
1089
- util.errorRequest(client, request, err)
1090
- }
1091
-
1092
- if (request.aborted) {
1093
- return false
1094
- }
1095
-
1096
- if (method === 'HEAD') {
1097
- // https://github.com/mcollina/undici/issues/258
1098
- // Close after a HEAD request to interop with misbehaving servers
1099
- // that may send a body in the response.
1100
-
1101
- socket[kReset] = true
1102
- }
1103
-
1104
- if (upgrade || method === 'CONNECT') {
1105
- // On CONNECT or upgrade, block pipeline from dispatching further
1106
- // requests on this connection.
1107
-
1108
- socket[kReset] = true
1109
- }
1110
-
1111
- if (reset != null) {
1112
- socket[kReset] = reset
1113
- }
1114
-
1115
- if (client[kMaxRequests] && socket[kCounter]++ >= client[kMaxRequests]) {
1116
- socket[kReset] = true
1117
- }
1118
-
1119
- if (blocking) {
1120
- socket[kBlocking] = true
1121
- }
1122
-
1123
- let header = `${method} ${path} HTTP/1.1\r\n`
1124
-
1125
- if (typeof host === 'string') {
1126
- header += `host: ${host}\r\n`
1127
- } else {
1128
- header += client[kHostHeader]
1129
- }
1130
-
1131
- if (upgrade) {
1132
- header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n`
1133
- } else if (client[kPipelining] && !socket[kReset]) {
1134
- header += 'connection: keep-alive\r\n'
1135
- } else {
1136
- header += 'connection: close\r\n'
1137
- }
1138
-
1139
- if (Array.isArray(headers)) {
1140
- for (let n = 0; n < headers.length; n += 2) {
1141
- const key = headers[n + 0]
1142
- const val = headers[n + 1]
1143
-
1144
- if (Array.isArray(val)) {
1145
- for (let i = 0; i < val.length; i++) {
1146
- header += `${key}: ${val[i]}\r\n`
1147
- }
1148
- } else {
1149
- header += `${key}: ${val}\r\n`
1150
- }
1151
- }
1152
- }
1153
-
1154
- if (channels.sendHeaders.hasSubscribers) {
1155
- channels.sendHeaders.publish({ request, headers: header, socket })
1156
- }
1157
-
1158
- /* istanbul ignore else: assertion */
1159
- if (!body || bodyLength === 0) {
1160
- writeBuffer(abort, null, client, request, socket, contentLength, header, expectsPayload)
1161
- } else if (util.isBuffer(body)) {
1162
- writeBuffer(abort, body, client, request, socket, contentLength, header, expectsPayload)
1163
- } else if (util.isBlobLike(body)) {
1164
- if (typeof body.stream === 'function') {
1165
- writeIterable(abort, body.stream(), client, request, socket, contentLength, header, expectsPayload)
1166
- } else {
1167
- writeBlob(abort, body, client, request, socket, contentLength, header, expectsPayload)
1168
- }
1169
- } else if (util.isStream(body)) {
1170
- writeStream(abort, body, client, request, socket, contentLength, header, expectsPayload)
1171
- } else if (util.isIterable(body)) {
1172
- writeIterable(abort, body, client, request, socket, contentLength, header, expectsPayload)
1173
- } else {
1174
- assert(false)
1175
- }
1176
-
1177
- return true
1178
- }
1179
-
1180
- /**
1181
- * @param {AbortCallback} abort
1182
- * @param {import('stream').Stream} body
1183
- * @param {import('./client.js')} client
1184
- * @param {import('../core/request.js')} request
1185
- * @param {import('net').Socket} socket
1186
- * @param {number} contentLength
1187
- * @param {string} header
1188
- * @param {boolean} expectsPayload
1189
- */
1190
- function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1191
- assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined')
1192
-
1193
- let finished = false
1194
-
1195
- const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header })
1196
-
1197
- /**
1198
- * @param {Buffer} chunk
1199
- * @returns {void}
1200
- */
1201
- const onData = function (chunk) {
1202
- if (finished) {
1203
- return
1204
- }
1205
-
1206
- try {
1207
- if (!writer.write(chunk) && this.pause) {
1208
- this.pause()
1209
- }
1210
- } catch (err) {
1211
- util.destroy(this, err)
1212
- }
1213
- }
1214
-
1215
- /**
1216
- * @returns {void}
1217
- */
1218
- const onDrain = function () {
1219
- if (finished) {
1220
- return
1221
- }
1222
-
1223
- if (body.resume) {
1224
- body.resume()
1225
- }
1226
- }
1227
-
1228
- /**
1229
- * @returns {void}
1230
- */
1231
- const onClose = function () {
1232
- // 'close' might be emitted *before* 'error' for
1233
- // broken streams. Wait a tick to avoid this case.
1234
- queueMicrotask(() => {
1235
- // It's only safe to remove 'error' listener after
1236
- // 'close'.
1237
- body.removeListener('error', onFinished)
1238
- })
1239
-
1240
- if (!finished) {
1241
- const err = new RequestAbortedError()
1242
- queueMicrotask(() => onFinished(err))
1243
- }
1244
- }
1245
-
1246
- /**
1247
- * @param {Error} [err]
1248
- * @returns
1249
- */
1250
- const onFinished = function (err) {
1251
- if (finished) {
1252
- return
1253
- }
1254
-
1255
- finished = true
1256
-
1257
- assert(socket.destroyed || (socket[kWriting] && client[kRunning] <= 1))
1258
-
1259
- socket
1260
- .off('drain', onDrain)
1261
- .off('error', onFinished)
1262
-
1263
- body
1264
- .removeListener('data', onData)
1265
- .removeListener('end', onFinished)
1266
- .removeListener('close', onClose)
1267
-
1268
- if (!err) {
1269
- try {
1270
- writer.end()
1271
- } catch (er) {
1272
- err = er
1273
- }
1274
- }
1275
-
1276
- writer.destroy(err)
1277
-
1278
- if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) {
1279
- util.destroy(body, err)
1280
- } else {
1281
- util.destroy(body)
1282
- }
1283
- }
1284
-
1285
- body
1286
- .on('data', onData)
1287
- .on('end', onFinished)
1288
- .on('error', onFinished)
1289
- .on('close', onClose)
1290
-
1291
- if (body.resume) {
1292
- body.resume()
1293
- }
1294
-
1295
- socket
1296
- .on('drain', onDrain)
1297
- .on('error', onFinished)
1298
-
1299
- if (body.errorEmitted ?? body.errored) {
1300
- setImmediate(() => onFinished(body.errored))
1301
- } else if (body.endEmitted ?? body.readableEnded) {
1302
- setImmediate(() => onFinished(null))
1303
- }
1304
-
1305
- if (body.closeEmitted ?? body.closed) {
1306
- setImmediate(onClose)
1307
- }
1308
- }
1309
-
1310
- /**
1311
- * @typedef AbortCallback
1312
- * @type {Function}
1313
- * @param {Error} [err]
1314
- * @returns {void}
1315
- */
1316
-
1317
- /**
1318
- * @param {AbortCallback} abort
1319
- * @param {Uint8Array|null} body
1320
- * @param {import('./client.js')} client
1321
- * @param {import('../core/request.js')} request
1322
- * @param {import('net').Socket} socket
1323
- * @param {number} contentLength
1324
- * @param {string} header
1325
- * @param {boolean} expectsPayload
1326
- * @returns {void}
1327
- */
1328
- function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1329
- try {
1330
- if (!body) {
1331
- if (contentLength === 0) {
1332
- socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
1333
- } else {
1334
- assert(contentLength === null, 'no body must not have content length')
1335
- socket.write(`${header}\r\n`, 'latin1')
1336
- }
1337
- } else if (util.isBuffer(body)) {
1338
- assert(contentLength === body.byteLength, 'buffer body must have content length')
1339
-
1340
- socket.cork()
1341
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1342
- socket.write(body)
1343
- socket.uncork()
1344
- request.onBodySent(body)
1345
-
1346
- if (!expectsPayload && request.reset !== false) {
1347
- socket[kReset] = true
1348
- }
1349
- }
1350
- request.onRequestSent()
1351
-
1352
- client[kResume]()
1353
- } catch (err) {
1354
- abort(err)
1355
- }
1356
- }
1357
-
1358
- /**
1359
- * @param {AbortCallback} abort
1360
- * @param {Blob} body
1361
- * @param {import('./client.js')} client
1362
- * @param {import('../core/request.js')} request
1363
- * @param {import('net').Socket} socket
1364
- * @param {number} contentLength
1365
- * @param {string} header
1366
- * @param {boolean} expectsPayload
1367
- * @returns {Promise<void>}
1368
- */
1369
- async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1370
- assert(contentLength === body.size, 'blob body must have content length')
1371
-
1372
- try {
1373
- if (contentLength != null && contentLength !== body.size) {
1374
- throw new RequestContentLengthMismatchError()
1375
- }
1376
-
1377
- const buffer = Buffer.from(await body.arrayBuffer())
1378
-
1379
- socket.cork()
1380
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1381
- socket.write(buffer)
1382
- socket.uncork()
1383
-
1384
- request.onBodySent(buffer)
1385
- request.onRequestSent()
1386
-
1387
- if (!expectsPayload && request.reset !== false) {
1388
- socket[kReset] = true
1389
- }
1390
-
1391
- client[kResume]()
1392
- } catch (err) {
1393
- abort(err)
1394
- }
1395
- }
1396
-
1397
- /**
1398
- * @param {AbortCallback} abort
1399
- * @param {Iterable} body
1400
- * @param {import('./client.js')} client
1401
- * @param {import('../core/request.js')} request
1402
- * @param {import('net').Socket} socket
1403
- * @param {number} contentLength
1404
- * @param {string} header
1405
- * @param {boolean} expectsPayload
1406
- * @returns {Promise<void>}
1407
- */
1408
- async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1409
- assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined')
1410
-
1411
- let callback = null
1412
- function onDrain () {
1413
- if (callback) {
1414
- const cb = callback
1415
- callback = null
1416
- cb()
1417
- }
1418
- }
1419
-
1420
- const waitForDrain = () => new Promise((resolve, reject) => {
1421
- assert(callback === null)
1422
-
1423
- if (socket[kError]) {
1424
- reject(socket[kError])
1425
- } else {
1426
- callback = resolve
1427
- }
1428
- })
1429
-
1430
- socket
1431
- .on('close', onDrain)
1432
- .on('drain', onDrain)
1433
-
1434
- const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header })
1435
- try {
1436
- // It's up to the user to somehow abort the async iterable.
1437
- for await (const chunk of body) {
1438
- if (socket[kError]) {
1439
- throw socket[kError]
1440
- }
1441
-
1442
- if (!writer.write(chunk)) {
1443
- await waitForDrain()
1444
- }
1445
- }
1446
-
1447
- writer.end()
1448
- } catch (err) {
1449
- writer.destroy(err)
1450
- } finally {
1451
- socket
1452
- .off('close', onDrain)
1453
- .off('drain', onDrain)
1454
- }
1455
- }
1456
-
1457
- class AsyncWriter {
1458
- /**
1459
- *
1460
- * @param {object} arg
1461
- * @param {AbortCallback} arg.abort
1462
- * @param {import('net').Socket} arg.socket
1463
- * @param {import('../core/request.js')} arg.request
1464
- * @param {number} arg.contentLength
1465
- * @param {import('./client.js')} arg.client
1466
- * @param {boolean} arg.expectsPayload
1467
- * @param {string} arg.header
1468
- */
1469
- constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) {
1470
- this.socket = socket
1471
- this.request = request
1472
- this.contentLength = contentLength
1473
- this.client = client
1474
- this.bytesWritten = 0
1475
- this.expectsPayload = expectsPayload
1476
- this.header = header
1477
- this.abort = abort
1478
-
1479
- socket[kWriting] = true
1480
- }
1481
-
1482
- /**
1483
- * @param {Buffer} chunk
1484
- * @returns
1485
- */
1486
- write (chunk) {
1487
- const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this
1488
-
1489
- if (socket[kError]) {
1490
- throw socket[kError]
1491
- }
1492
-
1493
- if (socket.destroyed) {
1494
- return false
1495
- }
1496
-
1497
- const len = Buffer.byteLength(chunk)
1498
- if (!len) {
1499
- return true
1500
- }
1501
-
1502
- // We should defer writing chunks.
1503
- if (contentLength !== null && bytesWritten + len > contentLength) {
1504
- if (client[kStrictContentLength]) {
1505
- throw new RequestContentLengthMismatchError()
1506
- }
1507
-
1508
- process.emitWarning(new RequestContentLengthMismatchError())
1509
- }
1510
-
1511
- socket.cork()
1512
-
1513
- if (bytesWritten === 0) {
1514
- if (!expectsPayload && request.reset !== false) {
1515
- socket[kReset] = true
1516
- }
1517
-
1518
- if (contentLength === null) {
1519
- socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1')
1520
- } else {
1521
- socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
1522
- }
1523
- }
1524
-
1525
- if (contentLength === null) {
1526
- socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1')
1527
- }
1528
-
1529
- this.bytesWritten += len
1530
-
1531
- const ret = socket.write(chunk)
1532
-
1533
- socket.uncork()
1534
-
1535
- request.onBodySent(chunk)
1536
-
1537
- if (!ret) {
1538
- if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
1539
- // istanbul ignore else: only for jest
1540
- if (socket[kParser].timeout.refresh) {
1541
- socket[kParser].timeout.refresh()
1542
- }
1543
- }
1544
- }
1545
-
1546
- return ret
1547
- }
1548
-
1549
- /**
1550
- * @returns {void}
1551
- */
1552
- end () {
1553
- const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this
1554
- request.onRequestSent()
1555
-
1556
- socket[kWriting] = false
1557
-
1558
- if (socket[kError]) {
1559
- throw socket[kError]
1560
- }
1561
-
1562
- if (socket.destroyed) {
1563
- return
1564
- }
1565
-
1566
- if (bytesWritten === 0) {
1567
- if (expectsPayload) {
1568
- // https://tools.ietf.org/html/rfc7230#section-3.3.2
1569
- // A user agent SHOULD send a Content-Length in a request message when
1570
- // no Transfer-Encoding is sent and the request method defines a meaning
1571
- // for an enclosed payload body.
1572
-
1573
- socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1')
1574
- } else {
1575
- socket.write(`${header}\r\n`, 'latin1')
1576
- }
1577
- } else if (contentLength === null) {
1578
- socket.write('\r\n0\r\n\r\n', 'latin1')
1579
- }
1580
-
1581
- if (contentLength !== null && bytesWritten !== contentLength) {
1582
- if (client[kStrictContentLength]) {
1583
- throw new RequestContentLengthMismatchError()
1584
- } else {
1585
- process.emitWarning(new RequestContentLengthMismatchError())
1586
- }
1587
- }
1588
-
1589
- if (socket[kParser].timeout && socket[kParser].timeoutType === TIMEOUT_HEADERS) {
1590
- // istanbul ignore else: only for jest
1591
- if (socket[kParser].timeout.refresh) {
1592
- socket[kParser].timeout.refresh()
1593
- }
1594
- }
1595
-
1596
- client[kResume]()
1597
- }
1598
-
1599
- /**
1600
- * @param {Error} [err]
1601
- * @returns {void}
1602
- */
1603
- destroy (err) {
1604
- const { socket, client, abort } = this
1605
-
1606
- socket[kWriting] = false
1607
-
1608
- if (err) {
1609
- assert(client[kRunning] <= 1, 'pipeline should only contain this request')
1610
- abort(err)
1611
- }
1612
- }
1613
- }
1614
-
1615
- module.exports = connectH1