Smail/backend/utils/ip/ip_test.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

89 lines
2.6 KiB
Go

package ip
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
func TestFetchPublicIPAcceptsPublicAddress(t *testing.T) {
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("8.8.8.8\n"))
}))
defer server.Close()
client := server.Client()
client.Timeout = time.Second
request, err := http.NewRequest(http.MethodGet, server.URL, nil)
if err != nil {
t.Fatal(err)
}
value, err := fetchPublicIP(client, request)
if err != nil || value != "8.8.8.8" {
t.Fatalf("unexpected public IP result: value=%q err=%v", value, err)
}
}
func TestFetchPublicIPRejectsUnsafeResponses(t *testing.T) {
cases := []struct {
name string
status int
body string
}{
{name: "private", status: http.StatusOK, body: "192.168.1.10"},
{name: "loopback", status: http.StatusOK, body: "127.0.0.1"},
{name: "invalid", status: http.StatusOK, body: "not-an-ip"},
{name: "large", status: http.StatusOK, body: strings.Repeat("1", maxIPResponseBytes+1)},
{name: "status", status: http.StatusBadGateway, body: "8.8.8.8"},
}
for _, item := range cases {
t.Run(item.name, func(t *testing.T) {
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(item.status)
_, _ = w.Write([]byte(item.body))
}))
defer server.Close()
client := server.Client()
client.Timeout = time.Second
request, err := http.NewRequest(http.MethodGet, server.URL, nil)
if err != nil {
t.Fatal(err)
}
if _, err := fetchPublicIP(client, request); err == nil {
t.Fatal("unsafe public IP response was accepted")
}
})
}
}
func TestFetchPublicIPRejectsPlainHTTP(t *testing.T) {
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
if err != nil {
t.Fatal(err)
}
if _, err := fetchPublicIP(&http.Client{Timeout: time.Second}, request); err == nil {
t.Fatal("plain HTTP public IP request was accepted")
}
}
func TestFetchPublicIPForFamilyRequiresRequestedAddressFamily(t *testing.T) {
server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("2001:db8::1\n"))
}))
defer server.Close()
request, err := http.NewRequest(http.MethodGet, server.URL, nil)
if err != nil {
t.Fatal(err)
}
value, err := fetchPublicIPForFamily(server.Client(), request, true)
if err != nil || value != "2001:db8::1" {
t.Fatalf("unexpected IPv6 result: value=%q err=%v", value, err)
}
if _, err := fetchPublicIPForFamily(server.Client(), request, false); err == nil {
t.Fatal("IPv6 result was accepted for IPv4 request")
}
}