mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-22 03:02:35 +00:00
ADA: Add unit tests for isDirectLoopbackRequest
This commit is contained in:
parent
3b5c1347d1
commit
0a623bee41
1 changed files with 181 additions and 0 deletions
181
internal/api/router_test.go
Normal file
181
internal/api/router_test.go
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsDirectLoopbackRequest(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
remoteAddr string
|
||||
headers map[string]string
|
||||
want bool
|
||||
}{
|
||||
// Nil request
|
||||
{
|
||||
name: "nil request",
|
||||
req: nil,
|
||||
want: false,
|
||||
},
|
||||
|
||||
// Valid loopback IPs without proxy headers
|
||||
{
|
||||
name: "loopback IPv4 without port",
|
||||
remoteAddr: "127.0.0.1",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv4 with port",
|
||||
remoteAddr: "127.0.0.1:8080",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv4 alternate",
|
||||
remoteAddr: "127.0.0.2:54321",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv6 without port",
|
||||
remoteAddr: "::1",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv6 with port",
|
||||
remoteAddr: "[::1]:8080",
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv6 with brackets no port",
|
||||
remoteAddr: "[::1]",
|
||||
want: true,
|
||||
},
|
||||
|
||||
// Loopback with proxy headers (should reject)
|
||||
{
|
||||
name: "loopback with X-Forwarded-For",
|
||||
remoteAddr: "127.0.0.1:8080",
|
||||
headers: map[string]string{
|
||||
"X-Forwarded-For": "192.168.1.1",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "loopback with Forwarded",
|
||||
remoteAddr: "127.0.0.1:8080",
|
||||
headers: map[string]string{
|
||||
"Forwarded": "for=192.168.1.1",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "loopback with X-Real-IP",
|
||||
remoteAddr: "127.0.0.1:8080",
|
||||
headers: map[string]string{
|
||||
"X-Real-IP": "192.168.1.1",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "loopback with multiple proxy headers",
|
||||
remoteAddr: "127.0.0.1:8080",
|
||||
headers: map[string]string{
|
||||
"X-Forwarded-For": "192.168.1.1",
|
||||
"X-Real-IP": "10.0.0.1",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "loopback IPv6 with X-Forwarded-For",
|
||||
remoteAddr: "[::1]:8080",
|
||||
headers: map[string]string{
|
||||
"X-Forwarded-For": "203.0.113.42",
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
|
||||
// Non-loopback IPs (should reject)
|
||||
{
|
||||
name: "private IPv4",
|
||||
remoteAddr: "192.168.1.1:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "private IPv4 10.x",
|
||||
remoteAddr: "10.0.0.1:54321",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "private IPv4 172.x",
|
||||
remoteAddr: "172.16.0.1:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "public IPv4",
|
||||
remoteAddr: "203.0.113.42:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "public IPv6",
|
||||
remoteAddr: "[2001:db8::1]:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "link-local IPv6",
|
||||
remoteAddr: "[fe80::1]:8080",
|
||||
want: false,
|
||||
},
|
||||
|
||||
// Edge cases
|
||||
{
|
||||
name: "empty RemoteAddr",
|
||||
remoteAddr: "",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "invalid IP format",
|
||||
remoteAddr: "not-an-ip:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "invalid IP with port",
|
||||
remoteAddr: "999.999.999.999:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "malformed IPv6",
|
||||
remoteAddr: "[::g]:8080",
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "just port",
|
||||
remoteAddr: ":8080",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var req *http.Request
|
||||
if tt.req != nil {
|
||||
req = tt.req
|
||||
} else if tt.name != "nil request" {
|
||||
req = httptest.NewRequest("GET", "/", nil)
|
||||
req.RemoteAddr = tt.remoteAddr
|
||||
for key, value := range tt.headers {
|
||||
req.Header.Set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
got := isDirectLoopbackRequest(req)
|
||||
if got != tt.want {
|
||||
t.Errorf("isDirectLoopbackRequest() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue