Blame Raw
· · · 40 lines (1.4 KB)
0 contributors
1import fs from 'node:fs';
2import path from 'node:path';
3import { fileURLToPath } from 'node:url';
4import mime from 'mime-types';
5import { serverDirectory } from './server-directory.js';
6import { getRequestURL, isFileURL, isPathUnderParent } from './util.js';
7
8const originalFetch = globalThis.fetch;
9
10const ALLOWED_EXTENSIONS = [
11 '.wasm',
12];
13
14// Patched fetch function that handles file URLs
15globalThis.fetch = async (/** @type {string | URL | Request} */ request, /** @type {RequestInit | undefined} */ options) => {
16 if (!isFileURL(request)) {
17 return originalFetch(request, options);
18 }
19 const url = getRequestURL(request);
20 const filePath = path.resolve(fileURLToPath(url));
21 const isUnderServerDirectory = isPathUnderParent(serverDirectory, filePath);
22 if (!isUnderServerDirectory) {
23 throw new Error('Requested file path is outside of the server directory.');
24 }
25 const parsedPath = path.parse(filePath);
26 if (!ALLOWED_EXTENSIONS.includes(parsedPath.ext)) {
27 throw new Error('Unsupported file extension.');
28 }
29 const fileName = parsedPath.base;
30 const buffer = await fs.promises.readFile(filePath);
31 const response = new Response(buffer, {
32 status: 200,
33 statusText: 'OK',
34 headers: {
35 'Content-Type': mime.lookup(fileName) || 'application/octet-stream',
36 'Content-Length': buffer.length.toString(),
37 },
38 });
39 return response;
40};