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,148 @@ 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+ origHTTP := os .Getenv ("HTTP_PROXY" )
81+ origHTTPS := os .Getenv ("HTTPS_PROXY" )
82+ origSOCKS := os .Getenv ("ALL_PROXY" )
83+
84+ defer func () {
85+ os .Setenv ("HTTP_PROXY" , origHTTP )
86+ os .Setenv ("HTTPS_PROXY" , origHTTPS )
87+ os .Setenv ("ALL_PROXY" , origSOCKS )
88+ }()
89+
90+ os .Setenv ("HTTP_PROXY" , tt .httpProxy )
91+ os .Setenv ("HTTPS_PROXY" , tt .httpsProxy )
92+ os .Setenv ("ALL_PROXY" , tt .socksProxy )
93+
94+ dialer := newProxyAwareDialer (30 * time .Second , 30 * time .Second , TestLogger )
95+ assert .NotNil (t , dialer )
96+
97+ if tt .expectDirect {
98+ _ , ok := dialer .(* net.Dialer )
99+ assert .True (t , ok , "Expected net.Dialer when no proxy configured" )
100+ } else if tt .expectProxy {
101+ assert .NotNil (t , dialer , "Expected proxy dialer when proxy configured" )
102+ }
103+ })
104+ }
105+ }
106+
107+ func TestProxyAwareDialerHTTPConnect (t * testing.T ) {
108+ proxyServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
109+ if r .Method != "CONNECT" {
110+ w .WriteHeader (http .StatusMethodNotAllowed )
111+ return
112+ }
113+ w .WriteHeader (http .StatusOK )
114+ }))
115+ defer proxyServer .Close ()
116+
117+ origHTTP := os .Getenv ("HTTP_PROXY" )
118+ defer os .Setenv ("HTTP_PROXY" , origHTTP )
119+
120+ os .Setenv ("HTTP_PROXY" , proxyServer .URL )
121+
122+ dialer := newProxyAwareDialer (5 * time .Second , 5 * time .Second , TestLogger )
123+ assert .NotNil (t , dialer )
124+
125+ // Test actual dial (this will fail because our mock proxy doesn't handle the full protocol)
126+ // but we can verify the proxy detection logic works
127+ proxyAwareDialer , ok := dialer .(* proxyAwareDialer )
128+ assert .True (t , ok , "Expected proxyAwareDialer when HTTP proxy configured" )
129+ assert .NotNil (t , proxyAwareDialer .baseDialer )
130+ }
131+
132+ func TestGetEnvProxy (t * testing.T ) {
133+ tests := []struct {
134+ name string
135+ upper string
136+ lower string
137+ upperVal string
138+ lowerVal string
139+ expected string
140+ }{
141+ {
142+ name : "upper case takes priority" ,
143+ upper : "TEST_PROXY" ,
144+ lower : "test_proxy" ,
145+ upperVal : "upper_value" ,
146+ lowerVal : "lower_value" ,
147+ expected : "upper_value" ,
148+ },
149+ {
150+ name : "lower case when upper not set" ,
151+ upper : "TEST_PROXY" ,
152+ lower : "test_proxy" ,
153+ lowerVal : "lower_value" ,
154+ expected : "lower_value" ,
155+ },
156+ {
157+ name : "empty when neither set" ,
158+ upper : "TEST_PROXY" ,
159+ lower : "test_proxy" ,
160+ expected : "" ,
161+ },
162+ }
163+
164+ for _ , tt := range tests {
165+ t .Run (tt .name , func (t * testing.T ) {
166+ // Save and restore environment
167+ origUpper := os .Getenv (tt .upper )
168+ origLower := os .Getenv (tt .lower )
169+ defer func () {
170+ os .Setenv (tt .upper , origUpper )
171+ os .Setenv (tt .lower , origLower )
172+ }()
173+
174+ os .Unsetenv (tt .upper )
175+ os .Unsetenv (tt .lower )
176+
177+ if tt .upperVal != "" {
178+ os .Setenv (tt .upper , tt .upperVal )
179+ }
180+ if tt .lowerVal != "" {
181+ os .Setenv (tt .lower , tt .lowerVal )
182+ }
183+
184+ result := getEnvProxy (tt .upper , tt .lower )
185+ assert .Equal (t , tt .expected , result )
186+ })
187+ }
188+ }
189+
43190func TestTCPOverWSServiceEstablishConnection (t * testing.T ) {
44191 originListener , err := net .Listen ("tcp" , "127.0.0.1:0" )
45192 require .NoError (t , err )
0 commit comments