Support network proxies
This commit is contained in:
@@ -10,6 +10,12 @@ port: 9999
|
||||
# username: yowmamasita
|
||||
# password: 1234
|
||||
|
||||
# You can proxy all zurg requests like this:
|
||||
# proxy: "http://[username:password@]host:port"
|
||||
# proxy: "https://[username:password@]host:port"
|
||||
# proxy: "socks4://[username@]host:port"
|
||||
# proxy: "socks5://[username:password@]host:port"
|
||||
|
||||
# How many requests in parallel should we send to Real-Debrid API?
|
||||
concurrent_workers: 20
|
||||
|
||||
|
||||
1
go.mod
1
go.mod
@@ -20,6 +20,7 @@ require (
|
||||
github.com/go-chi/chi/v5 v5.0.11 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
2
go.sum
2
go.sum
@@ -42,6 +42,8 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
|
||||
@@ -13,6 +13,7 @@ type ConfigInterface interface {
|
||||
GetPort() string
|
||||
GetUsername() string
|
||||
GetPassword() string
|
||||
GetProxy() string
|
||||
GetDirectories() []string
|
||||
MeetsConditions(directory, torrentName string, torrentSize int64, torrentIDs, fileNames []string, fileSizes []int64) bool
|
||||
GetOnLibraryUpdate() string
|
||||
@@ -39,6 +40,7 @@ type ZurgConfig struct {
|
||||
Port string `yaml:"port" json:"port"`
|
||||
Username string `yaml:"username" json:"username"`
|
||||
Password string `yaml:"password" json:"password"`
|
||||
Proxy string `yaml:"proxy" json:"proxy"`
|
||||
NumOfWorkers int `yaml:"concurrent_workers" json:"concurrent_workers"`
|
||||
RefreshEverySeconds int `yaml:"check_for_changes_every_secs" json:"check_for_changes_every_secs"`
|
||||
|
||||
@@ -92,6 +94,10 @@ func (z *ZurgConfig) GetPassword() string {
|
||||
return z.Password
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetProxy() string {
|
||||
return z.Proxy
|
||||
}
|
||||
|
||||
func (z *ZurgConfig) GetNumOfWorkers() int {
|
||||
if z.NumOfWorkers == 0 {
|
||||
return 50
|
||||
|
||||
@@ -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,23 +112,35 @@ 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
|
||||
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) {
|
||||
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.DialContext(ctx, network, ipv6Address)
|
||||
return dialer.Dial(network, ipv6Address)
|
||||
}
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
@@ -138,18 +152,21 @@ func NewHTTPClient(token string, maxRetries int, timeoutSecs int, ensureIPv6Host
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if ip.IP.To4() == nil { // IPv6 address found
|
||||
ip6Host := ip.IP.String()
|
||||
ipv6Address := net.JoinHostPort(ip6Host, port)
|
||||
ipv6Address := net.JoinHostPort(ip.IP.String(), port)
|
||||
client.ipv6.Set(address, ipv6Address)
|
||||
return dialer.DialContext(ctx, network, ipv6Address)
|
||||
return dialer.Dial(network, ipv6Address)
|
||||
}
|
||||
}
|
||||
return dialer.DialContext(ctx, network, address)
|
||||
return dialer.Dial(network, address)
|
||||
},
|
||||
}
|
||||
} else {
|
||||
client.client.Transport = &http.Transport{
|
||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return dialer.Dial(network, address)
|
||||
},
|
||||
}
|
||||
transport := &http.Transport{
|
||||
DialContext: dialContext,
|
||||
}
|
||||
client.client.Transport = transport
|
||||
|
||||
return &client
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user