fix(nginx): route /api/peer-content/* to the backend for B3 streaming
The B3 streaming proxy endpoint existed in the backend but nginx had no location for /api/peer-content/*, so the browser's requests fell through to the SPA (200 text/html) and media still wouldn't play. Add an NGINX_PEER_CONTENT_BLOCK that bootstrap patches into every server block (forwards Cookie for session auth + Range, proxy_buffering off). Idempotent; covers fresh-ISO nodes too since bootstrap runs on every startup. Verified on .198: after restart the async nginx patch lands and /api/peer-content/<onion>/<id> returns 401 (reaches backend, auth-gated) instead of the SPA; nginx block present in both server blocks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5c8707432b
commit
602b9cd3df
@ -48,6 +48,14 @@ const NGINX_BITCOIN_STATUS_BLOCK: &str = "\n location /bitcoin-status {\n
|
|||||||
/// sync with the canonical block in image-recipe/configs/nginx-archipelago.conf.
|
/// sync with the canonical block in image-recipe/configs/nginx-archipelago.conf.
|
||||||
const NGINX_LND_PROXY_BLOCK: &str = "\n # LND REST proxy — backend handles auth + CORS\n location /proxy/lnd/ {\n proxy_pass http://127.0.0.1:5678;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header Cookie $http_cookie;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_connect_timeout 10s;\n proxy_read_timeout 10s;\n proxy_send_timeout 5s;\n error_page 502 503 = @backend_unavailable;\n error_page 504 = @backend_timeout;\n }\n";
|
const NGINX_LND_PROXY_BLOCK: &str = "\n # LND REST proxy — backend handles auth + CORS\n location /proxy/lnd/ {\n proxy_pass http://127.0.0.1:5678;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header Cookie $http_cookie;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_connect_timeout 10s;\n proxy_read_timeout 10s;\n proxy_send_timeout 5s;\n error_page 502 503 = @backend_unavailable;\n error_page 504 = @backend_timeout;\n }\n";
|
||||||
|
|
||||||
|
/// Inserted into every server block lacking the peer-content streaming proxy.
|
||||||
|
/// Without it, the browser's `<video>`/`<audio>` Range requests to
|
||||||
|
/// `/api/peer-content/*` fall through to the SPA index.html (HTML, no Range)
|
||||||
|
/// and peer media won't play (B3). Forwards Cookie (session auth) + Range and
|
||||||
|
/// disables buffering so streaming works. Kept in sync with the canonical
|
||||||
|
/// block in image-recipe/configs/nginx-archipelago.conf.
|
||||||
|
const NGINX_PEER_CONTENT_BLOCK: &str = "\n # Peer content streaming proxy (B3) — Range-streams a peer's media file\n location /api/peer-content/ {\n proxy_pass http://127.0.0.1:5678;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header Cookie $http_cookie;\n proxy_set_header Range $http_range;\n proxy_buffering off;\n proxy_connect_timeout 10s;\n proxy_read_timeout 120s;\n error_page 502 503 = @backend_unavailable;\n error_page 504 = @backend_timeout;\n }\n";
|
||||||
|
|
||||||
/// Entry point called from main startup. Never returns an error to the caller —
|
/// Entry point called from main startup. Never returns an error to the caller —
|
||||||
/// failing to bootstrap host artifacts must not prevent the backend from serving.
|
/// failing to bootstrap host artifacts must not prevent the backend from serving.
|
||||||
pub async fn ensure_doctor_installed() {
|
pub async fn ensure_doctor_installed() {
|
||||||
@ -536,8 +544,14 @@ async fn patch_nginx_conf(path: &str) -> Result<bool> {
|
|||||||
let missing_app_catalog = !content.contains("location /api/app-catalog");
|
let missing_app_catalog = !content.contains("location /api/app-catalog");
|
||||||
let missing_bitcoin_status = !content.contains("location /bitcoin-status");
|
let missing_bitcoin_status = !content.contains("location /bitcoin-status");
|
||||||
let missing_lnd_proxy = !content.contains("location /proxy/lnd/");
|
let missing_lnd_proxy = !content.contains("location /proxy/lnd/");
|
||||||
|
let missing_peer_content = !content.contains("location /api/peer-content");
|
||||||
let has_lnd_dup_cors = content.contains(NGINX_LND_DUP_CORS);
|
let has_lnd_dup_cors = content.contains(NGINX_LND_DUP_CORS);
|
||||||
if !missing_app_catalog && !missing_bitcoin_status && !missing_lnd_proxy && !has_lnd_dup_cors {
|
if !missing_app_catalog
|
||||||
|
&& !missing_bitcoin_status
|
||||||
|
&& !missing_lnd_proxy
|
||||||
|
&& !missing_peer_content
|
||||||
|
&& !has_lnd_dup_cors
|
||||||
|
{
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,6 +581,22 @@ async fn patch_nginx_conf(path: &str) -> Result<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if missing_peer_content {
|
||||||
|
// Same anchoring as the LND proxy: prepend the block to every server
|
||||||
|
// block so /api/peer-content/* reaches the backend instead of the SPA.
|
||||||
|
let anchor = if patched.contains(" location /lnd-connect-info {") {
|
||||||
|
" location /lnd-connect-info {"
|
||||||
|
} else {
|
||||||
|
" location /electrs-status {"
|
||||||
|
};
|
||||||
|
if patched.contains(anchor) {
|
||||||
|
let replacement = format!("{}{}", NGINX_PEER_CONTENT_BLOCK, anchor);
|
||||||
|
patched = patched.replace(anchor, &replacement);
|
||||||
|
} else {
|
||||||
|
warn!("nginx conf missing anchor — skipping /api/peer-content patch");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if missing_bitcoin_status {
|
if missing_bitcoin_status {
|
||||||
let anchor = " location /electrs-status {";
|
let anchor = " location /electrs-status {";
|
||||||
if !patched.contains(anchor) {
|
if !patched.contains(anchor) {
|
||||||
|
|||||||
@ -111,6 +111,9 @@ Live (2026-06-15) federation sync last_transport on .116/.198: ~4 peers fips, ~6
|
|||||||
### B21 — Show Tor/FIPS transport pill on cloud browse — FIXED (build+type-check green; deploy+UI-confirm on .116/.198)
|
### B21 — Show Tor/FIPS transport pill on cloud browse — FIXED (build+type-check green; deploy+UI-confirm on .116/.198)
|
||||||
Tag whether the peer connection is Tor or FIPS and surface it as a small pill on the cloud browse screens / connection loader. Data source: federation node last_transport (now recorded by B14) exposed via federation.list-nodes; frontend renders a pill (FIPS=fast/green, Tor=slower) on PeerFiles.vue / Cloud peer view + the connection loader. Frontend-only-ish. FINDINGS: PeerFiles.vue:46 loader HARDCODES 'Connecting via Tor...' even when FIPS used (bug). Frontend types already have last_transport ('fips'|'tor'|'mesh'|'lan') federation/types.ts:31; NodeList.vue:167 already renders a transport indicator. PLAN: have content.browse-peer RETURN the transport used (B14 already computes it) → frontend shows a pill (FIPS green / Tor amber) on PeerFiles header + fix the loader text to reflect actual/attempted transport. Small backend (add transport to browse response) + frontend pill.
|
Tag whether the peer connection is Tor or FIPS and surface it as a small pill on the cloud browse screens / connection loader. Data source: federation node last_transport (now recorded by B14) exposed via federation.list-nodes; frontend renders a pill (FIPS=fast/green, Tor=slower) on PeerFiles.vue / Cloud peer view + the connection loader. Frontend-only-ish. FINDINGS: PeerFiles.vue:46 loader HARDCODES 'Connecting via Tor...' even when FIPS used (bug). Frontend types already have last_transport ('fips'|'tor'|'mesh'|'lan') federation/types.ts:31; NodeList.vue:167 already renders a transport indicator. PLAN: have content.browse-peer RETURN the transport used (B14 already computes it) → frontend shows a pill (FIPS green / Tor amber) on PeerFiles header + fix the loader text to reflect actual/attempted transport. Small backend (add transport to browse response) + frontend pill.
|
||||||
|
|
||||||
|
### B22 — Peer cloud download/audio errors (.228→.198) — TODO (pairs with B3)
|
||||||
|
Observed 2026-06-15 browsing .228's cloud from .198: (a) downloading a peer cloud file → "Operation failed. Check server logs for details." (b) playing a peer AUDIO file → "Could not play audio. File Browser may not be running." (misleading — it's a peer file, not File Browser; that's the OLD base64/blob path B3 replaces). ACTION: (a) check content.download-peer backend error on .198 logs while downloading (likely the same Range/transport/timeout path as B3, or a peer-side 4xx); (b) verify B3 streaming fixes peer audio once deployed, and fix the misleading audioPlayer error string. Get server logs: ssh .198, journalctl -u archipelago | grep -i 'content\|peer\|download'.
|
||||||
|
|
||||||
### B8 — netbird app doesn't work — TODO (LOW / much later)
|
### B8 — netbird app doesn't work — TODO (LOW / much later)
|
||||||
|
|
||||||
(RETRACTED: CryptPad placeholder-icon — user says cryptpad is fine.)
|
(RETRACTED: CryptPad placeholder-icon — user says cryptpad is fine.)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user