mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 20:49:53 +08:00
fix(mcp-server): review fixes for the preview token and the draw.io static files
- The preview page fetches a fresh copy of itself and retries once when an API request is refused with 403: another MCP process, with its own token, now answers on this port, and the recovery logic (recoverState) needs its polls to go through. The page is sent with Cache-Control: no-store. - draw.io files are served with an ETag and Cache-Control: no-cache instead of a 24 hour max-age: their names do not change between versions, so a package upgrade must reach the browser on the next preview. HEAD and If-None-Match (304) are answered. - The file read stream goes through stream.pipeline, so a read error no longer ends the MCP process and a client that leaves mid-download no longer leaks the file handle.
This commit is contained in:
@@ -87,7 +87,7 @@
|
||||
const sessionId = {{SESSION_JSON}};
|
||||
// Empty when draw.io is served from this origin
|
||||
const DRAWIO_ORIGIN = {{ORIGIN_JSON}} || location.origin;
|
||||
const API_TOKEN = {{TOKEN_JSON}};
|
||||
let API_TOKEN = {{TOKEN_JSON}};
|
||||
</script>
|
||||
<script>
|
||||
{{SCRIPT}}
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
const iframe = document.getElementById('drawio');
|
||||
// Every API request carries the token the server wrote into this page
|
||||
const api = (url, init = {}) => fetch(url, { ...init, headers: { ...(init.headers || {}), 'X-Drawio-Token': API_TOKEN } });
|
||||
// Every API request carries the token the server wrote into this page. A 403
|
||||
// means another MCP process (with its own token) now answers on this port:
|
||||
// read its token from a fresh copy of this page and retry once, so the next
|
||||
// poll can recover the session instead of being refused forever.
|
||||
let tokenRefresh = null;
|
||||
function refreshToken() {
|
||||
if (!tokenRefresh) {
|
||||
tokenRefresh = fetch(location.href, { cache: 'no-store' })
|
||||
.then((r) => r.text())
|
||||
.then((html) => { const m = html.match(/API_TOKEN = "([0-9a-f]+)"/); if (m) API_TOKEN = m[1]; })
|
||||
.catch(() => {})
|
||||
.finally(() => { tokenRefresh = null; });
|
||||
}
|
||||
return tokenRefresh;
|
||||
}
|
||||
async function api(url, init = {}) {
|
||||
const send = () => fetch(url, { ...init, headers: { ...(init.headers || {}), 'X-Drawio-Token': API_TOKEN } });
|
||||
let r = await send();
|
||||
if (r.status === 403) { await refreshToken(); r = await send(); }
|
||||
return r;
|
||||
}
|
||||
let currentVersion = 0, isReady = false, pendingXml = null, lastXml = null;
|
||||
// The server state this tab is in step with (see stateId in http-server.ts);
|
||||
// null until the first poll
|
||||
|
||||
Reference in New Issue
Block a user