Files
memby/server/internal/api/clientip_test.go
T

91 lines
2.5 KiB
Go
Raw Normal View History

2026-08-28 23:00:02 +12:00
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)
}
}