Skip to content

Commit

Permalink
add proxy test
Browse files Browse the repository at this point in the history
  • Loading branch information
Danny-Dasilva committed Jan 8, 2024
1 parent 81ff1e6 commit 890bb30
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/test_golang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ jobs:
run: |
docker run -d -p 1087:1080 serjs/go-socks5-proxy
- name: Start SOCKS4 Proxy (only on ubuntu)
if: matrix.platform == 'ubuntu-latest'
run: |
docker run -d -p 1088:1080 your/socks4-proxy-image
- name: Integration Tests
working-directory: ./cycletls
run: go test --race -v -tags=integration ./...
36 changes: 30 additions & 6 deletions cycletls/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,30 @@ import (
"encoding/base64"
"errors"
"fmt"
http "github.com/Danny-Dasilva/fhttp"
http2 "github.com/Danny-Dasilva/fhttp/http2"
"golang.org/x/net/proxy"
"io"
"net"
"net/url"
"strconv"
"sync"

http "github.com/Danny-Dasilva/fhttp"
http2 "github.com/Danny-Dasilva/fhttp/http2"
"golang.org/x/net/proxy"
"h12.io/socks"
)

type SocksDialer struct {
socksDial func(string, string) (net.Conn, error)
}

func (d *SocksDialer) DialContext(_ context.Context, network, addr string) (net.Conn, error) {
return d.socksDial(network, addr)
}

func (d *SocksDialer) Dial(network, addr string) (net.Conn, error) {
return d.socksDial(network, addr)
}

// connectDialer allows to configure one-time use HTTP CONNECT client
type connectDialer struct {
ProxyURL url.URL
Expand Down Expand Up @@ -64,7 +78,7 @@ func newConnectDialer(proxyURLStr string, UserAgent string) (proxy.ContextDialer
if proxyURL.Port() == "" {
proxyURL.Host = net.JoinHostPort(proxyURL.Host, "443")
}
case "socks5":
case "socks5", "socks5h":
var auth *proxy.Auth
if proxyURL.User != nil {
if proxyURL.User.Username() != "" {
Expand All @@ -73,7 +87,11 @@ func newConnectDialer(proxyURLStr string, UserAgent string) (proxy.ContextDialer
auth = &proxy.Auth{User: username, Password: password}
}
}
dialSocksProxy, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, nil)
var forward proxy.Dialer
if proxyURL.Scheme == "socks5h" {
forward = proxy.Direct
}
dialSocksProxy, err := proxy.SOCKS5("tcp", proxyURL.Host, auth, forward)
if err != nil {
return nil, fmt.Errorf("Error creating SOCKS5 proxy, reason %s", err)
}
Expand All @@ -84,6 +102,12 @@ func newConnectDialer(proxyURLStr string, UserAgent string) (proxy.ContextDialer
}
client.DefaultHeader.Set("User-Agent", UserAgent)
return client, nil
case "socks4":
var dialer *SocksDialer
dialer = &SocksDialer{socks.DialSocksProxy(socks.SOCKS4, proxyURL.Host)}
client.Dialer = dialer
client.DefaultHeader.Set("User-Agent", UserAgent)
return client, nil
case "":
return nil, errors.New("specify scheme explicitly (https://)")
default:
Expand Down Expand Up @@ -121,7 +145,7 @@ type ContextKeyHeader struct{}
// ctx.Value will be inspected for optional ContextKeyHeader{} key, with `http.Header` value,
// which will be added to outgoing request headers, overriding any colliding c.DefaultHeader
func (c *connectDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
if c.ProxyURL.Scheme == "socks5" {
if c.ProxyURL.Scheme == "socks5" || c.ProxyURL.Scheme == "socks4" {
return c.Dialer.DialContext(ctx, network, address)
}

Expand Down
65 changes: 46 additions & 19 deletions cycletls/tests/integration/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,50 @@ func TestProxySuccess(t *testing.T) {
}
log.Print("Body: " + resp.Body)
}
func TestSocks4Proxy(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("Skipping this test on non-linux platforms")
return
}
client := cycletls.Init()
resp, err := client.Do("https://ipinfo.io/json", cycletls.Options{
Body: "",
Ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0",
UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
Proxy: "socks4://abc:[email protected]:1087",
Headers: map[string]string{
"Accept": "Application/json, text/plain, */*",
},
}, "GET")
if err != nil {
t.Fatalf("Request Failed: " + err.Error())
}
if resp.Status != 200 {
t.Fatalf("Expected %d Got %d for Status", 200, resp.Status)
}
log.Print("Body: " + resp.Body)
}

// func TestHttpError(t *testing.T) {

// client := cycletls.Init()
// resp, err := client.Do("https://ipinfo.io/json", cycletls.Options{
// Body: "",
// Ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0",
// UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
// Proxy: "http://127.0.0.1:10809",
// Headers: map[string]string{
// "Accept": "Application/json, text/plain, */*",
// },
// }, "GET")
// if err != nil {
// log.Print("Request Failed: " + err.Error())
// }
// log.Print("Status: " + strconv.Itoa(resp.Status))
// log.Print("Body: " + resp.Body)

// }
func TestSocks5hProxy(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("Skipping this test on non-linux platforms")
return
}
client := cycletls.Init()
resp, err := client.Do("https://ipinfo.io/json", cycletls.Options{
Body: "",
Ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0",
UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
Proxy: "socks5h://abc:[email protected]:1087",
Headers: map[string]string{
"Accept": "Application/json, text/plain, */*",
},
}, "GET")
if err != nil {
t.Fatalf("Request Failed: " + err.Error())
}
if resp.Status != 200 {
t.Fatalf("Expected %d Got %d for Status", 200, resp.Status)
}
log.Print("Body: " + resp.Body)
}

0 comments on commit 890bb30

Please sign in to comment.