@hono/node-server 1.13.7 → 1.14.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/dist/index.js CHANGED
@@ -94,7 +94,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
94
94
  return req;
95
95
  }
96
96
  if (!(method === "GET" || method === "HEAD")) {
97
- init.body = import_node_stream.Readable.toWeb(incoming);
97
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
98
+ init.body = new ReadableStream({
99
+ start(controller) {
100
+ controller.enqueue(incoming.rawBody);
101
+ controller.close();
102
+ }
103
+ });
104
+ } else {
105
+ init.body = import_node_stream.Readable.toWeb(incoming);
106
+ }
98
107
  }
99
108
  return new Request(url, init);
100
109
  };
@@ -157,13 +166,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
157
166
  var newRequest = (incoming, defaultHostname) => {
158
167
  const req = Object.create(requestPrototype);
159
168
  req[incomingKey] = incoming;
169
+ const incomingUrl = incoming.url || "";
170
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
171
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
172
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
173
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
174
+ }
175
+ try {
176
+ const url2 = new URL(incomingUrl);
177
+ req[urlKey] = url2.href;
178
+ } catch (e) {
179
+ throw new RequestError("Invalid absolute URL", { cause: e });
180
+ }
181
+ return req;
182
+ }
160
183
  const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
161
184
  if (!host) {
162
185
  throw new RequestError("Missing host header");
163
186
  }
164
- const url = new URL(
165
- `${incoming instanceof import_node_http2.Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
166
- );
187
+ let scheme;
188
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
189
+ scheme = incoming.scheme;
190
+ if (!(scheme === "http" || scheme === "https")) {
191
+ throw new RequestError("Unsupported scheme");
192
+ }
193
+ } else {
194
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
195
+ }
196
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
167
197
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
168
198
  throw new RequestError("Invalid host header");
169
199
  }
@@ -442,10 +472,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
442
472
  try {
443
473
  req = newRequest(incoming, options.hostname);
444
474
  outgoing.on("close", () => {
475
+ const abortController = req[abortControllerKey];
476
+ if (!abortController) {
477
+ return;
478
+ }
445
479
  if (incoming.errored) {
446
- req[getAbortController]().abort(incoming.errored.toString());
480
+ req[abortControllerKey].abort(incoming.errored.toString());
447
481
  } else if (!outgoing.writableFinished) {
448
- req[getAbortController]().abort("Client connection prematurely closed.");
482
+ req[abortControllerKey].abort("Client connection prematurely closed.");
449
483
  }
450
484
  });
451
485
  res = fetchCallback(req, { incoming, outgoing });
package/dist/index.mjs CHANGED
@@ -55,7 +55,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
55
55
  return req;
56
56
  }
57
57
  if (!(method === "GET" || method === "HEAD")) {
58
- init.body = Readable.toWeb(incoming);
58
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
59
+ init.body = new ReadableStream({
60
+ start(controller) {
61
+ controller.enqueue(incoming.rawBody);
62
+ controller.close();
63
+ }
64
+ });
65
+ } else {
66
+ init.body = Readable.toWeb(incoming);
67
+ }
59
68
  }
60
69
  return new Request(url, init);
61
70
  };
@@ -118,13 +127,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
118
127
  var newRequest = (incoming, defaultHostname) => {
119
128
  const req = Object.create(requestPrototype);
120
129
  req[incomingKey] = incoming;
130
+ const incomingUrl = incoming.url || "";
131
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
132
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
133
+ if (incoming instanceof Http2ServerRequest) {
134
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
135
+ }
136
+ try {
137
+ const url2 = new URL(incomingUrl);
138
+ req[urlKey] = url2.href;
139
+ } catch (e) {
140
+ throw new RequestError("Invalid absolute URL", { cause: e });
141
+ }
142
+ return req;
143
+ }
121
144
  const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
122
145
  if (!host) {
123
146
  throw new RequestError("Missing host header");
124
147
  }
125
- const url = new URL(
126
- `${incoming instanceof Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
127
- );
148
+ let scheme;
149
+ if (incoming instanceof Http2ServerRequest) {
150
+ scheme = incoming.scheme;
151
+ if (!(scheme === "http" || scheme === "https")) {
152
+ throw new RequestError("Unsupported scheme");
153
+ }
154
+ } else {
155
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
156
+ }
157
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
128
158
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
129
159
  throw new RequestError("Invalid host header");
130
160
  }
