From 9f79a7a6d83ed0cd62a859932b57fa5b40ab0fba Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Fri, 2 Oct 2026 13:50:20 +0200 Subject: [PATCH] server : keep serving the ui under cross-origin isolation The hub avatars are fetched in cors mode instead, which coep allows without dropping the isolation headers. Assisted-by: pi (deepseek-ai/DeepSeek-V4.1-Flash) --- tools/server/server-http.cpp | 14 +++++++++----- .../components/app/models/ModelOrgAvatar.svelte | 4 ++++ tools/ui/vite.config.ts | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/server/server-http.cpp b/tools/server/server-http.cpp index d6d2bfee40..33cbb156c5 100644 --- a/tools/server/server-http.cpp +++ b/tools/server/server-http.cpp @@ -404,8 +404,8 @@ bool server_http_context::init_listener(const common_params & params) { static constexpr auto cache_revalidate = "no-cache"; // Serves an asset with ETag/304 handling, under the given caching policy. - auto serve_asset_cached = [](const std::string & name, const char * cache_control) { - return [name, cache_control](const httplib::Request & req, httplib::Response & res) { + auto serve_asset_cached = [](const std::string & name, bool isolation, const char * cache_control) { + return [name, isolation, cache_control](const httplib::Request & req, httplib::Response & res) { if (!handle_gzip_header(req, res)) { return true; // returns error message } @@ -417,6 +417,10 @@ bool server_http_context::init_listener(const common_params & params) { res.status = 304; return false; } + if (isolation) { + res.set_header("Cross-Origin-Embedder-Policy", "require-corp"); + res.set_header("Cross-Origin-Opener-Policy", "same-origin"); + } res.set_header("Cache-Control", cache_control); res.set_content(reinterpret_cast(a->data), a->size, a->type.c_str()); return false; @@ -440,8 +444,8 @@ bool server_http_context::init_listener(const common_params & params) { }; // main index file -- revalidated, so a new build is picked up on the next load - srv->Get(params.api_prefix + "/", serve_asset_cached("index.html", cache_revalidate)); - srv->Get(params.api_prefix + "/index.html", serve_asset_cached("index.html", cache_revalidate)); + srv->Get(params.api_prefix + "/", serve_asset_cached("index.html", true, cache_revalidate)); + srv->Get(params.api_prefix + "/index.html", serve_asset_cached("index.html", true, cache_revalidate)); // All remaining assets registered directly from the embedded asset table. // PWA revalidation files (sw.js, manifest, version.json) use no-cache; @@ -459,7 +463,7 @@ bool server_http_context::init_listener(const common_params & params) { SRV_DBG("serve nocache for %s\n", a.name.c_str()); srv->Get(params.api_prefix + "/" + a.name, serve_asset_nocache(a.name)); } else { - srv->Get(params.api_prefix + "/" + a.name, serve_asset_cached(a.name, cache_immutable)); + srv->Get(params.api_prefix + "/" + a.name, serve_asset_cached(a.name, false, cache_immutable)); } } diff --git a/tools/ui/src/lib/components/app/models/ModelOrgAvatar.svelte b/tools/ui/src/lib/components/app/models/ModelOrgAvatar.svelte index b4a5799edc..cb5d427db2 100644 --- a/tools/ui/src/lib/components/app/models/ModelOrgAvatar.svelte +++ b/tools/ui/src/lib/components/app/models/ModelOrgAvatar.svelte @@ -71,9 +71,12 @@ {:else}
+ { failedAvatarOrgs.add(org); @@ -101,6 +104,7 @@ { failedAvatarOrgs.add(quantOrg ?? ''); diff --git a/tools/ui/vite.config.ts b/tools/ui/vite.config.ts index 9beb19bb4d..0f24a600bf 100644 --- a/tools/ui/vite.config.ts +++ b/tools/ui/vite.config.ts @@ -55,6 +55,10 @@ export default defineConfig(({ mode }) => { fs: { allow: [searchForWorkspaceRoot(process.cwd()), resolve(__dirname, 'tests')] }, + headers: { + 'Cross-Origin-Embedder-Policy': 'require-corp', + 'Cross-Origin-Opener-Policy': 'same-origin' + }, proxy: { '/cors-proxy': SERVER_ORIGIN, '/models': SERVER_ORIGIN,