mirror of
https://github.com/Snawoot/hola-proxy.git
synced 2026-04-06 00:18:14 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60eee4ad84 | ||
|
|
223105b010 | ||
|
|
b93ba7718c | ||
|
|
8660c52f26 | ||
|
|
a003e75cb4 | ||
|
|
173fbd5d98 |
107
extver.go
Normal file
107
extver.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultProdVersion = "113.0"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoVerData = errors.New("no version data returned")
|
||||
)
|
||||
|
||||
type StoreExtUpdateResponse struct {
|
||||
XMLName xml.Name `xml:"gupdate"`
|
||||
App *struct {
|
||||
AppID string `xml:"appid,attr"`
|
||||
Status string `xml:"status,attr"`
|
||||
UpdateCheck *struct {
|
||||
Version string `xml:"version,attr"`
|
||||
Status string `xml:"status,attr"`
|
||||
} `xml:"updatecheck"`
|
||||
} `xml:"app"`
|
||||
}
|
||||
|
||||
func GetExtVer(ctx context.Context,
|
||||
prodVersion *string,
|
||||
id string,
|
||||
dialer ContextDialer,
|
||||
) (string, error) {
|
||||
if prodVersion == nil {
|
||||
prodVersion = &defaultProdVersion
|
||||
}
|
||||
if dialer == nil {
|
||||
dialer = &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
DialContext: dialer.DialContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
defer transport.CloseIdleConnections()
|
||||
httpClient := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
reqURL := (&url.URL{
|
||||
Scheme: "https",
|
||||
Host: "clients2.google.com",
|
||||
Path: "/service/update2/crx",
|
||||
RawQuery: url.Values{
|
||||
"prodversion": {*prodVersion},
|
||||
"acceptformat": {"crx2,crx3"},
|
||||
"x": {url.Values{
|
||||
"id": {id},
|
||||
"uc": {""},
|
||||
}.Encode()},
|
||||
}.Encode(),
|
||||
}).String()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", reqURL, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("chrome web store request construction failed: %w", err)
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("chrome web store request failed: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return "", fmt.Errorf("bad status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
reader := io.LimitReader(resp.Body, 64*1024)
|
||||
var respData *StoreExtUpdateResponse
|
||||
|
||||
dec := xml.NewDecoder(reader)
|
||||
err = dec.Decode(&respData)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unmarshaling of chrome web store response failed: %w", err)
|
||||
}
|
||||
|
||||
if respData != nil && respData.App != nil &&
|
||||
respData.App.UpdateCheck != nil && respData.App.UpdateCheck.Version != "" {
|
||||
return respData.App.UpdateCheck.Version, nil
|
||||
}
|
||||
|
||||
return "", ErrNoVerData
|
||||
}
|
||||
19
main.go
19
main.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
@@ -17,6 +18,10 @@ import (
|
||||
xproxy "golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
const (
|
||||
HolaExtStoreID = "gkojfkhlekighikafcpjkiklfbnlmeio"
|
||||
)
|
||||
|
||||
var (
|
||||
PROTOCOL_WHITELIST map[string]bool
|
||||
version = "undefined"
|
||||
@@ -63,7 +68,7 @@ type CLIArgs struct {
|
||||
|
||||
func parse_args() CLIArgs {
|
||||
var args CLIArgs
|
||||
flag.StringVar(&args.extVer, "ext-ver", "999.999.999", "extension version to mimic in requests. "+
|
||||
flag.StringVar(&args.extVer, "ext-ver", "", "extension version to mimic in requests. "+
|
||||
"Can be obtained from https://chrome.google.com/webstore/detail/hola-vpn-the-website-unbl/gkojfkhlekighikafcpjkiklfbnlmeio")
|
||||
flag.StringVar(&args.force_port_field, "force-port-field", "", "force specific port field/num (example 24232 or lum)") // would be nice to not show in help page
|
||||
flag.StringVar(&args.country, "country", "us", "desired proxy location")
|
||||
@@ -173,6 +178,18 @@ func run() int {
|
||||
return print_countries(args.timeout)
|
||||
}
|
||||
|
||||
if args.extVer == "" {
|
||||
ctx, cl := context.WithTimeout(context.Background(), args.timeout)
|
||||
defer cl()
|
||||
extVer, err := GetExtVer(ctx, nil, HolaExtStoreID, dialer)
|
||||
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,
|
||||
args.backoffInitial, args.backoffDeadline)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: hola-proxy
|
||||
version: '1.8.0'
|
||||
version: '1.9.1'
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user