@@ -403,10 +433,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
403
433
  try {
404
434
  req = newRequest(incoming, options.hostname);
405
435
  outgoing.on("close", () => {
436
+ const abortController = req[abortControllerKey];
437
+ if (!abortController) {
438
+ return;
439
+ }
406
440
  if (incoming.errored) {
407
- req[getAbortController]().abort(incoming.errored.toString());
441
+ req[abortControllerKey].abort(incoming.errored.toString());
408
442
  } else if (!outgoing.writableFinished) {
409
- req[getAbortController]().abort("Client connection prematurely closed.");
443
+ req[abortControllerKey].abort("Client connection prematurely closed.");
410
444
  }
411
445
  });
412
446
  res = fetchCallback(req, { incoming, outgoing });
package/dist/listener.js CHANGED
@@ -88,7 +88,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
88
88
  return req;
89
89
  }
90
90
  if (!(method === "GET" || method === "HEAD")) {
91
- init.body = import_node_stream.Readable.toWeb(incoming);
91
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
92
+ init.body = new ReadableStream({
93
+ start(controller) {
94
+ controller.enqueue(incoming.rawBody);
95
+ controller.close();
96
+ }
97
+ });
98
+ } else {
99
+ init.body = import_node_stream.Readable.toWeb(incoming);
100
+ }
92
101
  }
93
102
  return new Request(url, init);
94
103
  };
@@ -151,13 +160,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
151
160
  var newRequest = (incoming, defaultHostname) => {
152
161
  const req = Object.create(requestPrototype);
153
162
  req[incomingKey] = incoming;
163
+ const incomingUrl = incoming.url || "";
164
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
165
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
166
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
167
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
168
+ }
169
+ try {
170
+ const url2 = new URL(incomingUrl);
171
+ req[urlKey] = url2.href;
172
+ } catch (e) {
173
+ throw new RequestError("Invalid absolute URL", { cause: e });
174
+ }
175
+ return req;
176
+ }
154
177
  const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
155
178
  if (!host) {
156
179
  throw new RequestError("Missing host header");
157
180
  }
158
- const url = new URL(
159
- `${incoming instanceof import_node_http2.Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
160
- );
181
+ let scheme;
182
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
183
+ scheme = incoming.scheme;
184
+ if (!(scheme === "http" || scheme === "https")) {
185
+ throw new RequestError("Unsupported scheme");
186
+ }
187
+ } else {
188
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
189
+ }
190
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
161
191
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
162
192
  throw new RequestError("Invalid host header");
163
193
  }
@@ -436,10 +466,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
436
466
  try {
437
467
  req = newRequest(incoming, options.hostname);
438
468
  outgoing.on("close", () => {
469
+ const abortController = req[abortControllerKey];
470
+ if (!abortController) {
471
+ return;
472
+ }
439
473
  if (incoming.errored) {
440
- req[getAbortController]().abort(incoming.errored.toString());
474
+ req[abortControllerKey].abort(incoming.errored.toString());
441
475
  } else if (!outgoing.writableFinished) {
442
- req[getAbortController]().abort("Client connection prematurely closed.");
476
+ req[abortControllerKey].abort("Client connection prematurely closed.");
443
477
  }
444
478
  });
445
479
  res = fetchCallback(req, { incoming, outgoing });
package/dist/listener.mjs CHANGED
@@ -52,7 +52,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
52
52
  return req;
53
53
  }
54
54
  if (!(method === "GET" || method === "HEAD")) {
55
- init.body = Readable.toWeb(incoming);
55
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
56
+ init.body = new ReadableStream({
57
+ start(controller) {
58
+ controller.enqueue(incoming.rawBody);
59
+ controller.close();
60
+ }
61
+ });
62
+ } else {
63
+ init.body = Readable.toWeb(incoming);
64
+ }
56
65
  }
57
66
  return new Request(url, init);
58
67
  };
@@ -115,13 +124,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
115
124
  var newRequest = (incoming, defaultHostname) => {
116
125
  const req = Object.create(requestPrototype);
117
126
  req[incomingKey] = incoming;
127
+ const incomingUrl = incoming.url || "";
128
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
129
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
130
+ if (incoming instanceof Http2ServerRequest) {
131
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
132
+ }
133
+ try {
134
+ const url2 = new URL(incomingUrl);
135
+ req[urlKey] = url2.href;
136
+ } catch (e) {
137
+ throw new RequestError("Invalid absolute URL", { cause: e });
138
+ }
139
+ return req;
140
+ }
118
141
  const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
119
142
  if (!host) {
120
143
  throw new RequestError("Missing host header");
121
144
  }
122
- const url = new URL(
123
- `${incoming instanceof Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
124
- );
145
+ let scheme;
146
+ if (incoming instanceof Http2ServerRequest) {
147
+ scheme = incoming.scheme;
148
+ if (!(scheme === "http" || scheme === "https")) {
149
+ throw new RequestError("Unsupported scheme");
150
+ }
151
+ } else {
152
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
153
+ }
154
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
125
155
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
126
156
  throw new RequestError("Invalid host header");
127
157
  }
