@hono/node-server 1.19.10 → 1.19.14

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/dist/listener.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/listener.ts
2
- import { Http2ServerRequest as Http2ServerRequest2 } from "http2";
2
+ import { Http2ServerRequest as Http2ServerRequest2, constants as h2constants } from "http2";
3
3
 
4
4
  // src/request.ts
5
5
  import { Http2ServerRequest } from "http2";
@@ -148,6 +148,17 @@ var requestPrototype = {
148
148
  }
149
149
  });
150
150
  });
151
+ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), {
152
+ value: function(depth, options, inspectFn) {
153
+ const props = {
154
+ method: this.method,
155
+ url: this.url,
156
+ headers: this.headers,
157
+ nativeRequest: this[requestCache]
158
+ };
159
+ return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
160
+ }
161
+ });
151
162
  Object.setPrototypeOf(requestPrototype, Request.prototype);
152
163
  var newRequest = (incoming, defaultHostname) => {
153
164
  const req = Object.create(requestPrototype);
@@ -216,15 +227,17 @@ var Response2 = class _Response {
216
227
  this.#init = init;
217
228
  }
218
229
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
219
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
220
- this[cacheKey] = [init?.status || 200, body, headers];
230
+ ;
231
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
221
232
  }
222
233
  }
223
234
  get headers() {
224
235
  const cache = this[cacheKey];
225
236
  if (cache) {
226
237
  if (!(cache[2] instanceof Headers)) {
227
- cache[2] = new Headers(cache[2]);
238
+ cache[2] = new Headers(
239
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
240
+ );
228
241
  }
229
242
  return cache[2];
230
243
  }
@@ -252,6 +265,17 @@ var Response2 = class _Response {
252
265
  }
253
266
  });
254
267
  });
268
+ Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custom"), {
269
+ value: function(depth, options, inspectFn) {
270
+ const props = {
271
+ status: this.status,
272
+ headers: this.headers,
273
+ ok: this.ok,
274
+ nativeResponse: this[responseCache]
275
+ };
276
+ return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
277
+ }
278
+ });
255
279
  Object.setPrototypeOf(Response2, GlobalResponse);
256
280
  Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
257
281
 
