docs: server comments say what the code does, not how it came to be (#6277)
Comment blocks in cmd/minstrel and 30 smaller internal packages, rewritten
to rule 32's standard with each citation read in context: task, milestone
and rule ids go, and so do the stories they were attached to ("used to",
"Before #N", measurements from one install, quotes, pointers to Fabled
Librarian's records and to docs/superpowers files that are not in the
repo). Where a story wrapped a real constraint, the constraint stays as a
present-tense fact.
Comments that had gone stale are corrected:
- taste.Config: the tuned values are overlaid by internal/recsettings;
it is no longer "a later follow-up".
- StorageConfig: the data dir holds art, caches and the stream secret,
not only playlist covers.
- the Subsonic album list and getUser comments describe what they do
today rather than a milestone that would change it.
Checked: the non-comment token stream of every changed file matches
HEAD, and gofmt -l is empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+12
-13
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
// ClientIP returns the caller's address, reading through trustedProxyHops
|
||||
// reverse proxies (#2453).
|
||||
// reverse proxies.
|
||||
//
|
||||
// X-Forwarded-For grows left-to-right: every proxy APPENDS the peer it
|
||||
// received the request from. For client -> CDN -> own-proxy -> Minstrel the
|
||||
@@ -20,13 +20,12 @@ import (
|
||||
// honestly claim is the address it told us about
|
||||
// hops 2 -> XFF[0] = client
|
||||
//
|
||||
// This replaces an earlier heuristic that ignored XFF whenever RemoteAddr was
|
||||
// public. That was safe but useless in the deployment that matters: a proxy
|
||||
// on a public address (separate host, or a CDN) meant every session recorded
|
||||
// the proxy, so the active-sessions surface could never show an address
|
||||
// change (#370).
|
||||
// Ignoring XFF whenever RemoteAddr is public would be safe but useless: behind
|
||||
// a proxy on a public address (a separate host, or a CDN) every session would
|
||||
// record the proxy, and the active-sessions list could never show an address
|
||||
// change.
|
||||
//
|
||||
// # What the operator is asserting
|
||||
// # What the hop count asserts
|
||||
//
|
||||
// hops >= 1 is a DECLARATION that a proxy sits in front. Two ways to get it
|
||||
// wrong, both worth understanding rather than papering over:
|
||||
@@ -36,9 +35,9 @@ import (
|
||||
// - Set HIGHER than the real chain: the index runs past the proxy-written
|
||||
// entries into attacker-supplied ones, same result.
|
||||
//
|
||||
// Both are inherent to the trusted-hop model — Rails, Caddy, Traefik and
|
||||
// nginx all behave this way — which is why 0 is a first-class value and the
|
||||
// admin card tells the operator to count their proxies.
|
||||
// Both are inherent to the trusted-hop model (Rails, Caddy, Traefik and nginx
|
||||
// behave the same way), which is why 0 is the default and the admin card asks
|
||||
// for the number of proxies in front.
|
||||
func ClientIP(r *http.Request, trustedProxyHops int) string {
|
||||
remote := hostOf(r.RemoteAddr)
|
||||
if trustedProxyHops <= 0 {
|
||||
@@ -51,7 +50,7 @@ func ClientIP(r *http.Request, trustedProxyHops int) string {
|
||||
return remote
|
||||
}
|
||||
// Clamp rather than reject: a chain shorter than the configured depth
|
||||
// means the operator over-counted, and the leftmost entry is the closest
|
||||
// means the hops were over-counted, and the leftmost entry is the closest
|
||||
// thing to a client on offer. The caveat above covers the risk.
|
||||
idx := len(chain) - trustedProxyHops
|
||||
if idx < 0 {
|
||||
@@ -68,8 +67,8 @@ func ClientIP(r *http.Request, trustedProxyHops int) string {
|
||||
// IsHTTPS reports whether the client reached us over HTTPS, reading through
|
||||
// trustedProxyHops reverse proxies by the same rule as ClientIP.
|
||||
//
|
||||
// TLS terminates at the operator's proxy (rule 94), so r.TLS is nil in every
|
||||
// real deployment and only X-Forwarded-Proto can say what the client used.
|
||||
// TLS terminates at the reverse proxy, so r.TLS is nil in every real
|
||||
// deployment and only X-Forwarded-Proto can say what the client used.
|
||||
// That header is believed only when hops >= 1: with no trusted proxy it is
|
||||
// just something any client can send. Proxies that append rather than
|
||||
// overwrite produce a comma list, read positionally like X-Forwarded-For.
|
||||
|
||||
@@ -68,8 +68,8 @@ func TestClientIP(t *testing.T) {
|
||||
want: "198.51.100.7",
|
||||
},
|
||||
{
|
||||
// A client prepending a lie is only reachable if the operator
|
||||
// over-counts their proxies; at the correct depth it's skipped.
|
||||
// A client prepending a lie is only reachable if the hops are
|
||||
// over-counted; at the correct depth it's skipped.
|
||||
name: "forged prefix is not reached at the correct depth",
|
||||
hops: 1,
|
||||
remoteAddr: "172.18.0.1:40000",
|
||||
@@ -178,7 +178,7 @@ func TestIsHTTPS(t *testing.T) {
|
||||
tls bool
|
||||
want bool
|
||||
}{
|
||||
// The three cases rule 94 names.
|
||||
// No trusted proxy, a trusted proxy saying https, and one saying http.
|
||||
{name: "hops 0 ignores a forwarded https", hops: 0, proto: "https", want: false},
|
||||
{name: "hops 1 believes a forwarded https", hops: 1, proto: "https", want: true},
|
||||
{name: "plain request is not https", hops: 1, want: false},
|
||||
|
||||
@@ -68,8 +68,8 @@ const SessionCookieName = "minstrel_session"
|
||||
// leak whether the username existed (matches the /rest/* auth posture).
|
||||
//
|
||||
// trustedHops supplies the reverse-proxy depth used to record the session's
|
||||
// current address (#2453). It's a func rather than an int because the value
|
||||
// is operator-editable at runtime and this middleware is constructed once at
|
||||
// current address. It's a func rather than an int because the value
|
||||
// is editable at runtime and this middleware is constructed once at
|
||||
// boot — reading it per request is what makes an admin change take effect
|
||||
// without a restart. Passing nil means "trust nothing", i.e. the socket peer.
|
||||
func RequireUser(pool *pgxpool.Pool, trustedHops func() int) func(http.Handler) http.Handler {
|
||||
@@ -155,7 +155,7 @@ func SessionIDCtxKeyForTest() any { return sessionIDCtxKey }
|
||||
//
|
||||
// Database lookup failures fall through too — a transient DB blip should not
|
||||
// 5xx a stream request that may have a perfectly valid signed token. The
|
||||
// error is logged so the operator can correlate.
|
||||
// error is logged so it can be correlated.
|
||||
func OptionalUser(pool *pgxpool.Pool, logger *slog.Logger) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
)
|
||||
|
||||
// SetupToken guards the first-admin registration. Until the first account
|
||||
// exists, register makes whoever calls it the admin, so a fresh instance on a
|
||||
// public address belonged to whoever found it first. Now that call also has
|
||||
// to carry this token, which is generated at startup and written only to the
|
||||
// server log: proof that the caller can read the operator's logs.
|
||||
// exists, register makes whoever calls it the admin, so without this a fresh
|
||||
// instance on a public address would belong to whoever found it first. The
|
||||
// call must carry this token, which is generated at startup and written only
|
||||
// to the server log: proof that the caller can read the server's logs.
|
||||
//
|
||||
// The token lives in memory. A restart mints a new one and logs it again,
|
||||
// which is the behaviour wanted: an old token from a log line someone else
|
||||
|
||||
Reference in New Issue
Block a user