@@ -400,10 +430,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
400
430
  try {
401
431
  req = newRequest(incoming, options.hostname);
402
432
  outgoing.on("close", () => {
433
+ const abortController = req[abortControllerKey];
434
+ if (!abortController) {
435
+ return;
436
+ }
403
437
  if (incoming.errored) {
404
- req[getAbortController]().abort(incoming.errored.toString());
438
+ req[abortControllerKey].abort(incoming.errored.toString());
405
439
  } else if (!outgoing.writableFinished) {
406
- req[getAbortController]().abort("Client connection prematurely closed.");
440
+ req[abortControllerKey].abort("Client connection prematurely closed.");
407
441
  }
408
442
  });
409
443
  res = fetchCallback(req, { incoming, outgoing });
@@ -9,13 +9,14 @@ declare class RequestError extends Error {
9
9
  }
10
10
  declare const toRequestError: (e: unknown) => RequestError;
11
11
  declare const GlobalRequest: {
12
- new (input: RequestInfo | URL, init?: RequestInit | undefined): globalThis.Request;
12
+ new (input: RequestInfo | URL, init?: RequestInit): globalThis.Request;
13
13
  prototype: globalThis.Request;
14
14
  };
15
15
  declare class Request extends GlobalRequest {
16
16
  constructor(input: string | Request, options?: RequestInit);
17
17
  }
18
+ declare const abortControllerKey: unique symbol;
18
19
  declare const getAbortController: unique symbol;
19
20
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
20
21
 
21
- export { GlobalRequest, Request, RequestError, getAbortController, newRequest, toRequestError };
22
+ export { GlobalRequest, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError };
package/dist/request.d.ts CHANGED
@@ -9,13 +9,14 @@ declare class RequestError extends Error {
9
9
  }
10
10
  declare const toRequestError: (e: unknown) => RequestError;
11
11
  declare const GlobalRequest: {
12
- new (input: RequestInfo | URL, init?: RequestInit | undefined): globalThis.Request;
12
+ new (input: RequestInfo | URL, init?: RequestInit): globalThis.Request;
13
13
  prototype: globalThis.Request;
14
14
  };
15
15
  declare class Request extends GlobalRequest {
16
16
  constructor(input: string | Request, options?: RequestInit);
17
17
  }
18
+ declare const abortControllerKey: unique symbol;
18
19
  declare const getAbortController: unique symbol;
19
20
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
20
21
 
21
- export { GlobalRequest, Request, RequestError, getAbortController, newRequest, toRequestError };
22
+ export { GlobalRequest, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError };
package/dist/request.js CHANGED
@@ -23,6 +23,7 @@ __export(request_exports, {
23
23
  GlobalRequest: () => GlobalRequest,
24
24
  Request: () => Request,
25
25
  RequestError: () => RequestError,
26
+ abortControllerKey: () => abortControllerKey,
26
27
  getAbortController: () => getAbortController,
27
28
  newRequest: () => newRequest,
28
29
  toRequestError: () => toRequestError
@@ -81,7 +82,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
81
82
  return req;
82
83
  }
83
84
  if (!(method === "GET" || method === "HEAD")) {
84
- init.body = import_node_stream.Readable.toWeb(incoming);
85
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
86
+ init.body = new ReadableStream({
87
+ start(controller) {
88
+ controller.enqueue(incoming.rawBody);
89
+ controller.close();
90
+ }
91
+ });
92
+ } else {
93
+ init.body = import_node_stream.Readable.toWeb(incoming);
94
+ }
85
95
  }
86
96
  return new Request(url, init);
87
97
  };
