package api import ( "net/http" "net/netip" "testing" "github.com/ponzischeme89/memby/server/internal/config" ) func TestClientIPFrom(t *testing.T) { trusted := config.DefaultTrustedProxyRanges() tests := []struct { name string remoteAddr string headers map[string]string wantAddr string wantVia string }{ { name: "direct public client, no proxy headers believed", remoteAddr: "203.0.113.9:52344", headers: map[string]string{"X-Forwarded-For": "10.0.0.9"}, wantAddr: "203.0.113.9", wantVia: "socket", }, { name: "through the household proxy, real client in X-Forwarded-For", remoteAddr: "10.0.0.2:41000", headers: map[string]string{"X-Forwarded-For": "203.0.113.42, 10.0.0.2"}, wantAddr: "203.0.113.42", wantVia: "forwarded", }, { name: "direct LAN client behind the proxy still shows its LAN address", remoteAddr: "10.0.0.2:41000", headers: map[string]string{"X-Forwarded-For": "10.0.0.50"}, wantAddr: "10.0.0.50", wantVia: "forwarded", }, { name: "proxy sets only X-Real-IP", remoteAddr: "192.168.1.1:8443", headers: map[string]string{"X-Real-IP": "198.51.100.7"}, wantAddr: "198.51.100.7", wantVia: "real-ip", }, { name: "trusted proxy with no forwarding headers", remoteAddr: "127.0.0.1:5000", wantAddr: "127.0.0.1", wantVia: "socket", }, { name: "spoofed X-Real-IP from an untrusted client is ignored", remoteAddr: "203.0.113.9:1000", headers: map[string]string{"X-Real-IP": "10.0.0.1"}, wantAddr: "203.0.113.9", wantVia: "socket", }, { name: "unparseable remote address", remoteAddr: "garbage", wantAddr: "unknown", wantVia: "none", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { header := http.Header{} for key, value := range test.headers { header.Set(key, value) } got := clientIPFrom(test.remoteAddr, header, trusted) if got.String() != test.wantAddr || got.Via != test.wantVia { t.Fatalf("clientIPFrom = %+v, want addr %q via %q", got, test.wantAddr, test.wantVia) } }) } } func TestClientIPFromTrustsNothingWhenListEmpty(t *testing.T) { header := http.Header{"X-Forwarded-For": {"203.0.113.1"}} got := clientIPFrom("10.0.0.2:5000", header, []netip.Prefix{}) if got.String() != "10.0.0.2" || got.Via != "socket" { t.Fatalf("clientIPFrom with no trusted proxies = %+v, want 10.0.0.2 via socket", got) } }