@hono/node-server 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -125,6 +125,19 @@ serve({
125
125
  })
126
126
  ```
127
127
 
128
+ ### `autoCleanupIncoming`
129
+
130
+ The default value is `true`. The Node.js Adapter automatically cleans up (explicitly call `destroy()` method) if application is not finished to consume the incoming request. If you don't want to do that, set `false`.
131
+
132
+ If the application accepts connections from arbitrary clients, this cleanup must be done otherwise incomplete requests from clients may cause the application to stop responding. If your application only accepts connections from trusted clients, such as in a reverse proxy environment and there is no process that returns a response without reading the body of the POST request all the way through, you can improve performance by setting it to `false`.
133
+
134
+ ```ts
135
+ serve({
136
+ fetch: app.fetch,
137
+ autoCleanupIncoming: false,
138
+ })
139
+ ```
140
+
128
141
  ## Middleware
129
142
 
130
143
  Most built-in middleware also works with Node.js.
@@ -155,7 +168,7 @@ import { serveStatic } from '@hono/node-server/serve-static'
155
168
  app.use('/static/*', serveStatic({ root: './' }))
156
169
  ```
157
170
 
158
- Note that `root` must be _relative_ to the current working directory from which the app was started. Absolute paths are not supported.
171
+ If using a relative path, `root` will be relative to the current working directory from which the app was started.
159
172
 
160
173
  This can cause confusion when running your application locally.
161
174
 
package/dist/index.js CHANGED
@@ -40,6 +40,9 @@ module.exports = __toCommonJS(src_exports);
40
40
  // src/server.ts
41
41
  var import_node_http = require("http");
42
42
 
43
+ // src/listener.ts
44
+ var import_node_http22 = require("http2");
45
+
43
46
  // src/request.ts
44
47
  var import_node_http2 = require("http2");
45
48
  var import_node_stream = require("stream");
@@ -68,6 +71,7 @@ var Request = class extends GlobalRequest {
68
71
  super(input, options);
69
72
  }
70
73
  };
74
+ var wrapBodyStream = Symbol("wrapBodyStream");
71
75
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
72
76
  const headerRecord = [];
73
77
  const rawHeaders = incoming.rawHeaders;
@@ -101,6 +105,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
101
105
  controller.close();
102
106
  }
103
107
  });
108
+ } else if (incoming[wrapBodyStream]) {
109
+ let reader;
110
+ init.body = new ReadableStream({
111
+ async pull(controller) {
112
+ try {
113
+ reader ||= import_node_stream.Readable.toWeb(incoming).getReader();
114
+ const { done, value } = await reader.read();
115
+ if (done) {
116
+ controller.close();
117
+ } else {
118
+ controller.enqueue(value);
119
+ }
120
+ } catch (error) {
121
+ controller.error(error);
122
+ }
123
+ }
124
+ });
104
125
  } else {
105
126
  init.body = import_node_stream.Readable.toWeb(incoming);
106
127
  }
@@ -349,6 +370,7 @@ global.fetch = (info, init) => {
349
370
  };
350
371
 
351
372
  // src/listener.ts
373
+ var outgoingEnded = Symbol("outgoingEnded");
352
374
  var regBuffer = /^no$/i;
353
375
  var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