@@ -144,13 +154,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
144
154
  var newRequest = (incoming, defaultHostname) => {
145
155
  const req = Object.create(requestPrototype);
146
156
  req[incomingKey] = incoming;
157
+ const incomingUrl = incoming.url || "";
158
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
159
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
160
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
161
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
162
+ }
163
+ try {
164
+ const url2 = new URL(incomingUrl);
165
+ req[urlKey] = url2.href;
166
+ } catch (e) {
167
+ throw new RequestError("Invalid absolute URL", { cause: e });
168
+ }
169
+ return req;
170
+ }
147
171
  const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
148
172
  if (!host) {
149
173
  throw new RequestError("Missing host header");
150
174
  }
151
- const url = new URL(
152
- `${incoming instanceof import_node_http2.Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
153
- );
175
+ let scheme;
176
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
177
+ scheme = incoming.scheme;
178
+ if (!(scheme === "http" || scheme === "https")) {
179
+ throw new RequestError("Unsupported scheme");
180
+ }
181
+ } else {
182
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
183
+ }
184
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
154
185
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
155
186
  throw new RequestError("Invalid host header");
156
187
  }
@@ -162,6 +193,7 @@ var newRequest = (incoming, defaultHostname) => {
162
193
  GlobalRequest,
163
194
  Request,
164
195
  RequestError,
196
+ abortControllerKey,
165
197
  getAbortController,
166
198
  newRequest,
167
199
  toRequestError
package/dist/request.mjs CHANGED
@@ -52,7 +52,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
52
52
  return req;
53
53
  }
54
54
  if (!(method === "GET" || method === "HEAD")) {
55
- init.body = Readable.toWeb(incoming);
55
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
56
+ init.body = new ReadableStream({
57
+ start(controller) {
58
+ controller.enqueue(incoming.rawBody);
59
+ controller.close();
60
+ }
61
+ });
62
+ } else {
63
+ init.body = Readable.toWeb(incoming);
64
+ }
56
65
  }
57
66
  return new Request(url, init);
58
67
  };
@@ -115,13 +124,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
115
124
  var newRequest = (incoming, defaultHostname) => {
116
125
  const req = Object.create(requestPrototype);
117
126
  req[incomingKey] = incoming;
127
+ const incomingUrl = incoming.url || "";
128
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
129
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
130
+ if (incoming instanceof Http2ServerRequest) {
131
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
132
+ }
133
+ try {
134
+ const url2 = new URL(incomingUrl);
135
+ req[urlKey] = url2.href;
136
+ } catch (e) {
137
+ throw new RequestError("Invalid absolute URL", { cause: e });
138
+ }
139
+ return req;
140
+ }
118
141
  const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
119
142
  if (!host) {
120
143
  throw new RequestError("Missing host header");
121
144
  }
122
- const url = new URL(
123
- `${incoming instanceof Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
124
- );
145
+ let scheme;
146
+ if (incoming instanceof Http2ServerRequest) {
147
+ scheme = incoming.scheme;
148
+ if (!(scheme === "http" || scheme === "https")) {
149
+ throw new RequestError("Unsupported scheme");
150
+ }
151
+ } else {
152
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
153
+ }
154
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
125
155
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
126
156
  throw new RequestError("Invalid host header");
127
157
  }
