mirror of
https://github.com/Snawoot/hola-proxy.git
synced 2026-04-06 00:28:12 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6aa4fc334a | ||
|
|
124212a5e2 | ||
|
|
b120cb5462 | ||
|
|
972771b6af | ||
|
|
49b6ba9147 | ||
|
|
1e4c6684cc | ||
|
|
569bf1d39f | ||
|
|
92fdd4fb72 | ||
|
|
d4d37bb354 |
@@ -165,6 +165,8 @@ zagent248.hola.org,165.22.65.3,22222,22223,22224,22225,22226,digitalocean
|
||||
| ext-ver | String | extension version to mimic in requests. Can be obtained from https://chrome.google.com/webstore/detail/hola-vpn-the-website-unbl/gkojfkhlekighikafcpjkiklfbnlmeio (default "999.999.999") |
|
||||
| force-port-field | Number | force specific port field/num (example 24232 or lum) |
|
||||
| hide-SNI | Boolean | hide SNI in TLS sessions with proxy server (default true) |
|
||||
| init-retries | Number | number of attempts for initialization steps, zero for unlimited retry |
|
||||
| init-retry-interval | Duration | delay between initialization retries (default 5s) |
|
||||
| limit | Unsigned Integer (Number) | amount of proxies in retrieved list (default 3) |
|
||||
| list-countries | String | list available countries and exit |
|
||||
| list-proxies | - | output proxy list and exit |
|
||||
@@ -173,7 +175,7 @@ zagent248.hola.org,165.22.65.3,22222,22223,22224,22225,22226,digitalocean
|
||||
| resolver | String | DNS/DoH/DoT resolver to workaround Hola blocked hosts. See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format. (default "https://cloudflare-dns.com/dns-query") |
|
||||
| rotate | Duration | rotate user ID once per given period (default 1h0m0s) |
|
||||
| timeout | Duration | timeout for network operations (default 35s) |
|
||||
| user-agent | String | value of User-Agent header in requests (default "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36") |
|
||||
| user-agent | String | value of User-Agent header in requests (default "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36") |
|
||||
| verbosity | Number | logging verbosity (10 - debug, 20 - info, 30 - warning, 40 - error, 50 - critical) (default 20) |
|
||||
|
||||
## See also
|
||||
|
||||
18
go.mod
18
go.mod
@@ -13,22 +13,22 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AdguardTeam/golibs v0.29.0 // indirect
|
||||
github.com/AdguardTeam/golibs v0.30.2 // indirect
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
|
||||
github.com/ameshkov/dnscrypt/v2 v2.3.0 // indirect
|
||||
github.com/ameshkov/dnsstamps v1.0.3 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/cloudflare/circl v1.4.0 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/cloudflare/circl v1.5.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d // indirect
|
||||
github.com/klauspost/compress v1.17.10 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.47.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
github.com/quic-go/quic-go v0.48.1 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 // indirect
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
|
||||
42
go.sum
42
go.sum
@@ -1,7 +1,7 @@
|
||||
github.com/AdguardTeam/dnsproxy v0.73.2 h1:O6wRXzHsnWL5TkhYcuLWCShVFF0X5RFI6qUmq1ZFVsQ=
|
||||
github.com/AdguardTeam/dnsproxy v0.73.2/go.mod h1:zD5WfTctbRvYYk8PS39h6/OT84NTu6QxKbAiBN5PUcI=
|
||||
github.com/AdguardTeam/golibs v0.29.0 h1:NG3eUXaUwRTgKssblolh4XHME8MQCCdogyIZxxv4bOU=
|
||||
github.com/AdguardTeam/golibs v0.29.0/go.mod h1:vjw1OVZG6BYyoqGRY88U4LCJLOMfhBFhU0UJBdaSAuQ=
|
||||
github.com/AdguardTeam/golibs v0.30.2 h1:urU/NAyIvQOeArBqDmKCDpaRkfTCJ26uSiSuDMKQfuY=
|
||||
github.com/AdguardTeam/golibs v0.30.2/go.mod h1:FkwcNQEJoGsgDGXcalrVa/4gWbE68KsmE2guXWtBQUE=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 h1:52m0LGchQBBVqJRyYYufQuIbVqRawmubW3OFGqK1ekw=
|
||||
@@ -10,14 +10,14 @@ github.com/ameshkov/dnscrypt/v2 v2.3.0 h1:pDXDF7eFa6Lw+04C0hoMh8kCAQM8NwUdFEllSP
|
||||
github.com/ameshkov/dnscrypt/v2 v2.3.0/go.mod h1:N5hDwgx2cNb4Ay7AhvOSKst+eUiOZ/vbKRO9qMpQttE=
|
||||
github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
|
||||
github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ=
|
||||
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
|
||||
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
|
||||
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
@@ -26,34 +26,36 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d h1:Jaz2JzpQaQXyET0AjLBXShrthbpqMkhGiEfkcQAiAUs=
|
||||
github.com/google/pprof v0.0.0-20241001023024-f4c0cfd0cf1d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
|
||||
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
|
||||
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8=
|
||||
github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.47.0 h1:yXs3v7r2bm1wmPTYNLKAAJTHMYkPEsfYJmTazXrCZ7Y=
|
||||
github.com/quic-go/quic-go v0.47.0/go.mod h1:3bCapYsJvXGZcipOHuu7plYtaV6tnF+z7wIFsU0WK9E=
|
||||
github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
|
||||
github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw=
|
||||
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
|
||||
58
main.go
58
main.go
@@ -64,6 +64,8 @@ type CLIArgs struct {
|
||||
maxPause time.Duration
|
||||
backoffInitial time.Duration
|
||||
backoffDeadline time.Duration
|
||||
initRetries int
|
||||
initRetryInterval time.Duration
|
||||
hideSNI bool
|
||||
userAgent string
|
||||
}
|
||||
@@ -84,6 +86,8 @@ func parse_args() CLIArgs {
|
||||
flag.DurationVar(&args.rotate, "rotate", 1*time.Hour, "rotate user ID once per given period")
|
||||
flag.DurationVar(&args.backoffInitial, "backoff-initial", 3*time.Second, "initial average backoff delay for zgettunnels (randomized by +/-50%)")
|
||||
flag.DurationVar(&args.backoffDeadline, "backoff-deadline", 5*time.Minute, "total duration of zgettunnels method attempts")
|
||||
flag.IntVar(&args.initRetries, "init-retries", 0, "number of attempts for initialization steps, zero for unlimited retry")
|
||||
flag.DurationVar(&args.initRetryInterval, "init-retry-interval", 5*time.Second, "delay between initialization retries")
|
||||
flag.StringVar(&args.proxy_type, "proxy-type", "direct", "proxy type: direct or lum") // or skip but not mentioned
|
||||
// skip would be used something like this: `./bin/hola-proxy -proxy-type skip -force-port-field 24232 -country ua.peer` for debugging
|
||||
flag.StringVar(&args.resolver, "resolver", "https://cloudflare-dns.com/dns-query",
|
||||
@@ -180,28 +184,32 @@ func run() int {
|
||||
|
||||
SetUserAgent(args.userAgent)
|
||||
|
||||
try := retryPolicy(args.initRetries, args.initRetryInterval, mainLogger)
|
||||
|
||||
if args.list_countries {
|
||||
return print_countries(args.timeout)
|
||||
return print_countries(try, args.timeout)
|
||||
}
|
||||
|
||||
mainLogger.Info("hola-proxy client version %s is starting...", version)
|
||||
if args.extVer == "" {
|
||||
ctx, cl := context.WithTimeout(context.Background(), args.timeout)
|
||||
defer cl()
|
||||
extVer, err := GetExtVer(ctx, nil, HolaExtStoreID, dialer)
|
||||
err := try("get latest version of browser extension", func() error {
|
||||
ctx, cl := context.WithTimeout(context.Background(), args.timeout)
|
||||
defer cl()
|
||||
extVer, err := GetExtVer(ctx, nil, HolaExtStoreID, dialer)
|
||||
args.extVer = extVer
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
mainLogger.Critical("Can't detect latest API version. Try to specify -ext-ver parameter. Error: %v", err)
|
||||
return 8
|
||||
}
|
||||
args.extVer = extVer
|
||||
mainLogger.Warning("Detected latest extension version: %q. Pass -ext-ver parameter to skip resolve and speedup startup", args.extVer)
|
||||
cl()
|
||||
}
|
||||
if args.list_proxies {
|
||||
return print_proxies(mainLogger, args.extVer, args.country, args.proxy_type, args.limit, args.timeout,
|
||||
return print_proxies(try, mainLogger, args.extVer, args.country, args.proxy_type, args.limit, args.timeout,
|
||||
args.backoffInitial, args.backoffDeadline)
|
||||
}
|
||||
|
||||
mainLogger.Info("hola-proxy client version %s is starting...", version)
|
||||
mainLogger.Info("Constructing fallback DNS upstream...")
|
||||
resolver, err := NewResolver(args.resolver, args.timeout)
|
||||
if err != nil {
|
||||
@@ -209,11 +217,16 @@ func run() int {
|
||||
return 6
|
||||
}
|
||||
|
||||
mainLogger.Info("Initializing configuration provider...")
|
||||
auth, tunnels, err := CredService(args.rotate, args.timeout, args.extVer, args.country,
|
||||
args.proxy_type, credLogger, args.backoffInitial, args.backoffDeadline)
|
||||
var (
|
||||
auth AuthProvider
|
||||
tunnels *ZGetTunnelsResponse
|
||||
)
|
||||
err = try("run credentials service", func() error {
|
||||
auth, tunnels, err = CredService(args.rotate, args.timeout, args.extVer, args.country,
|
||||
args.proxy_type, credLogger, args.backoffInitial, args.backoffDeadline)
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
mainLogger.Critical("Unable to instantiate credential service: %v", err)
|
||||
return 4
|
||||
}
|
||||
endpoint, err := get_endpoint(tunnels, args.proxy_type, args.use_trial, args.force_port_field)
|
||||
@@ -236,3 +249,24 @@ func run() int {
|
||||
func main() {
|
||||
os.Exit(run())
|
||||
}
|
||||
|
||||
func retryPolicy(retries int, retryInterval time.Duration, logger *CondLogger) func(string, func() error) error {
|
||||
return func(name string, f func() error) error {
|
||||
var err error
|
||||
for i := 1; retries <= 0 || i <= retries; i++ {
|
||||
if i > 1 {
|
||||
logger.Warning("Retrying action %q in %v...", name, retryInterval)
|
||||
time.Sleep(retryInterval)
|
||||
}
|
||||
logger.Info("Attempting action %q, attempt #%d...", name, i)
|
||||
err = f()
|
||||
if err == nil {
|
||||
logger.Info("Action %q succeeded on attempt #%d", name, i)
|
||||
return nil
|
||||
}
|
||||
logger.Warning("Action %q failed: %v", name, err)
|
||||
}
|
||||
logger.Critical("All attempts for action %q have failed. Last error: %v", name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: hola-proxy
|
||||
version: '1.13.4'
|
||||
version: '1.14.0'
|
||||
summary: Standalone Hola proxy client.
|
||||
description: |
|
||||
Standalone Hola proxy client. Just run it and it'll start plain HTTP proxy server forwarding traffic via Hola proxies of your choice.
|
||||
|
||||
68
utils.go
68
utils.go
@@ -106,27 +106,33 @@ func proxyh2(ctx context.Context, leftreader io.ReadCloser, leftwriter io.Writer
|
||||
return
|
||||
}
|
||||
|
||||
func print_countries(timeout time.Duration) int {
|
||||
func print_countries(try func(string, func() error) error, timeout time.Duration) int {
|
||||
var (
|
||||
countries CountryList
|
||||
err error
|
||||
tx_res bool
|
||||
tx_err error
|
||||
)
|
||||
tx_res, tx_err := EnsureTransaction(context.Background(), timeout, func(ctx context.Context, client *http.Client) bool {
|
||||
ctx1, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
countries, err = VPNCountries(ctx1, client)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction error: %v. Retrying with the fallback mechanism...\n", err)
|
||||
return false
|
||||
err = try("list VPN countries", func() error {
|
||||
tx_res, tx_err = EnsureTransaction(context.Background(), timeout, func(ctx context.Context, client *http.Client) bool {
|
||||
ctx1, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
countries, err = VPNCountries(ctx1, client)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction error: %v. Retrying with the fallback mechanism...\n", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
if tx_err != nil {
|
||||
return fmt.Errorf("transaction recovery mechanism failure: %v", err)
|
||||
}
|
||||
return true
|
||||
if !tx_res {
|
||||
return errors.New("all fallback proxies failed.")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if tx_err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction recovery mechanism failure: %v.\n", tx_err)
|
||||
return 4
|
||||
}
|
||||
if !tx_res {
|
||||
fmt.Fprintf(os.Stderr, "All attempts failed.")
|
||||
if err != nil {
|
||||
return 3
|
||||
}
|
||||
for _, code := range countries {
|
||||
@@ -135,28 +141,34 @@ func print_countries(timeout time.Duration) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func print_proxies(logger *CondLogger, extVer, country string, proxy_type string,
|
||||
func print_proxies(try func(string, func() error) error, logger *CondLogger, extVer, country string, proxy_type string,
|
||||
limit uint, timeout time.Duration, backoffInitial time.Duration, backoffDeadline time.Duration,
|
||||
) int {
|
||||
var (
|
||||
tunnels *ZGetTunnelsResponse
|
||||
user_uuid string
|
||||
err error
|
||||
tx_res bool
|
||||
tx_err error
|
||||
)
|
||||
tx_res, tx_err := EnsureTransaction(context.Background(), timeout, func(ctx context.Context, client *http.Client) bool {
|
||||
tunnels, user_uuid, err = Tunnels(ctx, logger, client, extVer, country, proxy_type, limit, timeout, backoffInitial, backoffDeadline)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction error: %v. Retrying with the fallback mechanism...\n", err)
|
||||
return false
|
||||
err = try("list proxies", func() error {
|
||||
tx_res, tx_err = EnsureTransaction(context.Background(), timeout, func(ctx context.Context, client *http.Client) bool {
|
||||
tunnels, user_uuid, err = Tunnels(ctx, logger, client, extVer, country, proxy_type, limit, timeout, backoffInitial, backoffDeadline)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction error: %v. Retrying with the fallback mechanism...\n", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
if tx_err != nil {
|
||||
return fmt.Errorf("transaction recovery mechanism failure: %v", err)
|
||||
}
|
||||
return true
|
||||
if !tx_res {
|
||||
return errors.New("all fallback proxies failed.")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if tx_err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Transaction recovery mechanism failure: %v.\n", tx_err)
|
||||
return 4
|
||||
}
|
||||
if !tx_res {
|
||||
fmt.Fprintf(os.Stderr, "All attempts failed.")
|
||||
if err != nil {
|
||||
return 3
|
||||
}
|
||||
wr := csv.NewWriter(os.Stdout)
|
||||
|
||||
Reference in New Issue
Block a user