@@ -332,6 +356,50 @@ if (typeof global.crypto === "undefined") {
332
356
 
333
357
  // src/listener.ts
334
358
  var outgoingEnded = Symbol("outgoingEnded");
359
+ var incomingDraining = Symbol("incomingDraining");
360
+ var DRAIN_TIMEOUT_MS = 500;
361
+ var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
362
+ var drainIncoming = (incoming) => {
363
+ const incomingWithDrainState = incoming;
364
+ if (incoming.destroyed || incomingWithDrainState[incomingDraining]) {
365
+ return;
366
+ }
367
+ incomingWithDrainState[incomingDraining] = true;
368
+ if (incoming instanceof Http2ServerRequest2) {
369
+ try {
370
+ ;
371
+ incoming.stream?.close?.(h2constants.NGHTTP2_NO_ERROR);
372
+ } catch {
373
+ }
374
+ return;
375
+ }
376
+ let bytesRead = 0;
377
+ const cleanup = () => {
378
+ clearTimeout(timer);
379
+ incoming.off("data", onData);
380
+ incoming.off("end", cleanup);
381
+ incoming.off("error", cleanup);
382
+ };
383
+ const forceClose = () => {
384
+ cleanup();
385
+ const socket = incoming.socket;
386
+ if (socket && !socket.destroyed) {
387
+ socket.destroySoon();
388
+ }
389
+ };
390
+ const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
391
+ timer.unref?.();
392
+ const onData = (chunk) => {
393
+ bytesRead += chunk.length;
394
+ if (bytesRead > MAX_DRAIN_BYTES) {
395
+ forceClose();
396
+ }
397
+ };
398
+ incoming.on("data", onData);
399
+ incoming.on("end", cleanup);
400
+ incoming.on("error", cleanup);
401
+ incoming.resume();
402
+ };
335
403
  var handleRequestError = () => new Response(null, {
336
404
  status: 400
337
405
  });
@@ -358,15 +426,32 @@ var flushHeaders = (outgoing) => {
358
426
  };
359
427
  var responseViaCache = async (res, outgoing) => {
360
428
  let [status, body, header] = res[cacheKey];
361
- if (header instanceof Headers) {
429
+ let hasContentLength = false;
430
+ if (!header) {
431
+ header = { "content-type": "text/plain; charset=UTF-8" };
432
+ } else if (header instanceof Headers) {
433
+ hasContentLength = header.has("content-length");
362
434
  header = buildOutgoingHttpHeaders(header);
435
+ } else if (Array.isArray(header)) {
436
+ const headerObj = new Headers(header);
437
+ hasContentLength = headerObj.has("content-length");
438
+ header = buildOutgoingHttpHeaders(headerObj);
439
+ } else {
440
+ for (const key in header) {
441
+ if (key.length === 14 && key.toLowerCase() === "content-length") {
442
+ hasContentLength = true;
443
+ break;
444
+ }
445
+ }
363
446
  }
364
- if (typeof body === "string") {
365
- header["Content-Length"] = Buffer.byteLength(body);
366
- } else if (body instanceof Uint8Array) {
367
- header["Content-Length"] = body.byteLength;
368
- } else if (body instanceof Blob) {
369
- header["Content-Length"] = body.size;
447
+ if (!hasContentLength) {
448
+ if (typeof body === "string") {
449
+ header["Content-Length"] = Buffer.byteLength(body);
450
+ } else if (body instanceof Uint8Array) {
451
+ header["Content-Length"] = body.byteLength;
452
+ } else if (body instanceof Blob) {
453
+ header["Content-Length"] = body.size;
454
+ }
370
455
  }
371
456
  outgoing.writeHead(status, header);
372
457
  if (typeof body === "string" || body instanceof Uint8Array) {
@@ -486,14 +571,18 @@ var getRequestListener = (fetchCallback, options = {}) => {
486
571
  setTimeout(() => {
487
572
  if (!incomingEnded) {
488
573
  setTimeout(() => {
489
- incoming.destroy();
490
- outgoing.destroy();
574
+ drainIncoming(incoming);
491
575
  });
492
576
  }
493
577
  });
494
578
  }
495
579
  };
496
580
  }
581
+ outgoing.on("finish", () => {
582
+ if (!incomingEnded) {
583
+ drainIncoming(incoming);
584
+ }
585
+ });
497
586
  }
498
587
  outgoing.on("close", () => {
499
588
  const abortController = req[abortControllerKey];
@@ -508,7 +597,7 @@ var getRequestListener = (fetchCallback, options = {}) => {
508
597
  setTimeout(() => {
509
598
  if (!incomingEnded) {
510
599
  setTimeout(() => {
511
- incoming.destroy();
600
+ drainIncoming(incoming);
512
601
  });
513
602
  }
514
603
  });
package/dist/request.js CHANGED
@@ -176,6 +176,17 @@ var requestPrototype = {
176
176
  }
177
177
  });
178
178
  });
179
+ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), {
180
+ value: function(depth, options, inspectFn) {
181
+ const props = {
182
+ method: this.method,
183
+ url: this.url,
184
+ headers: this.headers,
185
+ nativeRequest: this[requestCache]
186
+ };
187
+ return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
188
+ }
189
+ });
179
190
  Object.setPrototypeOf(requestPrototype, Request.prototype);
180
191
  var newRequest = (incoming, defaultHostname) => {
181
192
  const req = Object.create(requestPrototype);
package/dist/request.mjs CHANGED
@@ -145,6 +145,17 @@ var requestPrototype = {
145
145
  }
146
146
  });
147
147
  });
