[Feature Request] Support `sendFile`
Similar to express, it would be great for Hono to have a sendFile function to complement serveStatic. There's a lot of custom logic that goes into serving a static file (as evidence'd by the serveStatic function), but you don't always want to just serve a static directory with predetermined paths - in a lot of cases, you may want to dynamically figure out which file to send. It's easy to just read the file into memory and send it along, but it's better to be able to support ranges, mime types, etc. automatically.
I think this api would probably look like:
import { sendFile } from '@hono/node-server/send-file'
// ...
app.get("/my-path", (c) => {
// Can accept options similar to `serveStatic`
return sendFile(c, filePath, { ...options })
})
import type { Context, Env } from 'hono';
import { readFileSync} from 'node:fs';
import { serveStatic } from 'hono/serve-static';
type Data = string | ArrayBuffer | ReadableStream;
async function sendFile(path: string, c: Context<Env, any, object>):Promise<Data | Response | null>{
const fsPath: string = calcPath(path);
return existsSync(fsPath)
? readFileSync(fsPath).toString()
: c.text(`404 not find at ${fsPath}`, 404);
}
const app = new Hono();
app
.get('/other/*', serveStatic({ getContent :sendFile }));
Not considering high load or edge case , i has a simple function like this. Also can use stream / promises.
import type { ReadStream } from 'node:fs';
import { createReadStream, existsSync } from 'node:fs';
const createStreamBody = (stream: ReadStream) => {
const body = new ReadableStream({
start(controller): void {
stream.on('data', (chunk) => {
controller.enqueue(chunk);
});
stream.on('end', () => {
controller.close();
});
},
cancel(): void {
stream.destroy();
},
});
return body;
};
export const sendFileStream = async (path: string, c) => {
if (!existsSync(path)) {
return c.body('404 not find at ' + path, 404);
}
return createStreamBody(createReadStream(path));
};
sendFile with Stream , On my computer, it is normal to provide a 2~4 GiB file.