Skip to content

Commit

Permalink
Merge pull request #45 from Snawoot/fix_http
Browse files Browse the repository at this point in the history
Fixed plain HTTP request
  • Loading branch information
Snawoot authored May 1, 2021
2 parents 4728548 + 70faaec commit 882bca3
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
15 changes: 13 additions & 2 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
)
Expand All @@ -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,
}
}
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 == "" {
Expand Down Expand Up @@ -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)
Expand Down
62 changes: 62 additions & 0 deletions plaintext.go
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit 882bca3

Please sign in to comment.