148
+ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), {
149
+ value: function(depth, options, inspectFn) {
150
+ const props = {
151
+ method: this.method,
152
+ url: this.url,
153
+ headers: this.headers,
154
+ nativeRequest: this[requestCache]
155
+ };
156
+ return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
157
+ }
158
+ });
148
159
  Object.setPrototypeOf(requestPrototype, Request.prototype);
149
160
  var newRequest = (incoming, defaultHostname) => {
150
161
  const req = Object.create(requestPrototype);
@@ -5,7 +5,7 @@ declare const cacheKey: unique symbol;
5
5
  type InternalCache = [
6
6
  number,
7
7
  string | ReadableStream,
8
- Record<string, string> | Headers | OutgoingHttpHeaders
8
+ Record<string, string> | [string, string][] | Headers | OutgoingHttpHeaders | undefined
9
9
  ];
10
10
  declare const GlobalResponse: {
11
11
  new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response;
@@ -5,7 +5,7 @@ declare const cacheKey: unique symbol;
5
5
  type InternalCache = [
6
6
  number,
7
7
  string | ReadableStream,
8
- Record<string, string> | Headers | OutgoingHttpHeaders
8
+ Record<string, string> | [string, string][] | Headers | OutgoingHttpHeaders | undefined
9
9
  ];
10
10
  declare const GlobalResponse: {
11
11
  new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response;
package/dist/response.js CHANGED
@@ -53,15 +53,17 @@ var Response = class _Response {
53
53
  this.#init = init;
54
54
  }
55
55
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
56
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
57
- this[cacheKey] = [init?.status || 200, body, headers];
56
+ ;
57
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
58
58
  }
59
59
  }
60
60
  get headers() {
61
61
  const cache = this[cacheKey];
62
62
  if (cache) {
63
63
  if (!(cache[2] instanceof Headers)) {
64
- cache[2] = new Headers(cache[2]);
64
+ cache[2] = new Headers(
65
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
66
+ );
65
67
  }
66
68
  return cache[2];
67
69
  }
@@ -89,6 +91,17 @@ var Response = class _Response {
89
91
  }
90
92
  });
91
93
  });
94
+ Object.defineProperty(Response.prototype, Symbol.for("nodejs.util.inspect.custom"), {
95
+ value: function(depth, options, inspectFn) {
96
+ const props = {
97
+ status: this.status,
98
+ headers: this.headers,
99
+ ok: this.ok,
100
+ nativeResponse: this[responseCache]
101
+ };
102
+ return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
103
+ }
104
+ });
92
105
  Object.setPrototypeOf(Response, GlobalResponse);
93
106
  Object.setPrototypeOf(Response.prototype, GlobalResponse.prototype);
94
107
  // Annotate the CommonJS export names for ESM import in node:
package/dist/response.mjs CHANGED
@@ -27,15 +27,17 @@ var Response = class _Response {
27
27
  this.#init = init;
28
28
  }
29
29
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
30
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
31
- this[cacheKey] = [init?.status || 200, body, headers];
30
+ ;
31
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
32
32
  }
33
33
  }
34
34
  get headers() {
35
35
  const cache = this[cacheKey];
36
36
  if (cache) {
37
37
  if (!(cache[2] instanceof Headers)) {
38
- cache[2] = new Headers(cache[2]);
38
+ cache[2] = new Headers(
39
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
40
+ );
39
41
  }
40
42
  return cache[2];
41
43
  }
@@ -63,6 +65,17 @@ var Response = class _Response {
63
65
  }
64
66
  });
65
67
  });
68
+ Object.defineProperty(Response.prototype, Symbol.for("nodejs.util.inspect.custom"), {
69
+ value: function(depth, options, inspectFn) {
70
+ const props = {
71
+ status: this.status,
72
+ headers: this.headers,
73
+ ok: this.ok,
74
+ nativeResponse: this[responseCache]
75
+ };
76
+ return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
77
+ }
78
+ });
66
79
  Object.setPrototypeOf(Response, GlobalResponse);
