undici 6.20.0 → 7.0.0-alpha.2

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 (137) hide show
  1. package/README.md +6 -10
  2. package/docs/docs/api/Agent.md +0 -3
  3. package/docs/docs/api/Client.md +1 -3
  4. package/docs/docs/api/Debug.md +1 -1
  5. package/docs/docs/api/Dispatcher.md +60 -8
  6. package/docs/docs/api/EnvHttpProxyAgent.md +0 -1
  7. package/docs/docs/api/Fetch.md +1 -0
  8. package/docs/docs/api/MockAgent.md +2 -0
  9. package/docs/docs/api/MockPool.md +2 -1
  10. package/docs/docs/api/Pool.md +0 -1
  11. package/docs/docs/api/RetryAgent.md +1 -1
  12. package/docs/docs/api/RetryHandler.md +1 -1
  13. package/docs/docs/api/WebSocket.md +45 -3
  14. package/index.js +6 -6
  15. package/lib/api/abort-signal.js +2 -0
  16. package/lib/api/api-connect.js +3 -1
  17. package/lib/api/api-pipeline.js +7 -6
  18. package/lib/api/api-request.js +32 -47
  19. package/lib/api/api-stream.js +39 -50
  20. package/lib/api/api-upgrade.js +5 -3
  21. package/lib/api/readable.js +261 -64
  22. package/lib/api/util.js +2 -0
  23. package/lib/core/constants.js +11 -9
  24. package/lib/core/diagnostics.js +122 -128
  25. package/lib/core/errors.js +4 -4
  26. package/lib/core/request.js +11 -9
  27. package/lib/core/symbols.js +2 -1
  28. package/lib/core/tree.js +9 -1
  29. package/lib/core/util.js +219 -48
  30. package/lib/dispatcher/agent.js +3 -17
  31. package/lib/dispatcher/balanced-pool.js +5 -8
  32. package/lib/dispatcher/client-h1.js +278 -54
  33. package/lib/dispatcher/client-h2.js +1 -1
  34. package/lib/dispatcher/client.js +23 -34
  35. package/lib/dispatcher/dispatcher-base.js +2 -34
  36. package/lib/dispatcher/dispatcher.js +3 -24
  37. package/lib/dispatcher/fixed-queue.js +91 -49
  38. package/lib/dispatcher/pool-stats.js +2 -0
  39. package/lib/dispatcher/pool.js +3 -6
  40. package/lib/dispatcher/proxy-agent.js +6 -7
  41. package/lib/handler/decorator-handler.js +24 -0
  42. package/lib/handler/redirect-handler.js +11 -2
  43. package/lib/handler/retry-handler.js +12 -3
  44. package/lib/interceptor/dns.js +346 -0
  45. package/lib/interceptor/dump.js +2 -2
  46. package/lib/interceptor/redirect.js +11 -14
  47. package/lib/interceptor/response-error.js +4 -1
  48. package/lib/llhttp/constants.d.ts +97 -0
  49. package/lib/llhttp/constants.js +412 -192
  50. package/lib/llhttp/constants.js.map +1 -0
  51. package/lib/llhttp/llhttp-wasm.js +11 -1
  52. package/lib/llhttp/llhttp_simd-wasm.js +11 -1
  53. package/lib/llhttp/utils.d.ts +2 -0
  54. package/lib/llhttp/utils.js +9 -9
  55. package/lib/llhttp/utils.js.map +1 -0
  56. package/lib/mock/mock-agent.js +5 -8
  57. package/lib/mock/mock-client.js +9 -4
  58. package/lib/mock/mock-errors.js +3 -1
  59. package/lib/mock/mock-interceptor.js +8 -6
  60. package/lib/mock/mock-pool.js +9 -4
  61. package/lib/mock/mock-symbols.js +3 -1
  62. package/lib/mock/mock-utils.js +29 -5
  63. package/lib/web/cache/cache.js +24 -21
  64. package/lib/web/cache/cachestorage.js +1 -1
  65. package/lib/web/cookies/index.js +17 -13
  66. package/lib/web/cookies/parse.js +2 -2
  67. package/lib/web/eventsource/eventsource-stream.js +9 -8
  68. package/lib/web/eventsource/eventsource.js +10 -6
  69. package/lib/web/fetch/body.js +42 -36
  70. package/lib/web/fetch/constants.js +35 -26
  71. package/lib/web/fetch/data-url.js +1 -1
  72. package/lib/web/fetch/formdata-parser.js +2 -2
  73. package/lib/web/fetch/formdata.js +65 -54
  74. package/lib/web/fetch/headers.js +117 -85
  75. package/lib/web/fetch/index.js +55 -62
  76. package/lib/web/fetch/request.js +135 -77
  77. package/lib/web/fetch/response.js +86 -56
  78. package/lib/web/fetch/util.js +90 -64
  79. package/lib/web/fetch/webidl.js +99 -64
  80. package/lib/web/websocket/connection.js +76 -147
  81. package/lib/web/websocket/constants.js +3 -4
  82. package/lib/web/websocket/events.js +4 -2
  83. package/lib/web/websocket/frame.js +45 -3
  84. package/lib/web/websocket/receiver.js +29 -33
  85. package/lib/web/websocket/sender.js +18 -13
  86. package/lib/web/websocket/stream/websocketerror.js +83 -0
  87. package/lib/web/websocket/stream/websocketstream.js +485 -0
  88. package/lib/web/websocket/util.js +128 -77
  89. package/lib/web/websocket/websocket.js +234 -135
  90. package/package.json +20 -33
  91. package/scripts/strip-comments.js +3 -1
  92. package/types/agent.d.ts +7 -7
  93. package/types/api.d.ts +24 -24
  94. package/types/balanced-pool.d.ts +11 -11
  95. package/types/client.d.ts +11 -12
  96. package/types/diagnostics-channel.d.ts +10 -10
  97. package/types/dispatcher.d.ts +96 -97
  98. package/types/env-http-proxy-agent.d.ts +2 -2
  99. package/types/errors.d.ts +53 -47
  100. package/types/fetch.d.ts +8 -8
  101. package/types/formdata.d.ts +7 -7
  102. package/types/global-dispatcher.d.ts +4 -4
  103. package/types/global-origin.d.ts +5 -5
  104. package/types/handlers.d.ts +4 -4
  105. package/types/header.d.ts +157 -1
  106. package/types/index.d.ts +42 -46
  107. package/types/interceptors.d.ts +22 -8
  108. package/types/mock-agent.d.ts +21 -18
  109. package/types/mock-client.d.ts +4 -4
  110. package/types/mock-errors.d.ts +3 -3
  111. package/types/mock-interceptor.d.ts +19 -19
  112. package/types/mock-pool.d.ts +4 -4
  113. package/types/patch.d.ts +0 -4
  114. package/types/pool-stats.d.ts +8 -8
  115. package/types/pool.d.ts +12 -12
  116. package/types/proxy-agent.d.ts +4 -4
  117. package/types/readable.d.ts +22 -14
  118. package/types/retry-agent.d.ts +1 -1
  119. package/types/retry-handler.d.ts +8 -8
  120. package/types/util.d.ts +3 -3
  121. package/types/utility.d.ts +7 -0
  122. package/types/webidl.d.ts +44 -6
  123. package/types/websocket.d.ts +34 -1
  124. package/docs/docs/api/DispatchInterceptor.md +0 -60
  125. package/lib/interceptor/redirect-interceptor.js +0 -21
  126. package/lib/mock/pluralizer.js +0 -29
  127. package/lib/web/cache/symbols.js +0 -5
  128. package/lib/web/fetch/file.js +0 -126
  129. package/lib/web/fetch/symbols.js +0 -9
  130. package/lib/web/fileapi/encoding.js +0 -290
  131. package/lib/web/fileapi/filereader.js +0 -344
  132. package/lib/web/fileapi/progressevent.js +0 -78
  133. package/lib/web/fileapi/symbols.js +0 -10
  134. package/lib/web/fileapi/util.js +0 -391
  135. package/lib/web/websocket/symbols.js +0 -12
  136. package/types/file.d.ts +0 -39
  137. package/types/filereader.d.ts +0 -54
