dialer_timeout_test.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package proxyutil
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "net/http"
  7. "net/url"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/require"
  11. )
  12. var errStub = errors.New("stub dial")
  13. // 回归:SOCKS5 分支覆盖了调用方在 Transport 上设置的 DialContext,
  14. // 底层 forward dialer 必须自带建连超时。proxy.Direct 是零值 net.Dialer,
  15. // 代理不可达时会一直卡到内核 TCP 重传耗尽(Linux 约 130 秒)。
  16. func TestSOCKS5ForwardDialerHasBoundedTimeout(t *testing.T) {
  17. require.Greater(t, socks5ForwardDialer.Timeout, time.Duration(0))
  18. require.Equal(t, socks5DialTimeout, socks5ForwardDialer.Timeout)
  19. require.Equal(t, socks5DialKeepAlive, socks5ForwardDialer.KeepAlive)
  20. }
  21. func TestConfigureTransportProxySOCKS5SetsDialContext(t *testing.T) {
  22. for _, scheme := range []string{"socks5", "socks5h"} {
  23. t.Run(scheme, func(t *testing.T) {
  24. proxyURL, err := url.Parse(scheme + "://127.0.0.1:1080")
  25. require.NoError(t, err)
  26. transport := &http.Transport{}
  27. require.NoError(t, ConfigureTransportProxy(transport, proxyURL))
  28. require.NotNil(t, transport.DialContext)
  29. require.Nil(t, transport.Proxy, "SOCKS5 不应设置 Transport.Proxy")
  30. })
  31. }
  32. }
  33. // HTTP 代理走 Transport.Proxy,不得覆盖调用方设置的 DialContext。
  34. func TestConfigureTransportProxyHTTPPreservesDialContext(t *testing.T) {
  35. proxyURL, err := url.Parse("http://127.0.0.1:8080")
  36. require.NoError(t, err)
  37. called := false
  38. transport := &http.Transport{}
  39. transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) {
  40. called = true
  41. return nil, errStub
  42. }
  43. require.NoError(t, ConfigureTransportProxy(transport, proxyURL))
  44. require.NotNil(t, transport.Proxy)
  45. require.NotNil(t, transport.DialContext)
  46. _, _ = transport.DialContext(context.Background(), "tcp", "127.0.0.1:1")
  47. require.True(t, called, "HTTP 代理分支不应替换调用方的 DialContext")
  48. }