

6 changed files with 80 additions and 0 deletions
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
import { server } from "./tests/proxy-server/index.mjs" |
||||
|
||||
export default function () { |
||||
server.listen(8080) |
||||
} |
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
import { server } from "./tests/proxy-server/index.mjs" |
||||
|
||||
export default () => { |
||||
server.close() |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
// @ts-check
|
||||
|
||||
import { createServer } from "node:http" |
||||
import path from "node:path" |
||||
import fs from "node:fs" |
||||
import crypto from "node:crypto" |
||||
import fetch from "node-fetch" |
||||
import chalk from "chalk" |
||||
|
||||
const baseDir = path.join(process.cwd(), ".proxy") |
||||
try { |
||||
fs.mkdirSync(baseDir, { recursive: true }) |
||||
} catch (e) {} |
||||
|
||||
/** @type {Map<string, Promise<{ headers: Record<string, string>, body: ArrayBuffer }>>} */ |
||||
const cache = new Map() |
||||
|
||||
export const server = createServer((req, res) => { |
||||
const pathname = req.url ?? "/" |
||||
const hash = crypto |
||||
.createHash("sha1") |
||||
.update(pathname ?? "/") |
||||
.digest("hex") |
||||
const extension = path.extname(pathname) |
||||
const filename = path.join(baseDir, hash) + extension |
||||
const headersFilename = path.join(baseDir, hash) + ".headers.json" |
||||
try { |
||||
const headers = JSON.parse(fs.readFileSync(headersFilename, "utf-8")) |
||||
const body = fs.createReadStream(filename) |
||||
console.log(chalk.green.dim(`[proxy] hit: ${pathname} -> ${filename}`)) |
||||
res.writeHead(200, headers) |
||||
body.pipe(res) |
||||
} catch { |
||||
let promise = cache.get(filename) |
||||
if (!promise) { |
||||
console.log(chalk.red.dim(`[proxy] miss: ${pathname} -> ${filename}`)) |
||||
promise = fetch( |
||||
"https://nodejs.org/dist/" + pathname.replace(/^\/+/, ""), |
||||
{ |
||||
compress: false, |
||||
} |
||||
).then(async (response) => { |
||||
const headers = Object.fromEntries(response.headers.entries()) |
||||
const body = await response.arrayBuffer() |
||||
fs.writeFileSync(headersFilename, JSON.stringify(headers)) |
||||
fs.writeFileSync(filename, Buffer.from(body)) |
||||
return { headers, body } |
||||
}) |
||||
cache.set(filename, promise) |
||||
promise.finally(() => cache.delete(filename)) |
||||
} |
||||
|
||||
promise.then( |
||||
({ headers, body }) => { |
||||
res.writeHead(200, headers) |
||||
res.end(Buffer.from(body)) |
||||
}, |
||||
(err) => { |
||||
console.error(err) |
||||
res.writeHead(500) |
||||
res.end() |
||||
} |
||||
) |
||||
} |
||||
}) |
Loading…
Reference in new issue