Support network proxies

This commit is contained in:
Ben Sarmiento
2024-01-11 04:15:40 +01:00
parent dfa3ef99b0
commit b2e02c7e1f
5 changed files with 66 additions and 34 deletions

View File

@@ -9,12 +9,14 @@ import (
"math/rand"
"net"
"net/http"
"net/url"
"strings"
"time"
"github.com/debridmediamanager/zurg/internal/config"
"github.com/debridmediamanager/zurg/pkg/hosts"
"github.com/debridmediamanager/zurg/pkg/logutil"
"golang.org/x/net/proxy"
cmap "github.com/orcaman/concurrent-map/v2"
)
@@ -110,46 +112,61 @@ func NewHTTPClient(token string, maxRetries int, timeoutSecs int, ensureIPv6Host
log: log,
}
if !cfg.ShouldForceIPv6() {
return &client
var dialer proxy.Dialer = &net.Dialer{}
if proxyURLString := cfg.GetProxy(); proxyURLString != "" {
proxyURL, err := url.Parse(proxyURLString)
if err != nil {
log.Errorf("Failed to parse proxy URL: %v", err)
return nil
}
proxyDialer, err := proxy.FromURL(proxyURL, dialer)
if err != nil {
log.Errorf("Failed to create proxy dialer: %v", err)
return nil
}
dialer = proxyDialer
}
// set ipv6 hosts
ipv6List, err := hosts.FetchHosts(hosts.IPV6)
if err != nil {
log.Warnf("Failed to fetch IPv6 hosts: %v", err)
}
client.ipv6Hosts = ipv6List
log.Debugf("Fetched %d IPv6 hosts", len(ipv6List))
if cfg.ShouldForceIPv6() {
ipv6List, err := hosts.FetchHosts(hosts.IPV6)
if err != nil {
log.Warnf("Failed to fetch IPv6 hosts: %v", err)
// Decide if you want to return nil here or continue without IPv6
} else {
client.ipv6Hosts = ipv6List
log.Debugf("Fetched %d IPv6 hosts", len(ipv6List))
}
// set ipv6 transport
dialer := &net.Dialer{}
dialContext := func(ctx context.Context, network, address string) (net.Conn, error) {
if ipv6Address, ok := client.ipv6.Get(address); ok {
return dialer.DialContext(ctx, network, ipv6Address)
client.client.Transport = &http.Transport{
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
if ipv6Address, ok := client.ipv6.Get(address); ok {
return dialer.Dial(network, ipv6Address)
}
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, err
}
for _, ip := range ips {
if ip.IP.To4() == nil { // IPv6 address found
ipv6Address := net.JoinHostPort(ip.IP.String(), port)
client.ipv6.Set(address, ipv6Address)
return dialer.Dial(network, ipv6Address)
}
}
return dialer.Dial(network, address)
},
}
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, err
} else {
client.client.Transport = &http.Transport{
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
return dialer.Dial(network, address)
},
}
ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
if err != nil {
return nil, err
}
for _, ip := range ips {
if ip.IP.To4() == nil { // IPv6 address found
ip6Host := ip.IP.String()
ipv6Address := net.JoinHostPort(ip6Host, port)
client.ipv6.Set(address, ipv6Address)
return dialer.DialContext(ctx, network, ipv6Address)
}
}
return dialer.DialContext(ctx, network, address)
}
transport := &http.Transport{
DialContext: dialContext,
}
client.client.Transport = transport
return &client
}