mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:50:42 +00:00
Remove env endpoint and mark live APIs no-store
This commit is contained in:
-19
@@ -195,25 +195,6 @@ server {
|
||||
add_header Cache-Control "public, max-age=86400"; # 24 hours
|
||||
}
|
||||
|
||||
# /api/env endpoint - Cache for 1 hour
|
||||
location = /api/env {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
# Cache configuration
|
||||
proxy_cache API_CACHE;
|
||||
proxy_cache_valid 200 1h; # Cache successful responses for 1 hour
|
||||
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
|
||||
proxy_cache_lock on;
|
||||
add_header X-Cache-Status $upstream_cache_status;
|
||||
|
||||
# Standard proxy headers
|
||||
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;
|
||||
}
|
||||
|
||||
# /api/health endpoint - No caching, always hit the backend
|
||||
location = /api/health {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
|
||||
@@ -40,20 +40,11 @@ export async function getServerConfigFromClient(): Promise<ServerConfig> {
|
||||
}
|
||||
|
||||
const bootstrapGameEnv = window.BOOTSTRAP_CONFIG?.gameEnv;
|
||||
if (bootstrapGameEnv) {
|
||||
cachedSC = getServerConfig(bootstrapGameEnv);
|
||||
return cachedSC;
|
||||
if (!bootstrapGameEnv) {
|
||||
throw new Error("Missing bootstrap server config");
|
||||
}
|
||||
|
||||
const response = await fetch("/api/env");
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch server config: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
const config = await response.json();
|
||||
|
||||
cachedSC = getServerConfig(config.game_env);
|
||||
cachedSC = getServerConfig(bootstrapGameEnv);
|
||||
return cachedSC;
|
||||
}
|
||||
export function getServerConfigFromServer(): ServerConfig {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
ExternalGameInfo,
|
||||
ExternalGameInfoSchema,
|
||||
} from "./GamePreviewBuilder";
|
||||
import { setNoStoreHeaders } from "./NoStoreHeaders";
|
||||
import { renderHtmlContent, setHtmlNoCacheHeaders } from "./RenderHtml";
|
||||
|
||||
const requestOrigin = (req: Request, config: ServerConfig): string => {
|
||||
@@ -151,6 +152,7 @@ export function registerGamePreviewRoute(opts: {
|
||||
}
|
||||
|
||||
// Fallback to JSON if HTML file not found
|
||||
setNoStoreHeaders(res);
|
||||
res.setHeader("Content-Type", "application/json");
|
||||
return res.send(JSON.stringify(lobby ?? publicInfo, replacer));
|
||||
} catch (error) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
|
||||
import { logger } from "./Logger";
|
||||
import { MapPlaylist } from "./MapPlaylist";
|
||||
import { MasterLobbyService } from "./MasterLobbyService";
|
||||
import { setNoStoreHeaders } from "./NoStoreHeaders";
|
||||
import { renderHtml } from "./RenderHtml";
|
||||
import { applyStaticAssetCacheControl } from "./StaticAssetCache";
|
||||
|
||||
@@ -61,6 +62,11 @@ app.use(
|
||||
}),
|
||||
);
|
||||
|
||||
app.use("/api", (_req, res, next) => {
|
||||
setNoStoreHeaders(res);
|
||||
next();
|
||||
});
|
||||
|
||||
// Start the master process
|
||||
export async function startMaster() {
|
||||
if (!cluster.isPrimary) {
|
||||
@@ -133,14 +139,6 @@ export async function startMaster() {
|
||||
});
|
||||
}
|
||||
|
||||
app.get("/api/env", async (req, res) => {
|
||||
const envConfig = {
|
||||
game_env: process.env.GAME_ENV,
|
||||
};
|
||||
if (!envConfig.game_env) return res.sendStatus(500);
|
||||
res.json(envConfig);
|
||||
});
|
||||
|
||||
app.get("/api/health", (_req, res) => {
|
||||
const ready = lobbyService?.isHealthy() ?? false;
|
||||
if (ready) {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Response } from "express";
|
||||
|
||||
export function setNoStoreHeaders(res: Response): void {
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
"no-store, no-cache, must-revalidate, proxy-revalidate",
|
||||
);
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
res.setHeader("Expires", "0");
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import ejs from "ejs";
|
||||
import type { Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import { buildAssetUrl } from "../core/AssetUrls";
|
||||
import { setNoStoreHeaders } from "./NoStoreHeaders";
|
||||
import { getRuntimeAssetManifest } from "./RuntimeAssetManifest";
|
||||
|
||||
export async function renderHtmlContent(htmlPath: string): Promise<string> {
|
||||
@@ -25,12 +26,7 @@ export async function renderHtmlContent(htmlPath: string): Promise<string> {
|
||||
}
|
||||
|
||||
export function setHtmlNoCacheHeaders(res: Response): void {
|
||||
res.setHeader(
|
||||
"Cache-Control",
|
||||
"no-store, no-cache, must-revalidate, proxy-revalidate",
|
||||
);
|
||||
res.setHeader("Pragma", "no-cache");
|
||||
res.setHeader("Expires", "0");
|
||||
setNoStoreHeaders(res);
|
||||
res.setHeader("ETag", "");
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import { logger } from "./Logger";
|
||||
|
||||
import { GameEnv } from "../core/configuration/Config";
|
||||
import { MapPlaylist } from "./MapPlaylist";
|
||||
import { setNoStoreHeaders } from "./NoStoreHeaders";
|
||||
import { startPolling } from "./PollingLoop";
|
||||
import { PrivilegeRefresher } from "./PrivilegeRefresher";
|
||||
import { applyStaticAssetCacheControl } from "./StaticAssetCache";
|
||||
@@ -139,6 +140,11 @@ export async function startWorker() {
|
||||
}),
|
||||
);
|
||||
|
||||
app.use("/api", (_req, res, next) => {
|
||||
setNoStoreHeaders(res);
|
||||
next();
|
||||
});
|
||||
|
||||
app.post("/api/create_game/:id", async (req, res) => {
|
||||
const id = req.params.id;
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { setNoStoreHeaders } from "../../src/server/NoStoreHeaders";
|
||||
|
||||
describe("NoStoreHeaders", () => {
|
||||
test("sets explicit no-store headers", () => {
|
||||
const headers = new Map<string, string>();
|
||||
const response = {
|
||||
setHeader(name: string, value: string) {
|
||||
headers.set(name, value);
|
||||
},
|
||||
} as any;
|
||||
|
||||
setNoStoreHeaders(response);
|
||||
|
||||
expect(headers.get("Cache-Control")).toBe(
|
||||
"no-store, no-cache, must-revalidate, proxy-revalidate",
|
||||
);
|
||||
expect(headers.get("Pragma")).toBe("no-cache");
|
||||
expect(headers.get("Expires")).toBe("0");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user