@hono/node-server 1.16.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
@@ -128,6 +128,7 @@ serve({
128
128
  ### `autoCleanupIncoming`
129
129
 
130
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
+
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`.
132
133
 
133
134
  ```ts
@@ -167,7 +168,7 @@ import { serveStatic } from '@hono/node-server/serve-static'
167
168
  app.use('/static/*', serveStatic({ root: './' }))
168
169
  ```
169
170
 
170
- 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.
171
172
 
172
173
  This can cause confusion when running your application locally.
173
174
 
@@ -1,2 +1,2 @@
1
1
 
2
- export { }
2
+ export { }
package/dist/globals.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
 
2
- export { }
2
+ export { }
@@ -22,4 +22,4 @@ declare const abortControllerKey: unique symbol;
22
22
  declare const getAbortController: unique symbol;
23
23
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
24
24
 
25
- export { GlobalRequest, IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
25
+ export { GlobalRequest, type IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
package/dist/request.d.ts CHANGED
@@ -22,4 +22,4 @@ declare const abortControllerKey: unique symbol;
22
22
  declare const getAbortController: unique symbol;
23
23
  declare const newRequest: (incoming: IncomingMessage | Http2ServerRequest, defaultHostname?: string) => any;
24
24
 
25
- export { GlobalRequest, IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
25
+ export { GlobalRequest, type IncomingMessageWithWrapBodyStream, Request, RequestError, abortControllerKey, getAbortController, newRequest, toRequestError, wrapBodyStream };
@@ -23,4 +23,4 @@ declare class Response {
23
23
  get ok(): boolean;
24
24
  }
25
25
 
26
- export { GlobalResponse, InternalCache, Response, cacheKey };
26
+ export { GlobalResponse, type InternalCache, Response, cacheKey };
@@ -23,4 +23,4 @@ declare class Response {
23
23
  get ok(): boolean;
24
24
  }
25
25
 
26
- export { GlobalResponse, InternalCache, Response, cacheKey };
26
+ export { GlobalResponse, type InternalCache, Response, cacheKey };
@@ -14,4 +14,4 @@ type ServeStaticOptions<E extends Env = Env> = {
14
14
  };
15
15
  declare const serveStatic: <E extends Env = any>(options?: ServeStaticOptions<E>) => MiddlewareHandler<E>;
16
16
 
17
- export { ServeStaticOptions, serveStatic };
17
+ export { type ServeStaticOptions, serveStatic };
@@ -14,4 +14,4 @@ type ServeStaticOptions<E extends Env = Env> = {
14
14
  };
15
15
  declare const serveStatic: <E extends Env = any>(options?: ServeStaticOptions<E>) => MiddlewareHandler<E>;
16
16
 
17
- export { ServeStaticOptions, serveStatic };
17
+ export { type ServeStaticOptions, serveStatic };
@@ -23,9 +23,9 @@ __export(serve_static_exports, {
23
23
  serveStatic: () => serveStatic
24
24
  });
25
25
  module.exports = __toCommonJS(serve_static_exports);
26
- var import_filepath = require("hono/utils/filepath");
27
26
  var import_mime = require("hono/utils/mime");
28
27
  var import_node_fs = require("fs");
28
+ var import_node_path = require("path");
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",
@@ -49,9 +49,6 @@ var createStreamBody = (stream) => {
49
49
  });
50
50
  return body;
51
51
  };
52
- var addCurrentDirPrefix = (path) => {
53
- return `./${path}`;
54
- };
55
52
  var getStats = (path) => {
56
53
  let stats;
57
54
  try {
@@ -61,36 +58,35 @@ var getStats = (path) => {
61
58
  return stats;
62
59
  };
63
60
  var serveStatic = (options = { root: "" }) => {
61
+ const root = (0, import_node_path.resolve)(options.root || ".");
62
+ const optionPath = options.path;
64
63
  return async (c, next) => {
65
64
  if (c.finalized) {
66
65
  return next();
67
66
  }
68
67
  let filename;
69
68
  try {
70
- filename = options.path ?? decodeURIComponent(c.req.path);
69
+ const rawPath = optionPath ?? c.req.path;
70
+ if (!optionPath) {
71
+ const decodedPath = decodeURIComponent(rawPath);
72
+ if (decodedPath.includes("..")) {
73
+ await options.onNotFound?.(rawPath, c);
74
+ return next();
75
+ }
76
+ }
77
+ filename = optionPath ?? decodeURIComponent(c.req.path);
71
78
  } catch {
72
79
  await options.onNotFound?.(c.req.path, c);
73
80
  return next();
74
81
  }
75
- let path = (0, import_filepath.getFilePathWithoutDefaultDocument)({
76
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename,
77
- root: options.root
78
- });
79
- if (path) {
80
- path = addCurrentDirPrefix(path);
81
- } else {
82
- return next();
83
- }
82
+ const requestPath = options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename;
83
+ let path = optionPath ? options.root ? (0, import_node_path.resolve)((0, import_node_path.join)(root, optionPath)) : optionPath : (0, import_node_path.resolve)((0, import_node_path.join)(root, requestPath));
84
84
  let stats = getStats(path);
85
85
  if (stats && stats.isDirectory()) {
86
- path = (0, import_filepath.getFilePath)({
87
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename,
88
- root: options.root,
89
- defaultDocument: options.index ?? "index.html"
90
- });
91
- if (path) {
92
- path = addCurrentDirPrefix(path);
93
- } else {
86
+ const indexFile = options.index ?? "index.html";
87
+ path = (0, import_node_path.resolve)((0, import_node_path.join)(path, indexFile));
88
+ if (!optionPath && !path.startsWith(root)) {
89
+ await options.onNotFound?.(path, c);
94
90
  return next();
95
91
  }
96
92
  stats = getStats(path);
@@ -1,7 +1,7 @@
1
1
  // src/serve-static.ts
2
- import { getFilePath, getFilePathWithoutDefaultDocument } from "hono/utils/filepath";
3
2
  import { getMimeType } from "hono/utils/mime";
4
3
  import { createReadStream, lstatSync } from "fs";
4
+ import { join, resolve } from "path";
5
5
  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;
6
6
  var ENCODINGS = {
7
7
  br: ".br",
@@ -25,9 +25,6 @@ var createStreamBody = (stream) => {
25
25
  });
26
26
  return body;
27
27
  };
28
- var addCurrentDirPrefix = (path) => {
29
- return `./${path}`;
30
- };
31
28
  var getStats = (path) => {
32
29
  let stats;
33
30
  try {
@@ -37,36 +34,35 @@ var getStats = (path) => {
37
34
  return stats;
38
35
  };
39
36
  var serveStatic = (options = { root: "" }) => {
37
+ const root = resolve(options.root || ".");
38
+ const optionPath = options.path;
40
39
  return async (c, next) => {
41
40
  if (c.finalized) {
42
41
  return next();
43
42
  }
44
43
  let filename;
45
44
  try {
46
- filename = options.path ?? decodeURIComponent(c.req.path);
45
+ const rawPath = optionPath ?? c.req.path;
46
+ if (!optionPath) {
47
+ const decodedPath = decodeURIComponent(rawPath);
48
+ if (decodedPath.includes("..")) {
49
+ await options.onNotFound?.(rawPath, c);
50
+ return next();
51
+ }
52
+ }
53
+ filename = optionPath ?? decodeURIComponent(c.req.path);
47
54
  } catch {
48
55
  await options.onNotFound?.(c.req.path, c);
49
56
  return next();
50
57
  }
51
- let path = getFilePathWithoutDefaultDocument({
52
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename,
53
- root: options.root
54
- });
55
- if (path) {
56
- path = addCurrentDirPrefix(path);
57
- } else {
58
- return next();
59
- }
58
+ const requestPath = options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename;
59
+ let path = optionPath ? options.root ? resolve(join(root, optionPath)) : optionPath : resolve(join(root, requestPath));
60
60
  let stats = getStats(path);
61
61
  if (stats && stats.isDirectory()) {
62
- path = getFilePath({
63
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename,
64
- root: options.root,
65
- defaultDocument: options.index ?? "index.html"
66
- });
67
- if (path) {
68
- path = addCurrentDirPrefix(path);
69
- } else {
62
+ const indexFile = options.index ?? "index.html";
63
+ path = resolve(join(path, indexFile));
64
+ if (!optionPath && !path.startsWith(root)) {
65
+ await options.onNotFound?.(path, c);
70
66
  return next();
71
67
  }
72
68
  stats = getStats(path);
package/dist/types.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { IncomingMessage, ServerResponse, Server, ServerOptions as ServerOptions$1, createServer } from 'node:http';
2
- import { Http2ServerRequest, Http2ServerResponse, Http2Server, Http2SecureServer, ServerOptions as ServerOptions$3, createServer as createServer$2, SecureServerOptions, createSecureServer } from 'node:http2';
1
+ import { IncomingMessage, ServerResponse, ServerOptions as ServerOptions$1, createServer, Server } from 'node:http';
2
+ import { Http2ServerRequest, Http2ServerResponse, ServerOptions as ServerOptions$3, createServer as createServer$2, SecureServerOptions, createSecureServer, Http2Server, Http2SecureServer } from 'node:http2';
3
3
  import { ServerOptions as ServerOptions$2, createServer as createServer$1 } from 'node:https';
4
4
 
5
5
  type HttpBindings = {
@@ -41,4 +41,4 @@ type Options = {
41
41
  } & ServerOptions;
42
42
  type CustomErrorHandler = (err: unknown) => void | Response | Promise<void | Response>;
43
43
 
44
- export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerOptions, ServerType };
44
+ export type { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerOptions, ServerType };
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { IncomingMessage, ServerResponse, Server, ServerOptions as ServerOptions$1, createServer } from 'node:http';
2
- import { Http2ServerRequest, Http2ServerResponse, Http2Server, Http2SecureServer, ServerOptions as ServerOptions$3, createServer as createServer$2, SecureServerOptions, createSecureServer } from 'node:http2';
1
+ import { IncomingMessage, ServerResponse, ServerOptions as ServerOptions$1, createServer, Server } from 'node:http';
2
+ import { Http2ServerRequest, Http2ServerResponse, ServerOptions as ServerOptions$3, createServer as createServer$2, SecureServerOptions, createSecureServer, Http2Server, Http2SecureServer } from 'node:http2';
3
3
  import { ServerOptions as ServerOptions$2, createServer as createServer$1 } from 'node:https';
4
4
 
5
5
  type HttpBindings = {
@@ -41,4 +41,4 @@ type Options = {
41
41
  } & ServerOptions;
42
42
  type CustomErrorHandler = (err: unknown) => void | Response | Promise<void | Response>;
43
43
 
44
- export { CustomErrorHandler, FetchCallback, Http2Bindings, HttpBindings, NextHandlerOption, Options, ServerOptions, ServerType };
44
+ export type { 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<void> | undefined;
4
+ declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<undefined> | 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<void> | undefined;
4
+ declare function writeFromReadableStream(stream: ReadableStream<Uint8Array>, writable: Writable): Promise<undefined> | undefined;
5
5
  declare const buildOutgoingHttpHeaders: (headers: Headers | HeadersInit | null | undefined) => OutgoingHttpHeaders;
6
6
 
7
7
  export { buildOutgoingHttpHeaders, writeFromReadableStream };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono/node-server",
3
- "version": "1.16.0",
3
+ "version": "1.17.0",
4
4
  "description": "Node.js Adapter for Hono",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -54,7 +54,7 @@
54
54
  }
55
55
  },
56
56
  "scripts": {
57
- "test": "node --expose-gc ./node_modules/.bin/jest",
57
+ "test": "node --expose-gc node_modules/jest/bin/jest.js",
58
58
  "build": "tsup --external hono",
59
59
  "watch": "tsup --watch",
60
60
  "postbuild": "publint",