feat: add http & socks5 proxy

This commit is contained in:
Zhiqiang Li
2023-09-26 12:45:30 +08:00
parent a02b32fd62
commit 2abc77d1ef
4 changed files with 104 additions and 2 deletions

54
util/http_proxy.go Normal file
View File

@@ -0,0 +1,54 @@
package util
import (
"context"
"encoding/base64"
"fmt"
"net"
"net/http"
"net/url"
"golang.org/x/net/proxy"
)
func NewHttpProxy(proxyAddress string) (*http.Transport, error) {
proxyURL, err := url.Parse(proxyAddress)
if err != nil {
return nil, fmt.Errorf("error parsing proxy URL: %v", err)
}
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
if proxyURL.User != nil {
proxyAuth := "Basic " + base64.StdEncoding.EncodeToString([]byte(proxyURL.User.String()))
transport.ProxyConnectHeader = http.Header{
"Proxy-Authorization": []string{proxyAuth},
}
}
return transport, nil
}
func NewSocksProxy(proxyAddress string) (*http.Transport, error) {
// proxyAddress: socks5://user:password@127.0.0.1:1080
proxyURL, err := url.Parse(proxyAddress)
if err != nil {
return nil, fmt.Errorf("error parsing proxy URL: %v", err)
}
dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
if err != nil {
return nil, fmt.Errorf("error creating proxy dialer: %v", err)
}
transport := &http.Transport{
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
return dialer.Dial(network, address)
},
}
return transport, nil
}

41
util/http_proxy_test.go Normal file
View File

@@ -0,0 +1,41 @@
package util
import (
"github.com/stretchr/testify/assert"
"net/http"
"testing"
)
func TestHttpProxy(t *testing.T) {
proxyAddress := "http://127.0.0.1:1087"
transport, err := NewHttpProxy(proxyAddress)
assert.NoError(t, err)
assert.NotNil(t, transport)
client := &http.Client{
Transport: transport,
}
resp, err := client.Get("https://www.google.com")
assert.NoError(t, err)
assert.NotNil(t, resp)
assert.Equal(t, 200, resp.StatusCode)
}
func TestSocksProxy(t *testing.T) {
proxyAddress := "socks5://127.0.0.1:1080"
transport, err := NewSocksProxy(proxyAddress)
assert.NoError(t, err)
assert.NotNil(t, transport)
client := &http.Client{
Transport: transport,
}
resp, err := client.Get("https://www.google.com")
assert.NoError(t, err)
assert.NotNil(t, resp)
assert.Equal(t, 200, resp.StatusCode)
}