middleware: take the client address from the right of X-Forwarded-For (closes #181)
check / check (push) Successful in 1m19s

realIP took the first X-Forwarded-For entry, which the client itself
can write, so behind a proxy that appends to the header a client chose
the address dnswatcher logs and the /metrics rate limit counts. It now
walks the entries from the right past trusted proxies, using the
existing trusted-proxy check, and takes the first that is not one; the
leftmost when all are. All X-Forwarded-For header lines are read as one
list, since a proxy may add its own line instead of appending to the
client's. An empty entry where the client address belongs falls back
to the peer address, as an empty first entry did before. X-Real-IP is
unchanged.

Model: opus-5-5
This commit is contained in:
2026-10-01 20:20:59 +00:00
parent fcd4f7e2c2
commit a41ff44b16
5 changed files with 122 additions and 14 deletions
+10 -1
View File
@@ -1,6 +1,9 @@
package middleware
import "time"
import (
"net/http"
"time"
)
// The /metrics rate limit, exported so the tests can count requests
// against it.
@@ -8,3 +11,9 @@ const (
MetricsRequestLimit = metricsRequestLimit
MetricsRequestWindow time.Duration = metricsRequestWindow
)
// RealIP is realIP, exported so the tests can check which address it
// takes as the client's.
func RealIP(r *http.Request) string {
return realIP(r)
}