354
376
  var handleRequestError = () => new Response(null, {
@@ -394,10 +416,12 @@ var responseViaCache = async (res, outgoing) => {
394
416
  outgoing.end(new Uint8Array(await body.arrayBuffer()));
395
417
  } else {
396
418
  flushHeaders(outgoing);
397
- return writeFromReadableStream(body, outgoing)?.catch(
419
+ await writeFromReadableStream(body, outgoing)?.catch(
398
420
  (e) => handleResponseError(e, outgoing)
399
421
  );
400
422
  }
423
+ ;
424
+ outgoing[outgoingEnded]?.();
401
425
  };
402
426
  var responseViaResponseObject = async (res, outgoing, options = {}) => {
403
427
  if (res instanceof Promise) {
@@ -443,8 +467,11 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
443
467
  outgoing.writeHead(res.status, resHeaderRecord);
444
468
  outgoing.end();
445
469
  }
470
+ ;
471
+ outgoing[outgoingEnded]?.();
446
472
  };
447
473
  var getRequestListener = (fetchCallback, options = {}) => {
474
+ const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
448
475
  if (options.overrideGlobalObjects !== false && global.Request !== Request) {
449
476
  Object.defineProperty(global, "Request", {
450
477
  value: Request
@@ -457,15 +484,46 @@ var getRequestListener = (fetchCallback, options = {}) => {
457
484
  let res, req;
458
485
  try {
459
486
  req = newRequest(incoming, options.hostname);
487
+ let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
488
+ if (!incomingEnded) {
489
+ ;
490
+ incoming[wrapBodyStream] = true;
491
+ incoming.on("end", () => {
492
+ incomingEnded = true;
493
+ });
494
+ if (incoming instanceof import_node_http22.Http2ServerRequest) {
495
+ ;
496
+ outgoing[outgoingEnded] = () => {
497
+ if (!incomingEnded) {
498
+ setTimeout(() => {
499
+ if (!incomingEnded) {
500
+ setTimeout(() => {
501
+ incoming.destroy();
502
+ outgoing.destroy();
503
+ });
504
+ }
505
+ });
506
+ }
507
+ };
508
+ }
509
+ }
460
510
  outgoing.on("close", () => {
461
511
  const abortController = req[abortControllerKey];
462
- if (!abortController) {
463
- return;
512
+ if (abortController) {
513
+ if (incoming.errored) {
514
+ req[abortControllerKey].abort(incoming.errored.toString());
515
+ } else if (!outgoing.writableFinished) {
516
+ req[abortControllerKey].abort("Client connection prematurely closed.");
517
+ }
464
518
  }
465
- if (incoming.errored) {
466
- req[abortControllerKey].abort(incoming.errored.toString());
467
- } else if (!outgoing.writableFinished) {
468
- req[abortControllerKey].abort("Client connection prematurely closed.");
519
+ if (!incomingEnded) {
520
+ setTimeout(() => {
521
+ if (!incomingEnded) {
522
+ setTimeout(() => {
523
+ incoming.destroy();
524
+ });
525
+ }
526
+ });
469
527
  }
470
528
  });
471
529
  res = fetchCallback(req, { incoming, outgoing });
@@ -501,7 +559,8 @@ var createAdaptorServer = (options) => {
501
559
  const fetchCallback = options.fetch;
502
560
  const requestListener = getRequestListener(fetchCallback, {
503
561
  hostname: options.hostname,
504
- overrideGlobalObjects: options.overrideGlobalObjects
562
+ overrideGlobalObjects: options.overrideGlobalObjects,
563
+ autoCleanupIncoming: options.autoCleanupIncoming
505
564
  });
506
565
  const createServer = options.createServer || import_node_http.createServer;
507
566
  const server = createServer(options.serverOptions || {}, requestListener);
package/dist/index.mjs CHANGED
@@ -1,6 +1,9 @@
1
1
  // src/server.ts
2
2
  import { createServer as createServerHTTP } from "http";
3
3
 
4
+ // src/listener.ts
5
+ import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
6
+
4
7
  // src/request.ts
5
8
  import { Http2ServerRequest } from "http2";
6
9
  import { Readable } from "stream";
@@ -29,6 +32,7 @@ var Request = class extends GlobalRequest {
29
32
  super(input, options);
30
33
  }
31
34
  };
35
+ var wrapBodyStream = Symbol("wrapBodyStream");
32
36
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
33
37
  const headerRecord = [];
34
38
  const rawHeaders = incoming.rawHeaders;
@@ -62,6 +66,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
62
66
  controller.close();
63
67
  }
64
68
  });
69
+ } else if (incoming[wrapBodyStream]) {
70
+ let reader;
71
+ init.body = new ReadableStream({
72
+ async pull(controller) {
73
+ try {
74
+ reader ||= Readable.toWeb(incoming).getReader();
75
+ const { done, value } = await reader.read();
76
+ if (done) {
77
+ controller.close();
78
+ } else {
79
+ controller.enqueue(value);
80
+ }
81
+ } catch (error) {
82
+ controller.error(error);
83
+ }
84
+ }
85
+ });
65
86
  } else {
66
87
  init.body = Readable.toWeb(incoming);
67
88
  }
@@ -310,6 +331,7 @@ global.fetch = (info, init) => {
310
331
  };
311
332
 
312
333
  // src/listener.ts
334
+ var outgoingEnded = Symbol("outgoingEnded");
313
335
  var regBuffer = /^no$/i;
314
336
  var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
315
337
  var handleRequestError = () => new Response(null, {
@@ -355,10 +377,12 @@ var responseViaCache = async (res, outgoing) => {
355
377
  outgoing.end(new Uint8Array(await body.arrayBuffer()));
356
378
  } else {
357
379
  flushHeaders(outgoing);
358
- return writeFromReadableStream(body, outgoing)?.catch(
380
+ await writeFromReadableStream(body, outgoing)?.catch(
359
381
  (e) => handleResponseError(e, outgoing)
360
382
  );
361
383
  }
384
+ ;
385
+ outgoing[outgoingEnded]?.();
362
386
  };
363
387
  var responseViaResponseObject = async (res, outgoing, options = {}) => {
364
388
  if (res instanceof Promise) {
@@ -404,8 +428,11 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
404
428
  outgoing.writeHead(res.status, resHeaderRecord);
405
429
  outgoing.end();
406
430
  }
431
+ ;
432
+ outgoing[outgoingEnded]?.();
407
433
  };
408
434
  var getRequestListener = (fetchCallback, options = {}) => {
435
+ const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
409
436
  if (options.overrideGlobalObjects !== false && global.Request !== Request) {
410
437
  Object.defineProperty(global, "Request", {
411
438
  value: Request
@@ -418,15 +445,46 @@ var getRequestListener = (fetchCallback, options = {}) => {
418
445
  let res, req;
419
446
  try {
420
447
  req = newRequest(incoming, options.hostname);
448
+ let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
449
+ if (!incomingEnded) {
450
+ ;
451
+ incoming[wrapBodyStream] = true;
452
+ incoming.on("end", () => {
453
+ incomingEnded = true;
454
+ });
455
+ if (incoming instanceof Http2ServerRequest2) {
456
+ ;
457
+ outgoing[outgoingEnded] = () => {
458
+ if (!incomingEnded) {
459
+ setTimeout(() => {
460
+ if (!incomingEnded) {
461
+ setTimeout(() => {
462
+ incoming.destroy();
463
+ outgoing.destroy();
464
+ });
465
+ }
466
+ });
467
+ }
468
+ };
469
+ }
470
+ }
421
471
  outgoing.on("close", () => {
422
472
  const abortController = req[abortControllerKey];
423
- if (!abortController) {
424
- return;
473
+ if (abortController) {
474
+ if (incoming.errored) {
475
+ req[abortControllerKey].abort(incoming.errored.toString());
476
+ } else if (!outgoing.writableFinished) {
477
+ req[abortControllerKey].abort("Client connection prematurely closed.");
478
+ }
425
479
  }
426
- if (incoming.errored) {
427
- req[abortControllerKey].abort(incoming.errored.toString());
428
- } else if (!outgoing.writableFinished) {
429
- req[abortControllerKey].abort("Client connection prematurely closed.");
480
+ if (!incomingEnded) {
481
+ setTimeout(() => {
482
+ if (!incomingEnded) {
483
+ setTimeout(() => {
484
+ incoming.destroy();
485
+ });
486
+ }
487
+ });
430
488
  }
431
489
  });
432
490
  res = fetchCallback(req, { incoming, outgoing });
@@ -462,7 +520,8 @@ var createAdaptorServer = (options) => {
462
520
  const fetchCallback = options.fetch;
463
521
  const requestListener = getRequestListener(fetchCallback, {
464
522
  hostname: options.hostname,
465
- overrideGlobalObjects: options.overrideGlobalObjects
523
+ overrideGlobalObjects: options.overrideGlobalObjects,
524
+ autoCleanupIncoming: options.autoCleanupIncoming
466
525
  });
467
526
  const createServer = options.createServer || createServerHTTP;
468
527
  const server = createServer(options.serverOptions || {}, requestListener);
@@ -7,6 +7,7 @@ declare const getRequestListener: (fetchCallback: FetchCallback, options?: {
7
7
  hostname?: string;
8
8
  errorHandler?: CustomErrorHandler;
9
9
  overrideGlobalObjects?: boolean;
10
+ autoCleanupIncoming?: boolean;
10
11
  }) => (incoming: IncomingMessage | Http2ServerRequest, outgoing: ServerResponse | Http2ServerResponse) => Promise<void>;
11
12
 
12
13
  export { getRequestListener };
@@ -7,6 +7,7 @@ declare const getRequestListener: (fetchCallback: FetchCallback, options?: {
7
7
  hostname?: string;
8
8
  errorHandler?: CustomErrorHandler;
9
9
  overrideGlobalObjects?: boolean;
10
+ autoCleanupIncoming?: boolean;
10
11
  }) => (incoming: IncomingMessage | Http2ServerRequest, outgoing: ServerResponse | Http2ServerResponse) => Promise<void>;
11
12
 
12
13
  export { getRequestListener };
package/dist/listener.js CHANGED
@@ -33,6 +33,7 @@ __export(listener_exports, {
33
33
  getRequestListener: () => getRequestListener
34
34
  });
35
35
  module.exports = __toCommonJS(listener_exports);
36
+ var import_node_http22 = require("http2");
36
37
 
37
38
  // src/request.ts
38
39
  var import_node_http2 = require("http2");
@@ -62,6 +63,7 @@ var Request = class extends GlobalRequest {
62
63
  super(input, options);
63
64
  }
64
65
  };
66
+ var wrapBodyStream = Symbol("wrapBodyStream");
65
67
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
66
68
  const headerRecord = [];
67
69
  const rawHeaders = incoming.rawHeaders;
@@ -95,6 +97,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
95
97
  controller.close();
96
98
  }
97
99
  });
100
+ } else if (incoming[wrapBodyStream]) {
101
+ let reader;
102
+ init.body = new ReadableStream({
103
+ async pull(controller) {
104
+ try {
105
+ reader ||= import_node_stream.Readable.toWeb(incoming).getReader();
106
+ const { done, value } = await reader.read();
107
+ if (done) {
108
+ controller.close();
109
+ } else {
110
+ controller.enqueue(value);
111
+ }
112
+ } catch (error) {
113
+ controller.error(error);
114
+ }
115
+ }
116
+ });
98
117
  } else {
99
118
  init.body = import_node_stream.Readable.toWeb(incoming);
100
119
  }
@@ -343,6 +362,7 @@ global.fetch = (info, init) => {
343
362
  };
344
363
 
345
364
  // src/listener.ts
365
+ var outgoingEnded = Symbol("outgoingEnded");
346
366
  var regBuffer = /^no$/i;
347
367
  var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
348
368
  var handleRequestError = () => new Response(null, {
@@ -388,10 +408,12 @@ var responseViaCache = async (res, outgoing) => {
388
408
  outgoing.end(new Uint8Array(await body.arrayBuffer()));
389
409
  } else {
390
410
  flushHeaders(outgoing);
391
- return writeFromReadableStream(body, outgoing)?.catch(
411
+ await writeFromReadableStream(body, outgoing)?.catch(
392
412
  (e) => handleResponseError(e, outgoing)
393
413
  );
394
414
  }
415
+ ;
416
+ outgoing[outgoingEnded]?.();
395
417
  };
396
418
  var responseViaResponseObject = async (res, outgoing, options = {}) => {
397
419
  if (res instanceof Promise) {
@@ -437,8 +459,11 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
437
459
  outgoing.writeHead(res.status, resHeaderRecord);
438
460
  outgoing.end();
439
461
  }
462
+ ;
463
+ outgoing[outgoingEnded]?.();
440
464
  };
441
465
  var getRequestListener = (fetchCallback, options = {}) => {
466
+ const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
442
467
  if (options.overrideGlobalObjects !== false && global.Request !== Request) {
443
468
  Object.defineProperty(global, "Request", {
444
469
  value: Request
@@ -451,15 +476,46 @@ var getRequestListener = (fetchCallback, options = {}) => {
451
476
  let res, req;
452
477
  try {
453
478
  req = newRequest(incoming, options.hostname);
479
+ let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
480
+ if (!incomingEnded) {
481
+ ;
482
+ incoming[wrapBodyStream] = true;
483
+ incoming.on("end", () => {
484
+ incomingEnded = true;
485
+ });
486
+ if (incoming instanceof import_node_http22.Http2ServerRequest) {
487
+ ;
488
+ outgoing[outgoingEnded] = () => {
489
+ if (!incomingEnded) {
490
+ setTimeout(() => {
491
+ if (!incomingEnded) {
492
+ setTimeout(() => {
493
+ incoming.destroy();
494
+ outgoing.destroy();
495
+ });
496
+ }
497
+ });
498
+ }
499
+ };
500
+ }
501
+ }
454
502
  outgoing.on("close", () => {
455
503
  const abortController = req[abortControllerKey];
456
- if (!abortController) {
457
- return;
504
+ if (abortController) {
505
+ if (incoming.errored) {
506
+ req[abortControllerKey].abort(incoming.errored.toString());
507
+ } else if (!outgoing.writableFinished) {
508
+ req[abortControllerKey].abort("Client connection prematurely closed.");
509
+ }
458
510
  }
459
- if (incoming.errored) {
460
- req[abortControllerKey].abort(incoming.errored.toString());
461
- } else if (!outgoing.writableFinished) {
462
- req[abortControllerKey].abort("Client connection prematurely closed.");
511
+ if (!incomingEnded) {
512
+ setTimeout(() => {
513
+ if (!incomingEnded) {
514
+ setTimeout(() => {
515
+ incoming.destroy();
516
+ });
517
+ }
518
+ });
463
519
  }
464
520
  });
465
521
  res = fetchCallback(req, { incoming, outgoing });
package/dist/listener.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ // src/listener.ts
2
+ import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
3
+
1
4
  // src/request.ts
2
5
  import { Http2ServerRequest } from "http2";
3
6
  import { Readable } from "stream";
@@ -26,6 +29,7 @@ var Request = class extends GlobalRequest {
26
29
  super(input, options);
27
30
  }
28
31
  };
32
+ var wrapBodyStream = Symbol("wrapBodyStream");
29
33
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
30
34
  const headerRecord = [];
31
35
  const rawHeaders = incoming.rawHeaders;
@@ -59,6 +63,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
59
63
  controller.close();
60
64
  }
61
65
  });
66
+ } else if (incoming[wrapBodyStream]) {
67
+ let reader;
68
+ init.body = new ReadableStream({
69
+ async pull(controller) {
70
+ try {
71
+ reader ||= Readable.toWeb(incoming).getReader();
72
+ const { done, value } = await reader.read();
73
+ if (done) {
74
+ controller.close();
75
+ } else {
76
+ controller.enqueue(value);
77
+ }
78
+ } catch (error) {
79
+ controller.error(error);
80
+ }
81
+ }
82
+ });
62
83
  } else {
63
84
  init.body = Readable.toWeb(incoming);
64
85
  }
@@ -307,6 +328,7 @@ global.fetch = (info, init) => {
307
328
  };
308
329
 
309
330
  // src/listener.ts
331
+ var outgoingEnded = Symbol("outgoingEnded");
310
332
  var regBuffer = /^no$/i;
311
333
  var regContentType = /^(application\/json\b|text\/(?!event-stream\b))/i;
312
334
  var handleRequestError = () => new Response(null, {
@@ -352,10 +374,12 @@ var responseViaCache = async (res, outgoing) => {
352
374
  outgoing.end(new Uint8Array(await body.arrayBuffer()));
353
375
  } else {
354
376
  flushHeaders(outgoing);
355
- return writeFromReadableStream(body, outgoing)?.catch(
377
+ await writeFromReadableStream(body, outgoing)?.catch(
356
378
  (e) => handleResponseError(e, outgoing)
357
379
  );
358
380
  }
381
+ ;
382
+ outgoing[outgoingEnded]?.();
359
383
  };
360
384
  var responseViaResponseObject = async (res, outgoing, options = {}) => {
361
385
  if (res instanceof Promise) {
@@ -401,8 +425,11 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
401
425
  outgoing.writeHead(res.status, resHeaderRecord);
402
426
  outgoing.end();
403
427
  }
428
+ ;
429
+ outgoing[outgoingEnded]?.();
404
430
  };
405
431
  var getRequestListener = (fetchCallback, options = {}) => {
432
+ const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
406
433
  if (options.overrideGlobalObjects !== false && global.Request !== Request) {
407
434
  Object.defineProperty(global, "Request", {
408
435
  value: Request
@@ -415,15 +442,46 @@ var getRequestListener = (fetchCallback, options = {}) => {
415
442
  let res, req;
416
443
  try {
417
444
  req = newRequest(incoming, options.hostname);
445
+ let incomingEnded = !autoCleanupIncoming || incoming.method === "GET" || incoming.method === "HEAD";
446
+ if (!incomingEnded) {
447
+ ;
448
+ incoming[wrapBodyStream] = true;
449
+ incoming.on("end", () => {
450
+ incomingEnded = true;
451
+ });
452
+ if (incoming instanceof Http2ServerRequest2) {
453
+ ;
454
+ outgoing[outgoingEnded] = () => {
455
+ if (!incomingEnded) {
456
+ setTimeout(() => {
457
+ if (!incomingEnded) {
458
+ setTimeout(() => {
459
+ incoming.destroy();
460
+ outgoing.destroy();
461
+ });
462
+ }
463
+ });
464
+ }
465
+ };
466
+ }
467
+ }
418
468
  outgoing.on("close", () => {
419
469
  const abortController = req[abortControllerKey];
420
- if (!abortController) {
421
- return;
470
+ if (abortController) {
471
+ if (incoming.errored) {
472
+ req[abortControllerKey].abort(incoming.errored.toString());
473
+ } else if (!outgoing.writableFinished) {
474
+ req[abortControllerKey].abort("Client connection prematurely closed.");
475
+ }
422
476
  }
423
- if (incoming.errored) {
424
- req[abortControllerKey].abort(incoming.errored.toString());
425
- } else if (!outgoing.writableFinished) {
426
- req[abortControllerKey].abort("Client connection prematurely closed.");
477
+ if (!incomingEnded) {
478
+ setTimeout(() => {
479
+ if (!incomingEnded) {
480
+ setTimeout(() => {
481
+ incoming.destroy();
482
+ });
483
+ }
484
+ });
427
485
  }
428
486
  });
429
487
  res = fetchCallback(req, { incoming, outgoing });
@@ -14,8 +14,12 @@ declare const GlobalRequest: {
14
14
  declare class Request extends GlobalRequest {
15
15
  constructor(input: string | Request, options?: RequestInit);
16
16
  }
17
+ type IncomingMessageWithWrapBodyStream = IncomingMessage & {
18
+ [wrapBodyStream]: boolean;
19
+ };
20
+ declare const wrapBodyStream: unique symbol;
17
21
  declare const abortControllerKey: unique symbol;
18
22
  declare const getAbortController: unique symbol;
19
23
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
20
24
 
21
- export { GlobalRequest, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError };
25
+ export { GlobalRequest, type IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
package/dist/request.d.ts CHANGED
@@ -14,8 +14,12 @@ declare const GlobalRequest: {
14
14
  declare class Request extends GlobalRequest {
15
15
  constructor(input: string | Request, options?: RequestInit);
16
16
  }
17
+ type IncomingMessageWithWrapBodyStream = IncomingMessage & {
18
+ [wrapBodyStream]: boolean;
19
+ };
20
+ declare const wrapBodyStream: unique symbol;
17
21
  declare const abortControllerKey: unique symbol;
18
22
  declare const getAbortController: unique symbol;
19
23
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
20
24
 
21
- export { GlobalRequest, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError };
25
+ export { GlobalRequest, type IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
package/dist/request.js CHANGED
@@ -26,7 +26,8 @@ __export(request_exports, {
26
26
  abortControllerKey: () => abortControllerKey,
27
27
  getAbortController: () => getAbortController,
28
28
  newRequest: () => newRequest,
29
- toRequestError: () => toRequestError
29
+ toRequestError: () => toRequestError,
30
+ wrapBodyStream: () => wrapBodyStream
30
31
  });
31
32
  module.exports = __toCommonJS(request_exports);
32
33
  var import_node_http2 = require("http2");
@@ -56,6 +57,7 @@ var Request = class extends GlobalRequest {
56
57
  super(input, options);
57
58
  }
58
59
  };
60
+ var wrapBodyStream = Symbol("wrapBodyStream");
59
61
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
60
62
  const headerRecord = [];
61
63
  const rawHeaders = incoming.rawHeaders;
@@ -89,6 +91,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
89
91
  controller.close();
90
92
  }
91
93
  });
94
+ } else if (incoming[wrapBodyStream]) {
95
+ let reader;
96
+ init.body = new ReadableStream({
97
+ async pull(controller) {
98
+ try {
99
+ reader ||= import_node_stream.Readable.toWeb(incoming).getReader();
100
+ const { done, value } = await reader.read();
101
+ if (done) {
102
+ controller.close();
103
+ } else {
104
+ controller.enqueue(value);
105
+ }
106
+ } catch (error) {
107
+ controller.error(error);
108
+ }
109
+ }
110
+ });
92
111
  } else {
93
112
  init.body = import_node_stream.Readable.toWeb(incoming);
94
113
  }
@@ -196,5 +215,6 @@ var newRequest = (incoming, defaultHostname) => {
196
215
  abortControllerKey,
197
216
  getAbortController,
198
217
  newRequest,
199
- toRequestError
218
+ toRequestError,
219
+ wrapBodyStream
200
220
  });
package/dist/request.mjs CHANGED
@@ -26,6 +26,7 @@ var Request = class extends GlobalRequest {
26
26
  super(input, options);
27
27
  }
28
28
  };
29
+ var wrapBodyStream = Symbol("wrapBodyStream");
29
30
  var newRequestFromIncoming = (method, url, incoming, abortController) => {
30
31
  const headerRecord = [];
31
32
  const rawHeaders = incoming.rawHeaders;
@@ -59,6 +60,23 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
59
60
  controller.close();
60
61
  }
61
62
  });
63
+ } else if (incoming[wrapBodyStream]) {
64
+ let reader;
65
+ init.body = new ReadableStream({
66
+ async pull(controller) {
67
+ try {
68
+ reader ||= Readable.toWeb(incoming).getReader();
69
+ const { done, value } = await reader.read();
70
+ if (done) {
71
+ controller.close();
72
+ } else {
73
+ controller.enqueue(value);
74
+ }
75
+ } catch (error) {
76
+ controller.error(error);
77
+ }
78
+ }
79
+ });
62
80
  } else {
63
81
  init.body = Readable.toWeb(incoming);
64
82
  }
@@ -165,5 +183,6 @@ export {
165
183
  abortControllerKey,
166
184
  getAbortController,
167
185
  newRequest,
168
- toRequestError
186
+ toRequestError,
187
+ wrapBodyStream
169
188
  };