- MemoryStore mirrors Laravel tooManyAttempts-before-hit first-hit-wins - FixedWindowLimiter + throttle factory; success and 429 rate-limit headers - Trusted-proxy ClientIP; remove noOpLimit; keep Limiter interface seam
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
package surf
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/netip"
|
|
"testing"
|
|
)
|
|
|
|
func TestClientIPEmptyTrustedUsesRemoteAddr(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.RemoteAddr = "203.0.113.9:1234"
|
|
req.Header.Set("X-Forwarded-For", "198.51.100.1")
|
|
got := ClientIP(req, nil)
|
|
if got != "203.0.113.9" {
|
|
t.Fatalf("got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestClientIPRejectsSpoofedXFF(t *testing.T) {
|
|
trusted := []netip.Prefix{mustPrefix("10.0.0.0/8")}
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.RemoteAddr = "203.0.113.9:1234"
|
|
req.Header.Set("X-Forwarded-For", "198.51.100.1")
|
|
got := ClientIP(req, trusted)
|
|
if got != "203.0.113.9" {
|
|
t.Fatalf("untrusted RemoteAddr must ignore X-Forwarded-For, got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestClientIPRightmostUntrustedHop(t *testing.T) {
|
|
trusted := []netip.Prefix{mustPrefix("10.0.0.0/8")}
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.RemoteAddr = "10.0.0.1:443"
|
|
req.Header.Set("X-Forwarded-For", "198.51.100.7, 203.0.113.10, 10.0.0.2")
|
|
got := ClientIP(req, trusted)
|
|
if got != "203.0.113.10" {
|
|
t.Fatalf("rightmost untrusted hop = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestClientIPAllHopsTrustedFallsBack(t *testing.T) {
|
|
trusted := []netip.Prefix{mustPrefix("10.0.0.0/8")}
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
req.RemoteAddr = "10.0.0.1:443"
|
|
req.Header.Set("X-Forwarded-For", "10.0.0.8, 10.0.0.9")
|
|
got := ClientIP(req, trusted)
|
|
if got != "10.0.0.1" {
|
|
t.Fatalf("fallback RemoteAddr = %q", got)
|
|
}
|
|
}
|
|
|
|
func mustPrefix(s string) netip.Prefix {
|
|
p, err := netip.ParsePrefix(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return p
|
|
}
|