Add trusted proxy middleware and simplify clientip

Strip forwarded headers (Forwarded, X-Forwarded-For, X-Real-Ip)
from requests originating from untrusted proxies at the HTTP
server level, reusing the existing proxy-protocol trusted-proxies
config. The clientip package is now a pure extraction helper;
context plumbing and middleware wrappers are removed.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-14 18:50:10 +04:00
parent 8f2426602b
commit e3ab373a0c
6 changed files with 329 additions and 26 deletions

View File

@@ -15,35 +15,11 @@
package clientip
import (
"context"
"net"
"net/http"
"strings"
)
type ctxKey struct{}
// NewMiddleware returns an HTTP middleware that extracts the client IP
// from standard proxy headers and stores it in the request context.
func NewMiddleware() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip := Extract(r)
ctx := context.WithValue(r.Context(), ctxKey{}, ip)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}
// FromContext returns the client IP stored by the middleware, or an
// empty string if the middleware has not run.
func FromContext(ctx context.Context) string {
if ip, ok := ctx.Value(ctxKey{}).(string); ok {
return ip
}
return ""
}
// Extract resolves the client IP address from standard proxy headers
// in priority order: RFC 7239 Forwarded, then X-Forwarded-For, then
// the connection's remote address.