@@ -78,56 +78,107 @@ async function lazyllhttp () {
78
78
 
79
79
  return await WebAssembly.instantiate(mod, {
80
80
  env: {
81
- /* eslint-disable camelcase */
82
-
81
+ /**
82
+ * @param {number} p
83
+ * @param {number} at
84
+ * @param {number} len
85
+ * @returns {number}
86
+ */
83
87
  wasm_on_url: (p, at, len) => {
84
88
  /* istanbul ignore next */
85
89
  return 0
86
90
  },
91
+ /**
92
+ * @param {number} p
93
+ * @param {number} at
94
+ * @param {number} len
95
+ * @returns {number}
96
+ */
87
97
  wasm_on_status: (p, at, len) => {
88
98
  assert(currentParser.ptr === p)
89
99
  const start = at - currentBufferPtr + currentBufferRef.byteOffset
90
- return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
100
+ return currentParser.onStatus(new FastBuffer(currentBufferRef.buffer, start, len))
91
101
  },
102
+ /**
103
+ * @param {number} p
104
+ * @returns {number}
105
+ */
92
106
  wasm_on_message_begin: (p) => {
93
107
  assert(currentParser.ptr === p)
94
- return currentParser.onMessageBegin() || 0
108
+ return currentParser.onMessageBegin()
95
109
  },
110
+ /**
111
+ * @param {number} p
112
+ * @param {number} at
113
+ * @param {number} len
114
+ * @returns {number}
115
+ */
96
116
  wasm_on_header_field: (p, at, len) => {
97
117
  assert(currentParser.ptr === p)
98
118
  const start = at - currentBufferPtr + currentBufferRef.byteOffset
99
- return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
119
+ return currentParser.onHeaderField(new FastBuffer(currentBufferRef.buffer, start, len))
100
120
  },
121
+ /**
122
+ * @param {number} p
123
+ * @param {number} at
124
+ * @param {number} len
125
+ * @returns {number}
126
+ */
101
127
  wasm_on_header_value: (p, at, len) => {
102
128
  assert(currentParser.ptr === p)
103
129
  const start = at - currentBufferPtr + currentBufferRef.byteOffset
104
- return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
130
+ return currentParser.onHeaderValue(new FastBuffer(currentBufferRef.buffer, start, len))
105
131
  },
132
+ /**
133
+ * @param {number} p
134
+ * @param {number} statusCode
135
+ * @param {0|1} upgrade
136
+ * @param {0|1} shouldKeepAlive
137
+ * @returns {number}
138
+ */
106
139
  wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
107
140
  assert(currentParser.ptr === p)
108
- return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
141
+ return currentParser.onHeadersComplete(statusCode, upgrade === 1, shouldKeepAlive === 1)
109
142
  },
143
+ /**
144
+ * @param {number} p
145
+ * @param {number} at
146
+ * @param {number} len
147
+ * @returns {number}
148
+ */
110
149
  wasm_on_body: (p, at, len) => {
111
150
  assert(currentParser.ptr === p)
112
151
  const start = at - currentBufferPtr + currentBufferRef.byteOffset
113
- return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len)) || 0
152
+ return currentParser.onBody(new FastBuffer(currentBufferRef.buffer, start, len))
114
153
  },
154
+ /**
155
+ * @param {number} p
156
+ * @returns {number}
157
+ */
115
158
  wasm_on_message_complete: (p) => {
116
159
  assert(currentParser.ptr === p)
117
- return currentParser.onMessageComplete() || 0
160
+ return currentParser.onMessageComplete()
118
161
  }
119
162
 
120
- /* eslint-enable camelcase */
121
163
  }
