Update elazarl/goproxy
This commit is contained in:
67
vendor/github.com/elazarl/goproxy/https.go
generated
vendored
67
vendor/github.com/elazarl/goproxy/https.go
generated
vendored
@@ -10,8 +10,10 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
@@ -23,6 +25,7 @@ const (
|
||||
ConnectMitm
|
||||
ConnectHijack
|
||||
ConnectHTTPMitm
|
||||
ConnectProxyAuthHijack
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -30,6 +33,7 @@ var (
|
||||
MitmConnect = &ConnectAction{Action: ConnectMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)}
|
||||
HTTPMitmConnect = &ConnectAction{Action: ConnectHTTPMitm, TLSConfig: TLSConfigFromCA(&GoproxyCa)}
|
||||
RejectConnect = &ConnectAction{Action: ConnectReject, TLSConfig: TLSConfigFromCA(&GoproxyCa)}
|
||||
httpsRegexp = regexp.MustCompile(`^https:\/\/`)
|
||||
)
|
||||
|
||||
type ConnectAction struct {
|
||||
@@ -97,8 +101,25 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
ctx.Logf("Accepting CONNECT to %s", host)
|
||||
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
|
||||
go copyAndClose(ctx, targetSiteCon, proxyClient)
|
||||
go copyAndClose(ctx, proxyClient, targetSiteCon)
|
||||
|
||||
targetTCP, targetOK := targetSiteCon.(*net.TCPConn)
|
||||
proxyClientTCP, clientOK := proxyClient.(*net.TCPConn)
|
||||
if targetOK && clientOK {
|
||||
go copyAndClose(ctx, targetTCP, proxyClientTCP)
|
||||
go copyAndClose(ctx, proxyClientTCP, targetTCP)
|
||||
} else {
|
||||
go func() {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go copyOrWarn(ctx, targetSiteCon, proxyClient, &wg)
|
||||
go copyOrWarn(ctx, proxyClient, targetSiteCon, &wg)
|
||||
wg.Wait()
|
||||
proxyClient.Close()
|
||||
targetSiteCon.Close()
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
case ConnectHijack:
|
||||
ctx.Logf("Hijacking CONNECT to %s", host)
|
||||
proxyClient.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
|
||||
@@ -132,6 +153,7 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
httpError(proxyClient, ctx, err)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
}
|
||||
resp = proxy.filterResponse(resp, ctx)
|
||||
if err := resp.Write(proxyClient); err != nil {
|
||||
@@ -166,6 +188,7 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
clientTlsReader := bufio.NewReader(rawClientTls)
|
||||
for !isEof(clientTlsReader) {
|
||||
req, err := http.ReadRequest(clientTlsReader)
|
||||
var ctx = &ProxyCtx{Req: req, Session: atomic.AddInt64(&proxy.sess, 1), proxy: proxy}
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
@@ -175,7 +198,10 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
req.RemoteAddr = r.RemoteAddr // since we're converting the request, need to carry over the original connecting IP as well
|
||||
ctx.Logf("req %v", r.Host)
|
||||
req.URL, err = url.Parse("https://" + r.Host + req.URL.String())
|
||||
|
||||
if !httpsRegexp.MatchString(req.URL.String()) {
|
||||
req.URL, err = url.Parse("https://" + r.Host + req.URL.String())
|
||||
}
|
||||
|
||||
// Bug fix which goproxy fails to provide request
|
||||
// information URL in the context when does HTTPS MITM
|
||||
@@ -196,6 +222,8 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
ctx.Logf("resp %v", resp.Status)
|
||||
}
|
||||
resp = proxy.filterResponse(resp, ctx)
|
||||
defer resp.Body.Close()
|
||||
|
||||
text := resp.Status
|
||||
statusCode := strconv.Itoa(resp.StatusCode) + " "
|
||||
if strings.HasPrefix(text, statusCode) {
|
||||
@@ -234,6 +262,9 @@ func (proxy *ProxyHttpServer) handleHttps(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
ctx.Logf("Exiting on EOF")
|
||||
}()
|
||||
case ConnectProxyAuthHijack:
|
||||
proxyClient.Write([]byte("HTTP/1.1 407 Proxy Authentication Required\r\n"))
|
||||
todo.Hijack(r, proxyClient, ctx)
|
||||
case ConnectReject:
|
||||
if ctx.Resp != nil {
|
||||
if err := ctx.Resp.Write(proxyClient); err != nil {
|
||||
@@ -253,15 +284,20 @@ func httpError(w io.WriteCloser, ctx *ProxyCtx, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func copyAndClose(ctx *ProxyCtx, w, r net.Conn) {
|
||||
connOk := true
|
||||
if _, err := io.Copy(w, r); err != nil {
|
||||
connOk = false
|
||||
func copyOrWarn(ctx *ProxyCtx, dst io.Writer, src io.Reader, wg *sync.WaitGroup) {
|
||||
if _, err := io.Copy(dst, src); err != nil {
|
||||
ctx.Warnf("Error copying to client: %s", err)
|
||||
}
|
||||
if err := r.Close(); err != nil && connOk {
|
||||
ctx.Warnf("Error closing: %s", err)
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
func copyAndClose(ctx *ProxyCtx, dst, src *net.TCPConn) {
|
||||
if _, err := io.Copy(dst, src); err != nil {
|
||||
ctx.Warnf("Error copying to client: %s", err)
|
||||
}
|
||||
|
||||
dst.CloseWrite()
|
||||
src.CloseRead()
|
||||
}
|
||||
|
||||
func dialerFromEnv(proxy *ProxyHttpServer) func(network, addr string) (net.Conn, error) {
|
||||
@@ -305,8 +341,12 @@ func (proxy *ProxyHttpServer) NewConnectDialToProxy(https_proxy string) func(net
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
resp, _ := ioutil.ReadAll(resp.Body)
|
||||
resp, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Close()
|
||||
return nil, errors.New("proxy refused connection" + string(resp))
|
||||
}
|
||||
@@ -339,9 +379,12 @@ func (proxy *ProxyHttpServer) NewConnectDialToProxy(https_proxy string) func(net
|
||||
c.Close()
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 500))
|
||||
resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 500))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.Close()
|
||||
return nil, errors.New("proxy refused connection" + string(body))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user