mirror of
https://github.com/Snawoot/hola-proxy.git
synced 2026-04-02 05:38:15 +00:00
fixed plain HTTP request
This commit is contained in:
15
handler.go
15
handler.go
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -15,20 +16,28 @@ type ProxyHandler struct {
|
||||
logger *CondLogger
|
||||
dialer ContextDialer
|
||||
httptransport http.RoundTripper
|
||||
auth AuthProvider
|
||||
}
|
||||
|
||||
func NewProxyHandler(dialer ContextDialer, resolver *Resolver, logger *CondLogger) *ProxyHandler {
|
||||
func NewProxyHandler(dialer, requestDialer ContextDialer, auth AuthProvider, resolver *Resolver, logger *CondLogger) *ProxyHandler {
|
||||
dialer = NewRetryDialer(dialer, resolver, logger)
|
||||
httptransport := &http.Transport{
|
||||
Proxy: func(_ *http.Request) (*url.URL, error) {
|
||||
return &url.URL{
|
||||
Scheme: "http",
|
||||
Host: "void",
|
||||
}, nil
|
||||
},
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
DialContext: dialer.DialContext,
|
||||
DialContext: requestDialer.DialContext,
|
||||
}
|
||||
return &ProxyHandler{
|
||||
logger: logger,
|
||||
dialer: dialer,
|
||||
auth: auth,
|
||||
httptransport: httptransport,
|
||||
}
|
||||
}
|
||||
@@ -74,6 +83,8 @@ func (s *ProxyHandler) HandleRequest(wr http.ResponseWriter, req *http.Request)
|
||||
req.URL.Scheme = "http" // We can't access :scheme pseudo-header, so assume http
|
||||
req.URL.Host = req.Host
|
||||
}
|
||||
delHopHeaders(req.Header)
|
||||
req.Header.Add("Proxy-Authorization", s.auth())
|
||||
resp, err := s.httptransport.RoundTrip(req)
|
||||
if err != nil {
|
||||
s.logger.Error("HTTP fetch error: %v", err)
|
||||
|
||||
7
main.go
7
main.go
@@ -71,8 +71,8 @@ func parse_args() CLIArgs {
|
||||
"See https://github.com/ameshkov/dnslookup/ for upstream DNS URL format.")
|
||||
flag.BoolVar(&args.use_trial, "dont-use-trial", false, "use regular ports instead of trial ports") // would be nice to not show in help page
|
||||
flag.BoolVar(&args.showVersion, "version", false, "show program version and exit")
|
||||
flag.StringVar(&args.proxy, "proxy", "", "sets base proxy to use for all dial-outs. " +
|
||||
"Format: <http|https|socks5|socks5h>://[login:password@]host[:port] " +
|
||||
flag.StringVar(&args.proxy, "proxy", "", "sets base proxy to use for all dial-outs. "+
|
||||
"Format: <http|https|socks5|socks5h>://[login:password@]host[:port] "+
|
||||
"Examples: http://user:password@192.168.1.1:3128, socks5://10.0.0.1:1080")
|
||||
flag.Parse()
|
||||
if args.country == "" {
|
||||
@@ -164,9 +164,10 @@ func run() int {
|
||||
return 5
|
||||
}
|
||||
handlerDialer := NewProxyDialer(endpoint.NetAddr(), endpoint.TLSName, auth, dialer)
|
||||
requestDialer := NewPlaintextDialer(endpoint.NetAddr(), endpoint.TLSName, dialer)
|
||||
mainLogger.Info("Endpoint: %s", endpoint.URL().String())
|
||||
mainLogger.Info("Starting proxy server...")
|
||||
handler := NewProxyHandler(handlerDialer, resolver, proxyLogger)
|
||||
handler := NewProxyHandler(handlerDialer, requestDialer, auth, resolver, proxyLogger)
|
||||
mainLogger.Info("Init complete.")
|
||||
err = http.ListenAndServe(args.bind_address, handler)
|
||||
mainLogger.Critical("Server terminated with a reason: %v", err)
|
||||
|
||||
62
plaintext.go
Normal file
62
plaintext.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
type PlaintextDialer struct {
|
||||
fixedAddress string
|
||||
tlsServerName string
|
||||
next ContextDialer
|
||||
}
|
||||
|
||||
func NewPlaintextDialer(address, tlsServerName string, next ContextDialer) *PlaintextDialer {
|
||||
return &PlaintextDialer{
|
||||
fixedAddress: address,
|
||||
tlsServerName: tlsServerName,
|
||||
next: next,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *PlaintextDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
default:
|
||||
return nil, errors.New("bad network specified for DialContext: only tcp is supported")
|
||||
}
|
||||
|
||||
conn, err := d.next.DialContext(ctx, "tcp", d.fixedAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if d.tlsServerName != "" {
|
||||
// Custom cert verification logic:
|
||||
// DO NOT send SNI extension of TLS ClientHello
|
||||
// DO peer certificate verification against specified servername
|
||||
conn = tls.Client(conn, &tls.Config{
|
||||
ServerName: "",
|
||||
InsecureSkipVerify: true,
|
||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||
opts := x509.VerifyOptions{
|
||||
DNSName: d.tlsServerName,
|
||||
Intermediates: x509.NewCertPool(),
|
||||
}
|
||||
for _, cert := range cs.PeerCertificates[1:] {
|
||||
opts.Intermediates.AddCert(cert)
|
||||
}
|
||||
_, err := cs.PeerCertificates[0].Verify(opts)
|
||||
return err
|
||||
},
|
||||
})
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (d *PlaintextDialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(context.Background(), network, address)
|
||||
}
|
||||
Reference in New Issue
Block a user