mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:30:43 +00:00
Make immutable asset cache headers explicit
This commit is contained in:
+93
@@ -17,6 +17,99 @@ server {
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
location ^~ /assets/ {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_cache STATIC;
|
||||
proxy_cache_valid 200 302 24h;
|
||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||
proxy_cache_lock on;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ^~ /_assets/ {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_cache STATIC;
|
||||
proxy_cache_valid 200 302 24h;
|
||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||
proxy_cache_lock on;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location ~* ^/w(\d+)(/(?:assets|_assets)/.*)$ {
|
||||
set $worker $1;
|
||||
set $worker_port 3001;
|
||||
|
||||
if ($worker = "0") { set $worker_port 3001; }
|
||||
if ($worker = "1") { set $worker_port 3002; }
|
||||
if ($worker = "2") { set $worker_port 3003; }
|
||||
if ($worker = "3") { set $worker_port 3004; }
|
||||
if ($worker = "4") { set $worker_port 3005; }
|
||||
if ($worker = "5") { set $worker_port 3006; }
|
||||
if ($worker = "6") { set $worker_port 3007; }
|
||||
if ($worker = "7") { set $worker_port 3008; }
|
||||
if ($worker = "8") { set $worker_port 3009; }
|
||||
if ($worker = "9") { set $worker_port 3010; }
|
||||
if ($worker = "10") { set $worker_port 3011; }
|
||||
if ($worker = "11") { set $worker_port 3012; }
|
||||
if ($worker = "12") { set $worker_port 3013; }
|
||||
if ($worker = "13") { set $worker_port 3014; }
|
||||
if ($worker = "14") { set $worker_port 3015; }
|
||||
if ($worker = "15") { set $worker_port 3016; }
|
||||
if ($worker = "16") { set $worker_port 3017; }
|
||||
if ($worker = "17") { set $worker_port 3018; }
|
||||
if ($worker = "18") { set $worker_port 3019; }
|
||||
if ($worker = "19") { set $worker_port 3020; }
|
||||
if ($worker = "20") { set $worker_port 3021; }
|
||||
if ($worker = "21") { set $worker_port 3022; }
|
||||
if ($worker = "22") { set $worker_port 3023; }
|
||||
if ($worker = "23") { set $worker_port 3024; }
|
||||
if ($worker = "24") { set $worker_port 3025; }
|
||||
if ($worker = "25") { set $worker_port 3026; }
|
||||
if ($worker = "26") { set $worker_port 3027; }
|
||||
if ($worker = "27") { set $worker_port 3028; }
|
||||
if ($worker = "28") { set $worker_port 3029; }
|
||||
if ($worker = "29") { set $worker_port 3030; }
|
||||
if ($worker = "30") { set $worker_port 3031; }
|
||||
if ($worker = "31") { set $worker_port 3032; }
|
||||
if ($worker = "32") { set $worker_port 3033; }
|
||||
if ($worker = "33") { set $worker_port 3034; }
|
||||
if ($worker = "34") { set $worker_port 3035; }
|
||||
if ($worker = "35") { set $worker_port 3036; }
|
||||
if ($worker = "36") { set $worker_port 3037; }
|
||||
if ($worker = "37") { set $worker_port 3038; }
|
||||
if ($worker = "38") { set $worker_port 3039; }
|
||||
if ($worker = "39") { set $worker_port 3040; }
|
||||
if ($worker = "40") { set $worker_port 3041; }
|
||||
|
||||
proxy_pass http://127.0.0.1:$worker_port$2$is_args$args;
|
||||
proxy_cache STATIC;
|
||||
proxy_cache_valid 200 302 24h;
|
||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||
proxy_cache_lock on;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Worker locations - Processing this first so worker-specific requests are handled by workers
|
||||
# This prevents static file regexes from capturing worker requests
|
||||
location ~* ^/w(\d+)(/.*)?$ {
|
||||
|
||||
+6
-10
@@ -11,6 +11,7 @@ import { logger } from "./Logger";
|
||||
import { MapPlaylist } from "./MapPlaylist";
|
||||
import { MasterLobbyService } from "./MasterLobbyService";
|
||||
import { renderHtml } from "./RenderHtml";
|
||||
import { applyStaticAssetCacheControl } from "./StaticAssetCache";
|
||||
|
||||
const config = getServerConfigFromServer();
|
||||
const playlist = new MapPlaylist();
|
||||
@@ -43,16 +44,11 @@ app.use(async (req, res, next) => {
|
||||
app.use(
|
||||
express.static(path.join(__dirname, "../../static"), {
|
||||
maxAge: "1y", // Set max-age to 1 year for all static assets
|
||||
setHeaders: (res, path) => {
|
||||
// You can conditionally set different cache times based on file types
|
||||
if (path.match(/\.(js|css|svg)$/)) {
|
||||
// JS, CSS, SVG get long cache with immutable
|
||||
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
||||
} else if (path.match(/\.(bin|dat|exe|dll|so|dylib)$/)) {
|
||||
// Binary files also get long cache with immutable
|
||||
res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
|
||||
}
|
||||
// Other file types use the default maxAge setting
|
||||
setHeaders: (res) => {
|
||||
applyStaticAssetCacheControl(
|
||||
res.setHeader.bind(res),
|
||||
res.req.originalUrl,
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
const IMMUTABLE_CACHE_CONTROL = "public, max-age=31536000, immutable";
|
||||
|
||||
function stripQueryString(urlPath: string): string {
|
||||
return urlPath.split("?", 1)[0];
|
||||
}
|
||||
|
||||
export function getStaticAssetCacheControl(
|
||||
urlPath: string | undefined,
|
||||
): string | undefined {
|
||||
if (!urlPath) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const normalizedPath = stripQueryString(urlPath);
|
||||
if (
|
||||
normalizedPath.startsWith("/assets/") ||
|
||||
normalizedPath.startsWith("/_assets/")
|
||||
) {
|
||||
return IMMUTABLE_CACHE_CONTROL;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function applyStaticAssetCacheControl(
|
||||
setHeader: (name: string, value: string) => void,
|
||||
urlPath: string | undefined,
|
||||
): void {
|
||||
const cacheControl = getStaticAssetCacheControl(urlPath);
|
||||
if (cacheControl) {
|
||||
setHeader("Cache-Control", cacheControl);
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -29,6 +29,7 @@ import { GameEnv } from "../core/configuration/Config";
|
||||
import { MapPlaylist } from "./MapPlaylist";
|
||||
import { startPolling } from "./PollingLoop";
|
||||
import { PrivilegeRefresher } from "./PrivilegeRefresher";
|
||||
import { applyStaticAssetCacheControl } from "./StaticAssetCache";
|
||||
import { verifyTurnstileToken } from "./Turnstile";
|
||||
import { WorkerLobbyService } from "./WorkerLobbyService";
|
||||
import { initWorkerMetrics } from "./WorkerMetrics";
|
||||
@@ -110,7 +111,16 @@ export async function startWorker() {
|
||||
// Configure MIME types for webp files
|
||||
express.static.mime.define({ "image/webp": ["webp"] });
|
||||
|
||||
app.use(express.static(path.join(__dirname, "../../out")));
|
||||
app.use(
|
||||
express.static(path.join(__dirname, "../../out"), {
|
||||
setHeaders: (res) => {
|
||||
applyStaticAssetCacheControl(
|
||||
res.setHeader.bind(res),
|
||||
res.req.originalUrl,
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
app.use(
|
||||
"/maps",
|
||||
express.static(path.join(__dirname, "../../static/maps"), {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { getStaticAssetCacheControl } from "../../src/server/StaticAssetCache";
|
||||
|
||||
describe("StaticAssetCache", () => {
|
||||
test("marks Vite asset namespace as immutable", () => {
|
||||
expect(getStaticAssetCacheControl("/assets/index-abc123.js")).toBe(
|
||||
"public, max-age=31536000, immutable",
|
||||
);
|
||||
});
|
||||
|
||||
test("marks custom hashed asset namespace as immutable", () => {
|
||||
expect(
|
||||
getStaticAssetCacheControl("/_assets/maps/world/manifest.hash.json"),
|
||||
).toBe("public, max-age=31536000, immutable");
|
||||
});
|
||||
|
||||
test("does not mark other paths as immutable", () => {
|
||||
expect(getStaticAssetCacheControl("/manifest.json")).toBeUndefined();
|
||||
expect(getStaticAssetCacheControl("/api/health")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user