67
80
  Object.setPrototypeOf(Response.prototype, GlobalResponse.prototype);
68
81
  export {
@@ -100,7 +100,7 @@ var serveStatic = (options = { root: "" }) => {
100
100
  } else {
101
101
  try {
102
102
  filename = tryDecodeURI(c.req.path);
103
- if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
103
+ if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}/.test(filename)) {
104
104
  throw new Error();
105
105
  }
106
106
  } catch {
@@ -76,7 +76,7 @@ var serveStatic = (options = { root: "" }) => {
76
76
  } else {
77
77
  try {
78
78
  filename = tryDecodeURI(c.req.path);
79
- if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
79
+ if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}/.test(filename)) {
80
80
  throw new Error();
81
81
  }
82
82
  } catch {
package/dist/server.js CHANGED
@@ -186,6 +186,17 @@ var requestPrototype = {
186
186
  }
187
187
  });
188
188
  });
189
+ Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), {
190
+ value: function(depth, options, inspectFn) {
191
+ const props = {
192
+ method: this.method,
193
+ url: this.url,
194
+ headers: this.headers,
195
+ nativeRequest: this[requestCache]
196
+ };
197
+ return `Request (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
198
+ }
199
+ });
189
200
  Object.setPrototypeOf(requestPrototype, Request.prototype);
190
201
  var newRequest = (incoming, defaultHostname) => {
191
202
  const req = Object.create(requestPrototype);
@@ -254,15 +265,17 @@ var Response2 = class _Response {
254
265
  this.#init = init;
255
266
  }
256
267
  if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
257
- headers ||= init?.headers || { "content-type": "text/plain; charset=UTF-8" };
258
- this[cacheKey] = [init?.status || 200, body, headers];
268
+ ;
269
+ this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
259
270
  }
260
271
  }
261
272
  get headers() {
262
273
  const cache = this[cacheKey];
263
274
  if (cache) {
264
275
  if (!(cache[2] instanceof Headers)) {
265
- cache[2] = new Headers(cache[2]);
276
+ cache[2] = new Headers(
277
+ cache[2] || { "content-type": "text/plain; charset=UTF-8" }
278
+ );
266
279
  }
267
280
  return cache[2];
268
281
  }
@@ -290,6 +303,17 @@ var Response2 = class _Response {
290
303
  }
291
304
  });
292
305
  });
306
+ Object.defineProperty(Response2.prototype, Symbol.for("nodejs.util.inspect.custom"), {
307
+ value: function(depth, options, inspectFn) {
308
+ const props = {
309
+ status: this.status,
310
+ headers: this.headers,
311
+ ok: this.ok,
312
+ nativeResponse: this[responseCache]
313
+ };
314
+ return `Response (lightweight) ${inspectFn(props, { ...options, depth: depth == null ? null : depth - 1 })}`;
315
+ }
316
+ });
293
317
  Object.setPrototypeOf(Response2, GlobalResponse);
294
318
  Object.setPrototypeOf(Response2.prototype, GlobalResponse.prototype);
295
319
 
@@ -370,6 +394,50 @@ if (typeof global.crypto === "undefined") {
370
394
 
371
395
  // src/listener.ts
372
396
  var outgoingEnded = Symbol("outgoingEnded");
397
+ var incomingDraining = Symbol("incomingDraining");
398
+ var DRAIN_TIMEOUT_MS = 500;
399
+ var MAX_DRAIN_BYTES = 64 * 1024 * 1024;
400
+ var drainIncoming = (incoming) => {
401
+ const incomingWithDrainState = incoming;
402
+ if (incoming.destroyed || incomingWithDrainState[incomingDraining]) {
403
+ return;
404
+ }
405
+ incomingWithDrainState[incomingDraining] = true;
406
+ if (incoming instanceof import_node_http22.Http2ServerRequest) {
407
+ try {
408
+ ;
409
+ incoming.stream?.close?.(import_node_http22.constants.NGHTTP2_NO_ERROR);
410
+ } catch {
411
+ }
412
+ return;
413
+ }
414
+ let bytesRead = 0;
415
+ const cleanup = () => {
416
+ clearTimeout(timer);
417
+ incoming.off("data", onData);
418
+ incoming.off("end", cleanup);
419
+ incoming.off("error", cleanup);
420
+ };
421
+ const forceClose = () => {
422
+ cleanup();
423
+ const socket = incoming.socket;
424
+ if (socket && !socket.destroyed) {
425
+ socket.destroySoon();
426
+ }
427
+ };
428
+ const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
429
+ timer.unref?.();
430
+ const onData = (chunk) => {
431
+ bytesRead += chunk.length;
432
+ if (bytesRead > MAX_DRAIN_BYTES) {
433
+ forceClose();
434
+ }
435
+ };
436
+ incoming.on("data", onData);
437
+ incoming.on("end", cleanup);
438
+ incoming.on("error", cleanup);
439
+ incoming.resume();
440
+ };
373
441
  var handleRequestError = () => new Response(null, {
374
442
  status: 400
375
443
  });
@@ -396,15 +464,32 @@ var flushHeaders = (outgoing) => {
396
464
  };
397
465
  var responseViaCache = async (res, outgoing) => {
398
466
  let [status, body, header] = res[cacheKey];
399
- if (header instanceof Headers) {
467
+ let hasContentLength = false;
468
+ if (!header) {
469
+ header = { "content-type": "text/plain; charset=UTF-8" };
470
+ } else if (header instanceof Headers) {
471
+ hasContentLength = header.has("content-length");
400
472
  header = buildOutgoingHttpHeaders(header);
473
+ } else if (Array.isArray(header)) {
474
+ const headerObj = new Headers(header);
475
+ hasContentLength = headerObj.has("content-length");
476
+ header = buildOutgoingHttpHeaders(headerObj);
477
+ } else {
478
+ for (const key in header) {
479
+ if (key.length === 14 && key.toLowerCase() === "content-length") {
480
+ hasContentLength = true;
481
+ break;
482
+ }
483
+ }
401
484
  }
402
- if (typeof body === "string") {
403
- header["Content-Length"] = Buffer.byteLength(body);
404
- } else if (body instanceof Uint8Array) {
405
- header["Content-Length"] = body.byteLength;
406
- } else if (body instanceof Blob) {
407
- header["Content-Length"] = body.size;
485
+ if (!hasContentLength) {
486
+ if (typeof body === "string") {
487
+ header["Content-Length"] = Buffer.byteLength(body);
488
+ } else if (body instanceof Uint8Array) {
489
+ header["Content-Length"] = body.byteLength;
490
+ } else if (body instanceof Blob) {
491
+ header["Content-Length"] = body.size;
492
+ }
408
493
  }
409
494
  outgoing.writeHead(status, header);
410
495
  if (typeof body === "string" || body instanceof Uint8Array) {
@@ -524,14 +609,18 @@ var getRequestListener = (fetchCallback, options = {}) => {
524
609
  setTimeout(() => {
525
610
  if (!incomingEnded) {
526
611
  setTimeout(() => {
527
- incoming.destroy();
528
- outgoing.destroy();
612
+ drainIncoming(incoming);
529
613
  });
530
614
  }
531
615
  });
532
616
  }
533
617
  };
534
618
  }
619
+ outgoing.on("finish", () => {
620
+ if (!incomingEnded) {
621
+ drainIncoming(incoming);
622
+ }
623
+ });
535
624
  }
536
625
  outgoing.on("close", () => {
537
626
  const abortController = req[abortControllerKey];
@@ -546,7 +635,7 @@ var getRequestListener = (fetchCallback, options = {}) => {
546
635
  setTimeout(() => {
547
636
  if (!incomingEnded) {
548
637
  setTimeout(() => {
549
- incoming.destroy();
638
+ drainIncoming(incoming);
550
639
  });
551
640
  }
552
641
  });