starnet/proxy_custom_ip_test.go
starainrt 732e81316c
fix(starnet): 重构请求执行链路并补齐代理/重试/trace边界
- 分离 Request 的配置态与执行态,修复二次 Do、raw 模式网络配置失效和 body 来源互斥问题
  - 新增 starnet trace 抽象,补齐 DNS/连接/TLS/重试事件,并优化动态 transport 缓存与代理解析路径
  - 收紧非法代理为 fail-fast,多目标目标回退仅限幂等请求,修复 Host/TLS/SNI 等语义边界
  - 补充防御性拷贝、专项回归测试、本地代理/TLS 用例与 README 行为说明
2026-04-19 15:39:51 +08:00

111 lines
2.7 KiB
Go

package starnet
import (
"fmt"
"net"
"net/http"
"testing"
)
func TestRequestProxyWithCustomIPTargetsOriginWithoutRewritingProxyDial(t *testing.T) {
tlsReqInfo := make(chan struct {
host string
sni string
}, 1)
tlsServer := newIPv4TLSServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tlsReqInfo <- struct {
host string
sni string
}{
host: r.Host,
sni: r.TLS.ServerName,
}
_, _ = w.Write([]byte("ok"))
}))
defer tlsServer.Close()
_, port, err := net.SplitHostPort(tlsServer.Listener.Addr().String())
if err != nil {
t.Fatalf("split tls server addr: %v", err)
}
proxyServer := newIPv4ConnectProxyServer(t, nil)
defer proxyServer.Close()
targetHost := "proxy-custom-ip.test"
reqURL := fmt.Sprintf("https://%s:%s", targetHost, port)
req := NewSimpleRequest(reqURL, http.MethodGet).
SetProxy(proxyServer.URL).
SetCustomIP([]string{"127.0.0.1"}).
SetSkipTLSVerify(true)
resp, err := req.Do()
if err != nil {
t.Fatalf("Do error: %v", err)
}
defer resp.Close()
targets := proxyServer.Targets()
if len(targets) != 1 {
t.Fatalf("connect targets=%v; want 1 target", targets)
}
gotConnectTarget := targets[0]
wantConnectTarget := net.JoinHostPort("127.0.0.1", port)
if gotConnectTarget != wantConnectTarget {
t.Fatalf("CONNECT target = %q; want %q", gotConnectTarget, wantConnectTarget)
}
gotTLS := <-tlsReqInfo
wantHost := net.JoinHostPort(targetHost, port)
if gotTLS.host != wantHost {
t.Fatalf("request host = %q; want %q", gotTLS.host, wantHost)
}
if gotTLS.sni != targetHost {
t.Fatalf("tls sni = %q; want %q", gotTLS.sni, targetHost)
}
}
func TestRequestCustomIPPreservesOriginalHostAndSNI(t *testing.T) {
tlsReqInfo := make(chan struct {
host string
sni string
}, 1)
tlsServer := newIPv4TLSServer(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tlsReqInfo <- struct {
host string
sni string
}{
host: r.Host,
sni: r.TLS.ServerName,
}
_, _ = w.Write([]byte("ok"))
}))
defer tlsServer.Close()
_, port, err := net.SplitHostPort(tlsServer.Listener.Addr().String())
if err != nil {
t.Fatalf("split tls server addr: %v", err)
}
targetHost := "custom-ip-direct.test"
reqURL := fmt.Sprintf("https://%s:%s", targetHost, port)
req := NewSimpleRequest(reqURL, http.MethodGet).
SetCustomIP([]string{"127.0.0.1"}).
SetSkipTLSVerify(true)
resp, err := req.Do()
if err != nil {
t.Fatalf("Do error: %v", err)
}
defer resp.Close()
gotTLS := <-tlsReqInfo
wantHost := net.JoinHostPort(targetHost, port)
if gotTLS.host != wantHost {
t.Fatalf("request host = %q; want %q", gotTLS.host, wantHost)
}
if gotTLS.sni != targetHost {
t.Fatalf("tls sni = %q; want %q", gotTLS.sni, targetHost)
}
}