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)
This commit is contained in:
Aleksander Grygier
2026-10-02 13:50:20 +02:00
parent c172cb5cc5
commit 9f79a7a6d8
3 changed files with 17 additions and 5 deletions
+9 -5
View File
@@ -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<const char*>(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));
}
}
@@ -71,9 +71,12 @@
</span>
{:else}
<div class="rounded-md">
<!-- the server serves the app under COEP require-corp, so a cross-origin
image has to be fetched in CORS mode to be allowed -->
<img
alt=""
class="{size} rounded-md {invertAvatar ? 'dark:invert' : ''} {baseImageClass}"
crossorigin="anonymous"
loading="lazy"
onerror={() => {
failedAvatarOrgs.add(org);
@@ -101,6 +104,7 @@
<img
alt=""
class="{quantImageClass} rounded-full {invertQuant ? 'dark:invert' : ''}"
crossorigin="anonymous"
loading="lazy"
onerror={() => {
failedAvatarOrgs.add(quantOrg ?? '');
+4
View File
@@ -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,