fix brotli cache
This commit is contained in:
+37
-21
@@ -1,7 +1,6 @@
|
||||
import brotliPromise from "brotli-wasm"; // Import the default export
|
||||
import { simpleHash } from "utils/cache";
|
||||
import { g } from "utils/global";
|
||||
const brotli = await brotliPromise;
|
||||
import { loadCachedBr } from "utils/br-load";
|
||||
|
||||
const parseQueryParams = (ctx: any) => {
|
||||
const pageHref = ctx.req.url;
|
||||
@@ -29,7 +28,7 @@ export const apiContext = (ctx: any) => {
|
||||
res: {
|
||||
...ctx.res,
|
||||
send: (body, cache_accept?: string) => {
|
||||
ctx.res = createResponse(ctx.res, body, cache_accept);
|
||||
ctx.res = createResponse(body, { cache_accept, res: ctx.res });
|
||||
},
|
||||
sendStatus: (code: number) => {
|
||||
ctx.res._status = code;
|
||||
@@ -50,30 +49,45 @@ export const apiContext = (ctx: any) => {
|
||||
};
|
||||
|
||||
export const createResponse = (
|
||||
existingRes: any,
|
||||
body: any,
|
||||
cache_accept?: string
|
||||
opt?: {
|
||||
cache_accept?: string;
|
||||
headers?: any;
|
||||
res?: any;
|
||||
}
|
||||
) => {
|
||||
const status =
|
||||
typeof existingRes._status === "number" ? existingRes._status : undefined;
|
||||
typeof opt?.res?._status === "number" ? opt?.res?._status : undefined;
|
||||
|
||||
let content: any = typeof body === "string" ? body : JSON.stringify(body);
|
||||
const headers = {} as Record<string, string>;
|
||||
if (cache_accept) {
|
||||
if (g.mode === "prod" && cache_accept.toLowerCase().includes("br")) {
|
||||
const headers = { ...(opt?.headers || {}) } as Record<string, string>;
|
||||
if (opt?.cache_accept) {
|
||||
let cached = false;
|
||||
if (opt.cache_accept.toLowerCase().includes("br")) {
|
||||
const content_hash = simpleHash(content);
|
||||
|
||||
if (!g.cache.br[content_hash]) {
|
||||
loadCachedBr(content_hash, content);
|
||||
}
|
||||
|
||||
if (g.cache.br[content_hash]) {
|
||||
cached = true;
|
||||
content = g.cache.br[content_hash];
|
||||
headers["content-encoding"] = "br";
|
||||
} else {
|
||||
if (!g.cache.br_timeout.has(content_hash)) {
|
||||
g.cache.br_timeout.add(content_hash);
|
||||
setTimeout(() => {
|
||||
g.cache.br[content_hash] = brotli.compress(Buffer.from(content));
|
||||
g.cache.br_timeout.delete(content_hash);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cached && opt.cache_accept.toLowerCase().includes("gz")) {
|
||||
const content_hash = simpleHash(content);
|
||||
|
||||
if (!g.cache.gz[content_hash]) {
|
||||
g.cache.gz[content_hash] = Bun.gzipSync(content);
|
||||
}
|
||||
|
||||
if (g.cache.gz[content_hash]) {
|
||||
cached = true;
|
||||
content = g.cache.gz[content_hash];
|
||||
headers["content-encoding"] = "gzip";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,10 +104,12 @@ export const createResponse = (
|
||||
for (const [k, v] of Object.entries(headers)) {
|
||||
res.headers.append(k, v);
|
||||
}
|
||||
const cur = existingRes as Response;
|
||||
cur.headers.forEach((value, key) => {
|
||||
res.headers.append(key, value);
|
||||
});
|
||||
const cur = opt?.res as Response;
|
||||
if (cur) {
|
||||
cur.headers.forEach((value, key) => {
|
||||
res.headers.append(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof body === "object" && !res.headers.has("content-type")) {
|
||||
res.headers.append("content-type", "application/json");
|
||||
|
||||
+17
-6
@@ -14,7 +14,12 @@ export const createServer = async () => {
|
||||
g.api = {};
|
||||
g.cache = {
|
||||
br: {},
|
||||
br_timeout: new Set(),
|
||||
gz: {},
|
||||
br_progress: {
|
||||
pending: {},
|
||||
running: false,
|
||||
timeout: null,
|
||||
},
|
||||
};
|
||||
const scan = async (path: string, root?: string) => {
|
||||
const apis = await listAsync(path);
|
||||
@@ -71,7 +76,7 @@ export const createServer = async () => {
|
||||
maxRequestBodySize: 1024 * 1024 * 128,
|
||||
async fetch(req) {
|
||||
const url = new URL(req.url) as URL;
|
||||
url.pathname = url.pathname.replace(/\/+/g, '/')
|
||||
url.pathname = url.pathname.replace(/\/+/g, "/");
|
||||
|
||||
const prasi = {};
|
||||
const index = prodIndex(g.deploy.config.site_id, prasi);
|
||||
@@ -89,12 +94,13 @@ export const createServer = async () => {
|
||||
return await serveWeb({
|
||||
content: index.render(),
|
||||
pathname: "index.html",
|
||||
cache_accept: req.headers.get("accept-encoding") || "",
|
||||
});
|
||||
}
|
||||
|
||||
if (g.deploy.gz) {
|
||||
const core = g.deploy.gz.code.core;
|
||||
const site = g.deploy.gz.code.site;
|
||||
if (g.deploy.content) {
|
||||
const core = g.deploy.content.code.core;
|
||||
const site = g.deploy.content.code.site;
|
||||
|
||||
let pathname = url.pathname;
|
||||
if (url.pathname[0] === "/") pathname = pathname.substring(1);
|
||||
@@ -107,6 +113,7 @@ export const createServer = async () => {
|
||||
return await serveWeb({
|
||||
content: index.render(),
|
||||
pathname: "index.html",
|
||||
cache_accept: req.headers.get("accept-encoding") || "",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -116,7 +123,11 @@ export const createServer = async () => {
|
||||
else if (site[pathname]) content = site[pathname];
|
||||
|
||||
if (content) {
|
||||
return await serveWeb({ content, pathname });
|
||||
return await serveWeb({
|
||||
content,
|
||||
pathname,
|
||||
cache_accept: req.headers.get("accept-encoding") || "",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export const serveAPI = async (url: URL, req: Request) => {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const [k, v] of Object.entries(json)) {
|
||||
for (const [k, v] of Object.entries(json as object)) {
|
||||
params[k] = v;
|
||||
}
|
||||
for (const [k, v] of Object.entries(params)) {
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import mime from "mime";
|
||||
import { createResponse } from "service-srv";
|
||||
|
||||
export const serveWeb = async (arg: { pathname: string; content: string }) => {
|
||||
export const serveWeb = async (arg: {
|
||||
pathname: string;
|
||||
content: string;
|
||||
cache_accept: string;
|
||||
}) => {
|
||||
const type = mime.getType(arg.pathname);
|
||||
|
||||
return new Response(arg.content, {
|
||||
return createResponse(arg.content, {
|
||||
cache_accept: arg.cache_accept,
|
||||
headers: !type ? undefined : { "content-type": type },
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user