122
164
  })
123
165
  }
124
166
 
125
167
  let llhttpInstance = null
168
+ /**
169
+ * @type {Promise<WebAssembly.Instance>|null}
170
+ */
126
171
  let llhttpPromise = lazyllhttp()
127
172
  llhttpPromise.catch()
128
173
 
174
+ /**
175
+ * @type {Parser|null}
176
+ */
129
177
  let currentParser = null
130
178
  let currentBufferRef = null
179
+ /**
180
+ * @type {number}
181
+ */
131
182
  let currentBufferSize = 0
132
183
  let currentBufferPtr = null
133
184
 
@@ -144,17 +195,23 @@ const TIMEOUT_BODY = 4 | USE_FAST_TIMER
144
195
  const TIMEOUT_KEEP_ALIVE = 8 | USE_NATIVE_TIMER
145
196
 
146
197
  class Parser {
198
+ /**
199
+ * @param {import('./client.js')} client
200
+ * @param {import('net').Socket} socket
201
+ * @param {*} llhttp
202
+ */
147
203
  constructor (client, socket, { exports }) {
148
- assert(Number.isFinite(client[kMaxHeadersSize]) && client[kMaxHeadersSize] > 0)
149
-
150
204
  this.llhttp = exports
151
205
  this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE)
152
206
  this.client = client
207
+ /**
208
+ * @type {import('net').Socket}
209
+ */
153
210
  this.socket = socket
154
211
  this.timeout = null
155
212
  this.timeoutValue = null
156
213
  this.timeoutType = null
157
- this.statusCode = null
214
+ this.statusCode = 0
158
215
  this.statusText = ''
159
216
  this.upgrade = false
160
217
  this.headers = []
@@ -213,7 +270,7 @@ class Parser {
213
270
  }
214
271
 
215
272
  assert(this.ptr != null)
216
- assert(currentParser == null)
273
+ assert(currentParser === null)
217
274
 
218
275
  this.llhttp.llhttp_resume(this.ptr)
219
276
 
@@ -240,22 +297,27 @@ class Parser {
240
297
  }
241
298
  }