@@ -132,6 +162,7 @@ export {
132
162
  GlobalRequest,
133
163
  Request,
134
164
  RequestError,
165
+ abortControllerKey,
135
166
  getAbortController,
136
167
  newRequest,
137
168
  toRequestError
@@ -6,11 +6,11 @@ interface InternalBody {
6
6
  declare const getResponseCache: unique symbol;
7
7
  declare const cacheKey: unique symbol;
8
8
  declare const GlobalResponse: {
9
- new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): globalThis.Response;
9
+ new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response;
10
10
  prototype: globalThis.Response;
11
11
  error(): globalThis.Response;
12
- json(data: any, init?: ResponseInit | undefined): globalThis.Response;
13
- redirect(url: string | URL, status?: number | undefined): globalThis.Response;
12
+ json(data: any, init?: ResponseInit): globalThis.Response;
13
+ redirect(url: string | URL, status?: number): globalThis.Response;
14
14
  };
15
15
  declare class Response {
16
16
  #private;
@@ -6,11 +6,11 @@ interface InternalBody {
6
6
  declare const getResponseCache: unique symbol;
7
7
  declare const cacheKey: unique symbol;
8
8
  declare const GlobalResponse: {
9
- new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined): globalThis.Response;
9
+ new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response;
10
10
  prototype: globalThis.Response;
11
11
  error(): globalThis.Response;
12
- json(data: any, init?: ResponseInit | undefined): globalThis.Response;
13
- redirect(url: string | URL, status?: number | undefined): globalThis.Response;
12
+ json(data: any, init?: ResponseInit): globalThis.Response;
13
+ redirect(url: string | URL, status?: number): globalThis.Response;
14
14
  };
15
15
  declare class Response {
16
16
  #private;
@@ -25,7 +25,7 @@ __export(serve_static_exports, {
25
25
  module.exports = __toCommonJS(serve_static_exports);
26
26
  var import_filepath = require("hono/utils/filepath");
27
27
  var import_mime = require("hono/utils/mime");
28
- var import_fs = require("fs");
28
+ var import_node_fs = require("fs");
29
29
  var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
30
30
  var ENCODINGS = {
31
31
  br: ".br",
@@ -55,7 +55,7 @@ var addCurrentDirPrefix = (path) => {
55
55
  var getStats = (path) => {
56
56
  let stats;
57
57
  try {
58
- stats = (0, import_fs.lstatSync)(path);
58
+ stats = (0, import_node_fs.lstatSync)(path);
59
59
  } catch {
60
60
  }
61
61
  return stats;
@@ -129,7 +129,7 @@ var serveStatic = (options = { root: "" }) => {
129
129
  const range = c.req.header("range") || "";
130
130
  if (!range) {
131
131
  c.header("Content-Length", size.toString());
132
- return c.body(createStreamBody((0, import_fs.createReadStream)(path)), 200);
132
+ return c.body(createStreamBody((0, import_node_fs.createReadStream)(path)), 200);
133
133
  }
134
134
  c.header("Accept-Ranges", "bytes");
135
135
  c.header("Date", stats.birthtime.toUTCString());
@@ -140,7 +140,7 @@ var serveStatic = (options = { root: "" }) => {
140
140
  end = size - 1;
141
141
  }
142
142
  const chunksize = end - start + 1;
143
- const stream = (0, import_fs.createReadStream)(path, { start, end });
143
+ const stream = (0, import_node_fs.createReadStream)(path, { start, end });
144
144
  c.header("Content-Length", chunksize.toString());
145
145
  c.header("Content-Range", `bytes ${start}-${end}/${stats.size}`);
146
146
  return c.body(createStreamBody(stream), 206);
package/dist/server.d.mts CHANGED
@@ -5,6 +5,6 @@ import 'node:http2';
5
5
  import 'node:https';
6
6
 
7
7
  declare const createAdaptorServer: (options: Options) => ServerType;
8
- declare const serve: (options: Options, listeningListener?: ((info: AddressInfo) => void) | undefined) => ServerType;
8
+ declare const serve: (options: Options, listeningListener?: (info: AddressInfo) => void) => ServerType;
9
9
 
10
10
  export { createAdaptorServer, serve };
package/dist/server.d.ts CHANGED
@@ -5,6 +5,6 @@ import 'node:http2';
5
5
  import 'node:https';
6
6
 
7
7
  declare const createAdaptorServer: (options: Options) => ServerType;
8
- declare const serve: (options: Options, listeningListener?: ((info: AddressInfo) => void) | undefined) => ServerType;
8
+ declare const serve: (options: Options, listeningListener?: (info: AddressInfo) => void) => ServerType;
9
9
 
10
10
  export { createAdaptorServer, serve };
package/dist/server.js CHANGED
@@ -90,7 +90,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
90
90
  return req;
91
91
  }
92
92
  if (!(method === "GET" || method === "HEAD")) {
93
- init.body = import_node_stream.Readable.toWeb(incoming);
93
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
94
+ init.body = new ReadableStream({
95
+ start(controller) {
96
+ controller.enqueue(incoming.rawBody);
97
+ controller.close();
98
+ }
99
+ });
100
+ } else {
101
+ init.body = import_node_stream.Readable.toWeb(incoming);
102
+ }
94
103
  }
95
104
  return new Request(url, init);
96
105
  };
@@ -153,13 +162,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
153
162
  var newRequest = (incoming, defaultHostname) => {
154
163
  const req = Object.create(requestPrototype);
155
164
  req[incomingKey] = incoming;
165
+ const incomingUrl = incoming.url || "";
166
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
167
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
168
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
169
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
170
+ }
171
+ try {
172
+ const url2 = new URL(incomingUrl);
173
+ req[urlKey] = url2.href;
174
+ } catch (e) {
175
+ throw new RequestError("Invalid absolute URL", { cause: e });
176
+ }
177
+ return req;
178
+ }
156
179
  const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
157
180
  if (!host) {
158
181
  throw new RequestError("Missing host header");
159
182
  }
160
- const url = new URL(
161
- `${incoming instanceof import_node_http2.Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
162
- );
183
+ let scheme;
184
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
185
+ scheme = incoming.scheme;
186
+ if (!(scheme === "http" || scheme === "https")) {
187
+ throw new RequestError("Unsupported scheme");
188
+ }
189
+ } else {
190
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
191
+ }
192
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
163
193
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
164
194
  throw new RequestError("Invalid host header");
165
195
  }
@@ -438,10 +468,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
438
468
  try {
439
469
  req = newRequest(incoming, options.hostname);
440
470
  outgoing.on("close", () => {
471
+ const abortController = req[abortControllerKey];
472
+ if (!abortController) {
473
+ return;
474
+ }
441
475
  if (incoming.errored) {
442
- req[getAbortController]().abort(incoming.errored.toString());
476
+ req[abortControllerKey].abort(incoming.errored.toString());
443
477
  } else if (!outgoing.writableFinished) {
444
- req[getAbortController]().abort("Client connection prematurely closed.");
478
+ req[abortControllerKey].abort("Client connection prematurely closed.");
445
479
  }
446
480
  });
447
481
  res = fetchCallback(req, { incoming, outgoing });
package/dist/server.mjs CHANGED
@@ -55,7 +55,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
55
55
  return req;
56
56
  }
57
57
  if (!(method === "GET" || method === "HEAD")) {
58
- init.body = Readable.toWeb(incoming);
58
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
59
+ init.body = new ReadableStream({
60
+ start(controller) {
61
+ controller.enqueue(incoming.rawBody);
62
+ controller.close();
63
+ }
64
+ });
65
+ } else {
66
+ init.body = Readable.toWeb(incoming);
67
+ }
59
68
  }
60
69
  return new Request(url, init);
61
70
  };
@@ -118,13 +127,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
118
127
  var newRequest = (incoming, defaultHostname) => {
119
128
  const req = Object.create(requestPrototype);
120
129
  req[incomingKey] = incoming;
130
+ const incomingUrl = incoming.url || "";
131
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
132
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
133
+ if (incoming instanceof Http2ServerRequest) {
134
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
135
+ }
136
+ try {
137
+ const url2 = new URL(incomingUrl);
138
+ req[urlKey] = url2.href;
139
+ } catch (e) {
140
+ throw new RequestError("Invalid absolute URL", { cause: e });
141
+ }
142
+ return req;
143
+ }
121
144
  const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
122
145
  if (!host) {
123
146
  throw new RequestError("Missing host header");
124
147
  }
125
- const url = new URL(
126
- `${incoming instanceof Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
127
- );
148
+ let scheme;
149
+ if (incoming instanceof Http2ServerRequest) {
150
+ scheme = incoming.scheme;
151
+ if (!(scheme === "http" || scheme === "https")) {
152
+ throw new RequestError("Unsupported scheme");
153
+ }
154
+ } else {
155
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
156
+ }
157
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
128
158
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
129
159
  throw new RequestError("Invalid host header");
130
160
  }
@@ -403,10 +433,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
403
433
  try {
404
434
  req = newRequest(incoming, options.hostname);
405
435
  outgoing.on("close", () => {
436
+ const abortController = req[abortControllerKey];
437
+ if (!abortController) {
438
+ return;
439
+ }
406
440
  if (incoming.errored) {
407
- req[getAbortController]().abort(incoming.errored.toString());
441
+ req[abortControllerKey].abort(incoming.errored.toString());
408
442
  } else if (!outgoing.writableFinished) {
409
- req[getAbortController]().abort("Client connection prematurely closed.");
443
+ req[abortControllerKey].abort("Client connection prematurely closed.");
410
444
  }
411
445
  });
412
446
  res = fetchCallback(req, { incoming, outgoing });
package/dist/types.d.mts CHANGED
@@ -40,4 +40,4 @@ type Options = {
40
40
  } & ServerOptions;
41
41
  type CustomErrorHandler = (err: unknown) => void | Response | Promise<void | Response>;
42
42
 
43
- export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerType };
43
+ export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerOptions, ServerType };
package/dist/types.d.ts CHANGED
@@ -40,4 +40,4 @@ type Options = {
40
40
  } & ServerOptions;
41
41
  type CustomErrorHandler = (err: unknown) => void | Response | Promise<void | Response>;
42
42
 
43
- export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerType };
43
+ export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerOptions, ServerType };
package/dist/utils.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { OutgoingHttpHeaders } from 'node:http';
2
2
  import { Writable } from 'node:stream';
3
3
 
4
- declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<undefined> | undefined;
4
+ declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<void> | undefined;
5
5
  declare const buildOutgoingHttpHeaders: (headers: Headers | HeadersInit | null | undefined) => OutgoingHttpHeaders;
6
6
 
7
7
  export { buildOutgoingHttpHeaders, writeFromReadableStream };
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { OutgoingHttpHeaders } from 'node:http';
2
2
  import { Writable } from 'node:stream';
3
3
 
4
- declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<undefined> | undefined;
4
+ declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<void> | undefined;
5
5
  declare const buildOutgoingHttpHeaders: (headers: Headers | HeadersInit | null | undefined) => OutgoingHttpHeaders;
6
6
 
7
7
  export { buildOutgoingHttpHeaders, writeFromReadableStream };
package/dist/vercel.d.mts CHANGED
@@ -2,6 +2,6 @@ import * as http2 from 'http2';
2
2
  import * as http from 'http';
3
3
  import { Hono } from 'hono';
4
4
 
5
- declare const handle: (app: Hono<any, any, any>) => (incoming: http.IncomingMessage | http2.Http2ServerRequest, outgoing: http.ServerResponse<http.IncomingMessage> | http2.Http2ServerResponse) => Promise<void>;
5
+ declare const handle: (app: Hono<any, any, any>) => (incoming: http.IncomingMessage | http2.Http2ServerRequest, outgoing: http.ServerResponse | http2.Http2ServerResponse) => Promise<void>;
6
6
 
7
7
  export { handle };
package/dist/vercel.d.ts CHANGED
@@ -2,6 +2,6 @@ import * as http2 from 'http2';
2
2
  import * as http from 'http';
3
3
  import { Hono } from 'hono';
4
4
 
5
- declare const handle: (app: Hono<any, any, any>) => (incoming: http.IncomingMessage | http2.Http2ServerRequest, outgoing: http.ServerResponse<http.IncomingMessage> | http2.Http2ServerResponse) => Promise<void>;
5
+ declare const handle: (app: Hono<any, any, any>) => (incoming: http.IncomingMessage | http2.Http2ServerRequest, outgoing: http.ServerResponse | http2.Http2ServerResponse) => Promise<void>;
6
6
 
7
7
  export { handle };
package/dist/vercel.js CHANGED
@@ -88,7 +88,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
88
88
  return req;
89
89
  }
90
90
  if (!(method === "GET" || method === "HEAD")) {
91
- init.body = import_node_stream.Readable.toWeb(incoming);
91
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
92
+ init.body = new ReadableStream({
93
+ start(controller) {
94
+ controller.enqueue(incoming.rawBody);
95
+ controller.close();
96
+ }
97
+ });
98
+ } else {
99
+ init.body = import_node_stream.Readable.toWeb(incoming);
100
+ }
92
101
  }
