hive-gateway: route dashboard by path, not Accept header
The dashboard vhost split static-vs-backend on the request Accept header (map $http_accept $dashboard_spa_target), so the same URL behaved differently by content-type — e.g. /api/state fetched with Accept: text/html wrongly returned index.html. Now that all hive-c0re routes live under /api/ plus the single /webhook/knowledge endpoint, route by path instead: /api/ and /webhook/ proxy to c0re (SSE settings on /api/), everything else serves the dist with try_files $uri /index.html. Drops the dashboard Accept-header map and the @c0re named location. Updates docs/gateway.md accordingly.
This commit is contained in:
parent
5ae5657ca4
commit
d4f106d590
2 changed files with 38 additions and 27 deletions
|
|
@ -747,8 +747,9 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
# Shared auth block — named locations don't inherit auth_basic, so
|
||||
# both `/` and `@c0re` need it or the proxied surface is unauthed.
|
||||
# Shared auth block — separate locations don't inherit auth_basic, so
|
||||
# each dashboard location (`/`, `/api/`, `/webhook/`) needs it or that
|
||||
# surface is unauthed.
|
||||
dashboardAuth = lib.optionalString cfg.auth.enable ''
|
||||
auth_basic "${cfg.auth.realm}";
|
||||
auth_basic_user_file /run/hive-state/gateway.htpasswd;
|
||||
|
|
@ -757,30 +758,39 @@ in
|
|||
error_page 401 =401 /__hive_auth_unauthorized;
|
||||
'';
|
||||
|
||||
# Dashboard: nginx static-serves the dist, c0re is API-only. The
|
||||
# Accept-header map splits without enumerating routes — html
|
||||
# navigations → SPA index.html, everything else (API/SSE/actions/
|
||||
# webhook) → @c0re. Replaces the old `location / { proxy_pass c0re }`
|
||||
# that made c0re ServeDir the dist (and restart on every frontend
|
||||
# change). New c0re routes need no gateway change.
|
||||
# Dashboard: nginx static-serves the dist, c0re is API-only. Routing
|
||||
# is by PATH, never content-type. c0re serves exactly two prefixes —
|
||||
# `/api/` (all dashboard data + actions + the SSE streams) and
|
||||
# `/webhook/` (the knowledge webhook) — so those proxy to c0re and
|
||||
# everything else serves the dist with an SPA fallback to index.html.
|
||||
# The earlier `map $http_accept` Accept-header split made the SAME
|
||||
# url behave differently by content-type (e.g. `/api/state` fetched
|
||||
# with `Accept: text/html` wrongly got index.html); path routing is
|
||||
# deterministic. A new top-level c0re route prefix (beyond /api +
|
||||
# /webhook) would need a matching location added here.
|
||||
dashboardProxyLocation = {
|
||||
"/" = {
|
||||
root = dashboardDist;
|
||||
extraConfig = ''
|
||||
try_files $uri $dashboard_spa_target @c0re;
|
||||
try_files $uri /index.html;
|
||||
${dashboardAuth}
|
||||
'';
|
||||
};
|
||||
"@c0re" = {
|
||||
"/api/" = {
|
||||
proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
# off + 1d keep the SSE streams live.
|
||||
# off + 1d keep the SSE streams (/api/dashboard/stream,
|
||||
# /api/build-logs/id/{id}/stream) live.
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 1d;
|
||||
${dashboardAuth}
|
||||
'';
|
||||
};
|
||||
"/webhook/" = {
|
||||
proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}";
|
||||
extraConfig = dashboardAuth;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
|
|
@ -862,17 +872,11 @@ in
|
|||
recommendedTlsSettings = true;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
# Accept-header SPA maps (see docs/gateway.md "SPA fallback"):
|
||||
# text/html → index.html, else a sentinel so try_files falls
|
||||
# through (dashboard → @c0re, matrix → 404). Dashboard map is
|
||||
# unconditional; matrix map only with the matrix GUI.
|
||||
appendHttpConfig = ''
|
||||
map $http_accept $dashboard_spa_target {
|
||||
default "/__dashboard_no_html_fallback";
|
||||
"~*text/html" "/index.html";
|
||||
}
|
||||
''
|
||||
+ lib.optionalString (matrixCfg.enable && matrixCfg.gui.enable) ''
|
||||
# Accept-header SPA map for the matrix GUI only (see docs/gateway.md
|
||||
# "SPA fallback"): text/html → index.html, else a sentinel so
|
||||
# try_files falls through to 404. The dashboard no longer uses an
|
||||
# Accept-header map — it routes by path (see dashboardProxyLocation).
|
||||
appendHttpConfig = lib.optionalString (matrixCfg.enable && matrixCfg.gui.enable) ''
|
||||
map $http_accept $matrix_spa_target {
|
||||
default "/__matrix_spa_no_html_fallback";
|
||||
"~*text/html" "/index.html";
|
||||
|
|
|
|||
Loading…
Reference in a new issue