242
299
 
243
- execute (data) {
300
+ /**
301
+ * @param {Buffer} chunk
302
+ */
303
+ execute (chunk) {
304
+ assert(currentParser === null)
244
305
  assert(this.ptr != null)
245
- assert(currentParser == null)
246
306
  assert(!this.paused)
247
307
 
248
308
  const { socket, llhttp } = this
249
309
 
250
- if (data.length > currentBufferSize) {
310
+ // Allocate a new buffer if the current buffer is too small.
311
+ if (chunk.length > currentBufferSize) {
251
312
  if (currentBufferPtr) {
252
313
  llhttp.free(currentBufferPtr)
253
314
  }
254
- currentBufferSize = Math.ceil(data.length / 4096) * 4096
315
+ // Allocate a buffer that is a multiple of 4096 bytes.
316
+ currentBufferSize = Math.ceil(chunk.length / 4096) * 4096
255
317
  currentBufferPtr = llhttp.malloc(currentBufferSize)
256
318
  }
257
319
 
258
- new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(data)
320
+ new Uint8Array(llhttp.memory.buffer, currentBufferPtr, currentBufferSize).set(chunk)
259
321
 
260
322
  // Call `execute` on the wasm parser.
261
323
  // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data,
@@ -265,9 +327,9 @@ class Parser {
265
327
  let ret
266
328
 
267
329
  try {
268
- currentBufferRef = data
330
+ currentBufferRef = chunk
269
331
  currentParser = this
270
- ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, data.length)
332
+ ret = llhttp.llhttp_execute(this.ptr, currentBufferPtr, chunk.length)
271
333
  /* eslint-disable-next-line no-useless-catch */
272
334
  } catch (err) {
273
335
  /* istanbul ignore next: difficult to make a test case for */
@@ -277,25 +339,27 @@ class Parser {
277
339
  currentBufferRef = null
278
340
  }
279
341
 
280
- const offset = llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr
281
-
282
- if (ret === constants.ERROR.PAUSED_UPGRADE) {
283
- this.onUpgrade(data.slice(offset))
284
- } else if (ret === constants.ERROR.PAUSED) {
285
- this.paused = true
286
- socket.unshift(data.slice(offset))
287
- } else if (ret !== constants.ERROR.OK) {
288
- const ptr = llhttp.llhttp_get_error_reason(this.ptr)
289
- let message = ''
290
- /* istanbul ignore else: difficult to make a test case for */
291
- if (ptr) {
292
- const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0)
293
- message =
294
- 'Response does not match the HTTP/1.1 protocol (' +
295
- Buffer.from(llhttp.memory.buffer, ptr, len).toString() +
296
- ')'
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)
297
362
  }
298
- throw new HTTPParserError(message, constants.ERROR[ret], data.slice(offset))
299
363
  }
300
364
  } catch (err) {
301
365
  util.destroy(socket, err)
@@ -303,8 +367,8 @@ class Parser {
303
367
  }
304
368
 
305
369
  destroy () {
370
+ assert(currentParser === null)
306
371
  assert(this.ptr != null)
307
- assert(currentParser == null)
308
372
 
309
373
  this.llhttp.llhttp_free(this.ptr)
310
374
  this.ptr = null
@@ -317,10 +381,18 @@ class Parser {
317
381
  this.paused = false
318
382
  }
319
383
 
384
+ /**
385
+ * @param {Buffer} buf
386
+ * @returns {0}
387
+ */
320
388
  onStatus (buf) {
321
389
  this.statusText = buf.toString()
390
+ return 0
322
391
  }
323
392
 
393
+ /**
394
+ * @returns {0|-1}
395
+ */
324
396
  onMessageBegin () {
325
397
  const { socket, client } = this
326
398
 
@@ -334,8 +406,14 @@ class Parser {
334
406
  return -1
335
407
  }
336
408
  request.onResponseStarted()
409
+
410
+ return 0
337
411
  }
338
412
 
413
+ /**
414
+ * @param {Buffer} buf
415
+ * @returns {number}
416
+ */
339
417
  onHeaderField (buf) {
340
418
  const len = this.headers.length
341
419
 
@@ -346,8 +424,14 @@ class Parser {
346
424
  }
347
425
 
348
426
  this.trackHeader(buf.length)
427
+
428
+ return 0
349
429
  }
350
430
 
431
+ /**
432
+ * @param {Buffer} buf
433
+ * @returns {number}
434
+ */
351
435
  onHeaderValue (buf) {
352
436
  let len = this.headers.length
353
437
 
@@ -371,8 +455,13 @@ class Parser {
371
455
  }
372
456
 
373
457
  this.trackHeader(buf.length)
458
+
459
+ return 0
374
460
  }
375
461
 
462
+ /**
463
+ * @param {number} len
464
+ */
376
465
  trackHeader (len) {
377
466
  this.headersSize += len
378
467
  if (this.headersSize >= this.headersMaxSize) {
@@ -380,6 +469,9 @@ class Parser {
380
469
  }
381
470
  }
382
471
 
472
+ /**
473
+ * @param {Buffer} head
474
+ */
383
475
  onUpgrade (head) {
384
476
  const { upgrade, client, socket, headers, statusCode } = this
385
477
 
@@ -393,9 +485,9 @@ class Parser {
393
485
  assert(request)
394
486
  assert(request.upgrade || request.method === 'CONNECT')
395
487
 
396
- this.statusCode = null
488
+ this.statusCode = 0
397
489
  this.statusText = ''
398
- this.shouldKeepAlive = null
490
+ this.shouldKeepAlive = false
399
491
 
400
492
  this.headers = []
401
493
  this.headersSize = 0
@@ -424,6 +516,12 @@ class Parser {
424
516
  client[kResume]()
425
517
  }
426
518
 
519
+ /**
520
+ * @param {number} statusCode
521
+ * @param {boolean} upgrade
522
+ * @param {boolean} shouldKeepAlive
523
+ * @returns {number}
524
+ */
427
525
  onHeadersComplete (statusCode, upgrade, shouldKeepAlive) {
428
526
  const { client, socket, headers, statusText } = this
429
527
 
@@ -533,6 +631,10 @@ class Parser {
533
631
  return pause ? constants.ERROR.PAUSED : 0
534
632
  }
535
633
 
634
+ /**
635
+ * @param {Buffer} buf
636
+ * @returns {number}
637
+ */
536
638
  onBody (buf) {
537
639
  const { client, socket, statusCode, maxResponseSize } = this
538
640
 
@@ -563,8 +665,13 @@ class Parser {
563
665
  if (request.onData(buf) === false) {
564
666
  return constants.ERROR.PAUSED
565
667
  }
668
+
669
+ return 0
566
670
  }
567
671
 
672
+ /**
673
+ * @returns {number}
674
+ */
568
675
  onMessageComplete () {
569
676
  const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this
570
677
 
@@ -573,7 +680,7 @@ class Parser {
573
680
  }
574
681
 
575
682
  if (upgrade) {
576
- return
683
+ return 0
577
684
  }
578
685
 
579
686
  assert(statusCode >= 100)
@@ -582,7 +689,7 @@ class Parser {
582
689
  const request = client[kQueue][client[kRunningIdx]]
583
690
  assert(request)
584
691
 
585
- this.statusCode = null
692
+ this.statusCode = 0
586
693
  this.statusText = ''
587
694
  this.bytesRead = 0
588
695
  this.contentLength = ''
@@ -593,7 +700,7 @@ class Parser {
593
700
  this.headersSize = 0
594
701
 
595
702
  if (statusCode < 200) {
596
- return
703
+ return 0
597
704
  }
598
705
 
599
706
  /* istanbul ignore next: should be handled by llhttp? */
@@ -629,6 +736,8 @@ class Parser {
629
736
  } else {
630
737
  client[kResume]()
631
738
  }
739
+
740
+ return 0
632
741
  }
633
742
  }
634
743
 
@@ -651,6 +760,11 @@ function onParserTimeout (parser) {
651
760
  }
652
761
  }
653
762
 
763
+ /**
764
+ * @param {import ('./client.js')} client
765
+ * @param {import('net').Socket} socket
766
+ * @returns
767
+ */
654
768
  async function connectH1 (client, socket) {
655
769
  client[kSocket] = socket
656
770
 
@@ -683,11 +797,7 @@ async function connectH1 (client, socket) {
683
797
  this[kClient][kOnError](err)
684
798
  })
685
799
  addListener(socket, 'readable', function () {
686
- const parser = this[kParser]
687
-
688
- if (parser) {
689
- parser.readMore()
690
- }
800
+ this[kParser]?.readMore()
691
801
  })
692
802
  addListener(socket, 'end', function () {
693
803
  const parser = this[kParser]
@@ -701,7 +811,6 @@ async function connectH1 (client, socket) {
701
811
  util.destroy(this, new SocketError('other side closed', util.getSocketInfo(this)))
702
812
  })
703
813
  addListener(socket, 'close', function () {
704
- const client = this[kClient]
705
814
  const parser = this[kParser]
706
815
 
707
816
  if (parser) {
@@ -716,6 +825,8 @@ async function connectH1 (client, socket) {
716
825
 
717
826
  const err = this[kError] || new SocketError('closed', util.getSocketInfo(this))
718
827
 
828
+ const client = this[kClient]
829
+
719
830
  client[kSocket] = null
720
831
  client[kHTTPContext] = null // TODO (fix): This is hacky...
721
832
 
@@ -753,22 +864,34 @@ async function connectH1 (client, socket) {
753
864
  return {
754
865
  version: 'h1',
755
866
  defaultPipelining: 1,
756
- write (...args) {
757
- return writeH1(client, ...args)
867
+ write (request) {
868
+ return writeH1(client, request)
758
869
  },
759
870
  resume () {
760
871
  resumeH1(client)
761
872
  },
873
+ /**
874
+ * @param {Error|undefined} err
875
+ * @param {() => void} callback
876
+ */
762
877
  destroy (err, callback) {
763
878
  if (closed) {
764
879
  queueMicrotask(callback)
765
880
  } else {
766
- socket.destroy(err).on('close', callback)
881
+ socket.on('close', callback)
882
+ socket.destroy(err)
767
883
  }
768
884
  },
885
+ /**
886
+ * @returns {boolean}
887
+ */
769
888
  get destroyed () {
770
889
  return socket.destroyed
771
890
  },
891
+ /**
892
+ * @param {import('../core/request.js')} request
893
+ * @returns {boolean}
894
+ */
772
895
  busy (request) {
773
896
  if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
774
897
  return true
@@ -808,6 +931,9 @@ async function connectH1 (client, socket) {
808
931
  }
809
932
  }
810
933
 
934
+ /**
935
+ * @param {import('./client.js')} client
936
+ */
811
937
  function resumeH1 (client) {
812
938
  const socket = client[kSocket]
813
939
 
@@ -843,6 +969,11 @@ function shouldSendContentLength (method) {
843
969
  return method !== 'GET' && method !== 'HEAD' && method !== 'OPTIONS' && method !== 'TRACE' && method !== 'CONNECT'
844
970
  }
845
971
 
972
+ /**
973
+ * @param {import('./client.js')} client
974
+ * @param {import('../core/request.js')} request
975
+ * @returns
976
+ */
846
977
  function writeH1 (client, request) {
847
978
  const { method, path, host, upgrade, blocking, reset } = request
848
979
 
@@ -913,6 +1044,10 @@ function writeH1 (client, request) {
913
1044
 
914
1045
  const socket = client[kSocket]
915
1046
 
1047
+ /**
1048
+ * @param {Error} [err]
1049
+ * @returns {void}
1050
+ */
916
1051
  const abort = (err) => {
917
1052
  if (request.aborted || request.completed) {
918
1053
  return
@@ -1018,6 +1153,16 @@ function writeH1 (client, request) {
1018
1153
  return true
1019
1154
  }
1020
1155
 
1156
+ /**
1157
+ * @param {AbortCallback} abort
1158
+ * @param {import('stream').Stream} body
1159
+ * @param {import('./client.js')} client
1160
+ * @param {import('../core/request.js')} request
1161
+ * @param {import('net').Socket} socket
1162
+ * @param {number} contentLength
1163
+ * @param {string} header
1164
+ * @param {boolean} expectsPayload
1165
+ */
1021
1166
  function writeStream (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1022
1167
  assert(contentLength !== 0 || client[kRunning] === 0, 'stream body cannot be pipelined')
1023
1168
 
@@ -1025,6 +1170,10 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
1025
1170
 
1026
1171
  const writer = new AsyncWriter({ abort, socket, request, contentLength, client, expectsPayload, header })
1027
1172
 
1173
+ /**
1174
+ * @param {Buffer} chunk
1175
+ * @returns {void}
1176
+ */
1028
1177
  const onData = function (chunk) {
1029
1178
  if (finished) {
1030
1179
  return
@@ -1038,6 +1187,10 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
1038
1187
  util.destroy(this, err)
1039
1188
  }
1040
1189
  }
1190
+
1191
+ /**
1192
+ * @returns {void}
1193
+ */
1041
1194
  const onDrain = function () {
1042
1195
  if (finished) {
1043
1196
  return
@@ -1047,6 +1200,10 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
1047
1200
  body.resume()
1048
1201
  }
1049
1202
  }
1203
+
1204
+ /**
1205
+ * @returns {void}
1206
+ */
1050
1207
  const onClose = function () {
1051
1208
  // 'close' might be emitted *before* 'error' for
1052
1209
  // broken streams. Wait a tick to avoid this case.
@@ -1061,6 +1218,11 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
1061
1218
  queueMicrotask(() => onFinished(err))
1062
1219
  }
1063
1220
  }
1221
+
1222
+ /**
1223
+ * @param {Error} [err]
1224
+ * @returns
1225
+ */
1064
1226
  const onFinished = function (err) {
1065
1227
  if (finished) {
1066
1228
  return
@@ -1121,6 +1283,24 @@ function writeStream (abort, body, client, request, socket, contentLength, heade
1121
1283
  }
1122
1284
  }
1123
1285
 
1286
+ /**
1287
+ * @typedef AbortCallback
1288
+ * @type {Function}
1289
+ * @param {Error} [err]
1290
+ * @returns {void}
1291
+ */
1292
+
1293
+ /**
1294
+ * @param {AbortCallback} abort
1295
+ * @param {Uint8Array|null} body
1296
+ * @param {import('./client.js')} client
1297
+ * @param {import('../core/request.js')} request
1298
+ * @param {import('net').Socket} socket
1299
+ * @param {number} contentLength
1300
+ * @param {string} header
1301
+ * @param {boolean} expectsPayload
1302
+ * @returns {void}
1303
+ */
1124
1304
  function writeBuffer (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1125
1305
  try {
1126
1306
  if (!body) {
@@ -1151,6 +1331,17 @@ function writeBuffer (abort, body, client, request, socket, contentLength, heade
1151
1331
  }
1152
1332
  }
1153
1333
 
1334
+ /**
1335
+ * @param {AbortCallback} abort
1336
+ * @param {Blob} body
1337
+ * @param {import('./client.js')} client
1338
+ * @param {import('../core/request.js')} request
1339
+ * @param {import('net').Socket} socket
1340
+ * @param {number} contentLength
1341
+ * @param {string} header
1342
+ * @param {boolean} expectsPayload
1343
+ * @returns {Promise<void>}
1344
+ */
1154
1345
  async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1155
1346
  assert(contentLength === body.size, 'blob body must have content length')
1156
1347
 
@@ -1179,6 +1370,17 @@ async function writeBlob (abort, body, client, request, socket, contentLength, h
1179
1370
  }
1180
1371
  }
1181
1372
 
1373
+ /**
1374
+ * @param {AbortCallback} abort
1375
+ * @param {Iterable} body
1376
+ * @param {import('./client.js')} client
1377
+ * @param {import('../core/request.js')} request
1378
+ * @param {import('net').Socket} socket
1379
+ * @param {number} contentLength
1380
+ * @param {string} header
1381
+ * @param {boolean} expectsPayload
1382
+ * @returns {Promise<void>}
1383
+ */
1182
1384
  async function writeIterable (abort, body, client, request, socket, contentLength, header, expectsPayload) {
1183
1385
  assert(contentLength !== 0 || client[kRunning] === 0, 'iterator body cannot be pipelined')
1184
1386
 
@@ -1229,6 +1431,17 @@ async function writeIterable (abort, body, client, request, socket, contentLengt
1229
1431
  }
1230
1432
 
1231
1433
  class AsyncWriter {
1434
+ /**
1435
+ *
1436
+ * @param {object} arg
1437
+ * @param {AbortCallback} arg.abort
1438
+ * @param {import('net').Socket} arg.socket
1439
+ * @param {import('../core/request.js')} arg.request
1440
+ * @param {number} arg.contentLength
1441
+ * @param {import('./client.js')} arg.client
1442
+ * @param {boolean} arg.expectsPayload
1443
+ * @param {string} arg.header
1444
+ */
1232
1445
  constructor ({ abort, socket, request, contentLength, client, expectsPayload, header }) {
1233
1446
  this.socket = socket
1234
1447
  this.request = request
@@ -1242,6 +1455,10 @@ class AsyncWriter {
1242
1455
  socket[kWriting] = true
1243
1456
  }
1244
1457
 
1458
+ /**
1459
+ * @param {Buffer} chunk
1460
+ * @returns
1461
+ */
1245
1462
  write (chunk) {
1246
1463
  const { socket, request, contentLength, client, bytesWritten, expectsPayload, header } = this
1247
1464
 
@@ -1305,6 +1522,9 @@ class AsyncWriter {
1305
1522
  return ret
1306
1523
  }
1307
1524
 
1525
+ /**
1526
+ * @returns {void}
1527
+ */
1308
1528
  end () {
1309
1529
  const { socket, contentLength, client, bytesWritten, expectsPayload, header, request } = this
1310
1530
  request.onRequestSent()
@@ -1352,6 +1572,10 @@ class AsyncWriter {
1352
1572
  client[kResume]()
1353
1573
  }
1354
1574
 
1575
+ /**
1576
+ * @param {Error} [err]
1577
+ * @returns {void}
1578
+ */
1355
1579
  destroy (err) {
1356
1580
  const { socket, client, abort } = this
1357
1581
 
@@ -281,7 +281,7 @@ function writeH2 (client, request) {
281
281
  }
282
282
 
283
283
  // We do not destroy the socket as we can continue using the session
284
- // the stream get's destroyed and the session remains to create new streams
284
+ // the stream gets destroyed and the session remains to create new streams
285
285
  util.destroy(body, err)
286
286
  }
287
287