88 "net/http"
99 "net/http/httptest"
1010 "net/url"
11+ "os"
1112 "testing"
13+ "time"
1214
1315 "github.com/stretchr/testify/assert"
1416 "github.com/stretchr/testify/require"
@@ -24,7 +26,10 @@ func TestRawTCPServiceEstablishConnection(t *testing.T) {
2426 listenerClosed := make (chan struct {})
2527 tcpListenRoutine (originListener , listenerClosed )
2628
27- rawTCPService := & rawTCPService {name : ServiceWarpRouting }
29+ rawTCPService := & rawTCPService {
30+ name : ServiceWarpRouting ,
31+ dialer : newProxyAwareDialer (30 * time .Second , 30 * time .Second , nil ),
32+ }
2833
2934 req , err := http .NewRequest (http .MethodGet , fmt .Sprintf ("http://%s" , originListener .Addr ()), nil )
3035 require .NoError (t , err )
@@ -40,6 +45,159 @@ func TestRawTCPServiceEstablishConnection(t *testing.T) {
4045 require .Error (t , err )
4146}
4247
48+ func TestProxyAwareDialer (t * testing.T ) {
49+ tests := []struct {
50+ name string
51+ httpProxy string
52+ httpsProxy string
53+ socksProxy string
54+ expectDirect bool
55+ expectProxy bool
56+ }{
57+ {
58+ name : "no proxy configured" ,
59+ expectDirect : true ,
60+ },
61+ {
62+ name : "HTTP proxy configured" ,
63+ httpProxy : "http://proxy.example.com:8080" ,
64+ expectProxy : true ,
65+ },
66+ {
67+ name : "HTTPS proxy configured" ,
68+ httpsProxy : "http://proxy.example.com:8080" ,
69+ expectProxy : true ,
70+ },
71+ {
72+ name : "SOCKS proxy configured" ,
73+ socksProxy : "socks5://proxy.example.com:1080" ,
74+ expectProxy : true ,
75+ },
76+ }
77+
78+ for _ , tt := range tests {
79+ t .Run (tt .name , func (t * testing.T ) {
80+ // Save original environment
81+ origHTTP := os .Getenv ("HTTP_PROXY" )
82+ origHTTPS := os .Getenv ("HTTPS_PROXY" )
83+ origSOCKS := os .Getenv ("ALL_PROXY" )
84+
85+ defer func () {
86+ os .Setenv ("HTTP_PROXY" , origHTTP )
87+ os .Setenv ("HTTPS_PROXY" , origHTTPS )
88+ os .Setenv ("ALL_PROXY" , origSOCKS )
89+ }()
90+
91+ // Set test environment
92+ os .Setenv ("HTTP_PROXY" , tt .httpProxy )
93+ os .Setenv ("HTTPS_PROXY" , tt .httpsProxy )
94+ os .Setenv ("ALL_PROXY" , tt .socksProxy )
95+
96+ dialer := newProxyAwareDialer (30 * time .Second , 30 * time .Second , TestLogger )
97+ assert .NotNil (t , dialer )
98+
99+ // Test that dialer implements expected interface
100+ if tt .expectDirect {
101+ // Should return base net.Dialer when no proxy configured
102+ _ , ok := dialer .(* net.Dialer )
103+ assert .True (t , ok , "Expected net.Dialer when no proxy configured" )
104+ } else if tt .expectProxy {
105+ // Should return some proxy dialer when proxy configured
106+ assert .NotNil (t , dialer , "Expected proxy dialer when proxy configured" )
107+ }
108+ })
109+ }
110+ }
111+
112+ func TestProxyAwareDialerHTTPConnect (t * testing.T ) {
113+ // Create a mock HTTP CONNECT proxy server
114+ proxyServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
115+ if r .Method != "CONNECT" {
116+ w .WriteHeader (http .StatusMethodNotAllowed )
117+ return
118+ }
119+ // Simulate successful CONNECT
120+ w .WriteHeader (http .StatusOK )
121+ }))
122+ defer proxyServer .Close ()
123+
124+ // Save original environment
125+ origHTTP := os .Getenv ("HTTP_PROXY" )
126+ defer os .Setenv ("HTTP_PROXY" , origHTTP )
127+
128+ // Set proxy environment
129+ os .Setenv ("HTTP_PROXY" , proxyServer .URL )
130+
131+ dialer := newProxyAwareDialer (5 * time .Second , 5 * time .Second , TestLogger )
132+ assert .NotNil (t , dialer )
133+
134+ // Test actual dial (this will fail because our mock proxy doesn't handle the full protocol)
135+ // but we can verify the proxy detection logic works
136+ proxyAwareDialer , ok := dialer .(* proxyAwareDialer )
137+ assert .True (t , ok , "Expected proxyAwareDialer when HTTP proxy configured" )
138+ assert .NotNil (t , proxyAwareDialer .baseDialer )
139+ }
140+
141+ func TestGetEnvProxy (t * testing.T ) {
142+ tests := []struct {
143+ name string
144+ upper string
145+ lower string
146+ upperVal string
147+ lowerVal string
148+ expected string
149+ }{
150+ {
151+ name : "upper case takes priority" ,
152+ upper : "TEST_PROXY" ,
153+ lower : "test_proxy" ,
154+ upperVal : "upper_value" ,
155+ lowerVal : "lower_value" ,
156+ expected : "upper_value" ,
157+ },
158+ {
159+ name : "lower case when upper not set" ,
160+ upper : "TEST_PROXY" ,
161+ lower : "test_proxy" ,
162+ lowerVal : "lower_value" ,
163+ expected : "lower_value" ,
164+ },
165+ {
166+ name : "empty when neither set" ,
167+ upper : "TEST_PROXY" ,
168+ lower : "test_proxy" ,
169+ expected : "" ,
170+ },
171+ }
172+
173+ for _ , tt := range tests {
174+ t .Run (tt .name , func (t * testing.T ) {
175+ // Save and restore environment
176+ origUpper := os .Getenv (tt .upper )
177+ origLower := os .Getenv (tt .lower )
178+ defer func () {
179+ os .Setenv (tt .upper , origUpper )
180+ os .Setenv (tt .lower , origLower )
181+ }()
182+
183+ // Clear environment first
184+ os .Unsetenv (tt .upper )
185+ os .Unsetenv (tt .lower )
186+
187+ // Set test values
188+ if tt .upperVal != "" {
189+ os .Setenv (tt .upper , tt .upperVal )
190+ }
191+ if tt .lowerVal != "" {
192+ os .Setenv (tt .lower , tt .lowerVal )
193+ }
194+
195+ result := getEnvProxy (tt .upper , tt .lower )
196+ assert .Equal (t , tt .expected , result )
197+ })
198+ }
199+ }
200+
43201func TestTCPOverWSServiceEstablishConnection (t * testing.T ) {
44202 originListener , err := net .Listen ("tcp" , "127.0.0.1:0" )
45203 require .NoError (t , err )
0 commit comments