93
102
  return new Request(url, init);
94
103
  };
@@ -151,13 +160,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
151
160
  var newRequest = (incoming, defaultHostname) => {
152
161
  const req = Object.create(requestPrototype);
153
162
  req[incomingKey] = incoming;
163
+ const incomingUrl = incoming.url || "";
164
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
165
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
166
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
167
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
168
+ }
169
+ try {
170
+ const url2 = new URL(incomingUrl);
171
+ req[urlKey] = url2.href;
172
+ } catch (e) {
173
+ throw new RequestError("Invalid absolute URL", { cause: e });
174
+ }
175
+ return req;
176
+ }
154
177
  const host = (incoming instanceof import_node_http2.Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
155
178
  if (!host) {
156
179
  throw new RequestError("Missing host header");
157
180
  }
158
- const url = new URL(
159
- `${incoming instanceof import_node_http2.Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
160
- );
181
+ let scheme;
182
+ if (incoming instanceof import_node_http2.Http2ServerRequest) {
183
+ scheme = incoming.scheme;
184
+ if (!(scheme === "http" || scheme === "https")) {
185
+ throw new RequestError("Unsupported scheme");
186
+ }
187
+ } else {
188
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
189
+ }
190
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
161
191
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
162
192
  throw new RequestError("Invalid host header");
163
193
  }
@@ -436,10 +466,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
436
466
  try {
437
467
  req = newRequest(incoming, options.hostname);
438
468
  outgoing.on("close", () => {
469
+ const abortController = req[abortControllerKey];
470
+ if (!abortController) {
471
+ return;
472
+ }
439
473
  if (incoming.errored) {
440
- req[getAbortController]().abort(incoming.errored.toString());
474
+ req[abortControllerKey].abort(incoming.errored.toString());
441
475
  } else if (!outgoing.writableFinished) {
442
- req[getAbortController]().abort("Client connection prematurely closed.");
476
+ req[abortControllerKey].abort("Client connection prematurely closed.");
443
477
  }
444
478
  });
445
479
  res = fetchCallback(req, { incoming, outgoing });
package/dist/vercel.mjs CHANGED
@@ -52,7 +52,16 @@ var newRequestFromIncoming = (method, url, incoming, abortController) => {
52
52
  return req;
53
53
  }
54
54
  if (!(method === "GET" || method === "HEAD")) {
55
- init.body = Readable.toWeb(incoming);
55
+ if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) {
56
+ init.body = new ReadableStream({
57
+ start(controller) {
58
+ controller.enqueue(incoming.rawBody);
59
+ controller.close();
60
+ }
61
+ });
62
+ } else {
63
+ init.body = Readable.toWeb(incoming);
64
+ }
56
65
  }
57
66
  return new Request(url, init);
58
67
  };
@@ -115,13 +124,34 @@ Object.setPrototypeOf(requestPrototype, Request.prototype);
115
124
  var newRequest = (incoming, defaultHostname) => {
116
125
  const req = Object.create(requestPrototype);
117
126
  req[incomingKey] = incoming;
127
+ const incomingUrl = incoming.url || "";
128
+ if (incomingUrl[0] !== "/" && // short-circuit for performance. most requests are relative URL.
129
+ (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
130
+ if (incoming instanceof Http2ServerRequest) {
131
+ throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
132
+ }
133
+ try {
134
+ const url2 = new URL(incomingUrl);
135
+ req[urlKey] = url2.href;
136
+ } catch (e) {
137
+ throw new RequestError("Invalid absolute URL", { cause: e });
138
+ }
139
+ return req;
140
+ }
118
141
  const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
119
142
  if (!host) {
120
143
  throw new RequestError("Missing host header");
121
144
  }
122
- const url = new URL(
123
- `${incoming instanceof Http2ServerRequest || incoming.socket && incoming.socket.encrypted ? "https" : "http"}://${host}${incoming.url}`
124
- );
145
+ let scheme;
146
+ if (incoming instanceof Http2ServerRequest) {
147
+ scheme = incoming.scheme;
148
+ if (!(scheme === "http" || scheme === "https")) {
149
+ throw new RequestError("Unsupported scheme");
150
+ }
151
+ } else {
152
+ scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
153
+ }
154
+ const url = new URL(`${scheme}://${host}${incomingUrl}`);
125
155
  if (url.hostname.length !== host.length && url.hostname !== host.replace(/:\d+$/, "")) {
126
156
  throw new RequestError("Invalid host header");
127
157
  }
@@ -400,10 +430,14 @@ var getRequestListener = (fetchCallback, options = {}) => {
400
430
  try {
401
431
  req = newRequest(incoming, options.hostname);
402
432
  outgoing.on("close", () => {
433
+ const abortController = req[abortControllerKey];
434
+ if (!abortController) {
435
+ return;
436
+ }
403
437
  if (incoming.errored) {
404
- req[getAbortController]().abort(incoming.errored.toString());
438
+ req[abortControllerKey].abort(incoming.errored.toString());
405
439
  } else if (!outgoing.writableFinished) {
406
- req[getAbortController]().abort("Client connection prematurely closed.");
440
+ req[abortControllerKey].abort("Client connection prematurely closed.");
407
441
  }
408
442
  });
409
443
  res = fetchCallback(req, { incoming, outgoing });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono/node-server",
3
- "version": "1.13.7",
3
+ "version": "1.14.0",
4
4
  "description": "Node.js Adapter for Hono",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -58,7 +58,7 @@
58
58
  "build": "tsup --external hono",
59
59
  "watch": "tsup --watch",
60
60
  "postbuild": "publint",
61
- "prerelease": "yarn build && yarn test",
61
+ "prerelease": "bun run build && bun run test",
62
62
  "release": "np",
63
63
  "lint": "eslint src test",
64
64
  "lint:fix": "eslint src test --fix",