Skip to content

Home HTTP: a self-signed server answers plain HTTP to the home network - #132

Merged
KodeStar merged 4 commits into
mainfrom
fix/home-http
Oct 14, 2026
Merged

KodeStar merged 4 commits into
mainfrom
fix/home-http

Conversation

@KodeStar

Copy link
Copy Markdown
Owner

Fixes #128.

The native apps can't trust the default self-signed certificate, so with the default setup they couldn't connect at all (the browser could, after accepting the warning).

What changes

  • tls.home_http (default on; env AUDIOSILO_TLS_HOME_HTTP; console Settings > Network & HTTPS, restart). Only in selfsigned mode with the server's own generated certificate (off when tls.cert_file is set).
  • The bind port serves both protocols: server.splitListener classifies each connection by its first byte in its own goroutine (10 s bound), one http.Server serves both, ALPN h2 kept, sendfile kept for plain HTTP.
  • server.homeHTTPGate: plain HTTP is served to loopback, or to a private/link-local connection address that names the server by a home-network Host; everyone else gets a 308 to https. The Host check keeps internet clients that a NAT/proxy gateway (Docker's IPv6 proxy) hands over from a private address on https.
  • The derived home address is http://host:port even for an https request; base_url, web_url and server= stay https (even when the pairing is asked for over plain HTTP).
  • Pairing links end with sid=<server_id> (payload server_id) so the app can verify the home address before sending the token there.
  • No HSTS on self-signed and no upgrade-insecure-requests (test-guarded), so the console and web player work over http on the LAN.

App side: KodeStar/audiosilo-frontend (fix/home-http). Docs: KodeStar/audiosilo-docs (docs/home-http).

Not verified on real hardware: a phone pairing with a real server over the LAN, Docker networking variants.

The native apps can't trust a self-signed certificate, so on the default
tls.mode selfsigned they couldn't connect at all (#128). With tls.home_http
(default on; AUDIOSILO_TLS_HOME_HTTP, console network.tls_home_http, restart)
the bind port now serves both protocols: splitListener peeks each
connection's first byte in its own goroutine (bounded by the header
timeout) and hands 0x16 to TLS, anything else to plain HTTP, all on one
http.Server. homeHTTPGate serves plain requests only when the connection's
own address is private, link-local or loopback (config.HomeNetworkIP, never
X-Forwarded-For, never CGNAT) and sends everyone else to https with a 308.

A derived home address on such a server is http://, keeping the request's
port (443 added when the Host has none), so pairing over the https QR still
teaches the apps an address they can use; lan_url, base_url, web_url and
uri server= are unchanged. The console shows the switch under Network &
HTTPS while the mode is self-signed.
An app that can't trust the https base falls back to the link's http home
address, where on a foreign network any box may hold the same private
address. Both pairing links now end with sid=<server_id> (after home/away,
additive: older clients ignore it) and the payload carries server_id, so
the app can check GET /server there before sending the token in cleartext.
…backoff

Pairing and invite links keep the https base on a server serving home HTTP, even when
asked for over plain HTTP; only home is http. The peeked connection offers ReadFrom so
plain-HTTP audio keeps the sendfile path, and the accept loop leaves backing off to
http.Server.
… cert

Plain HTTP is served to a private address only when the request names the server by a
home-network host, so an internet client a NAT or proxy gateway hands over (Docker's
IPv6 proxy) stays on https. A supplied certificate (tls.cert_file) turns home HTTP off.
Review fixes: CloseWrite forwarded, a proxied port-less Host keeps its base, one
HostWithPort for addresses, links and the redirect, sid from one config read.
@KodeStar
KodeStar merged commit 4e8cdf0 into main Oct 14, 2026
3 checks passed
@KodeStar
KodeStar deleted the fix/home-http branch October 14, 2026 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native apps can't connect to a server on the default self-signed certificate

1 participant