From 54df169029f1c9f03afe9c830c9aa4ab0ad025d7 Mon Sep 17 00:00:00 2001 From: Erik Dubbelboer Date: Mon, 20 Apr 2020 18:30:10 +0200 Subject: [PATCH] Add fasthttpproxy.FasthttpHTTPDialer --- fasthttpproxy/http.go | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 fasthttpproxy/http.go diff --git a/fasthttpproxy/http.go b/fasthttpproxy/http.go new file mode 100644 index 0000000000..2879408aaf --- /dev/null +++ b/fasthttpproxy/http.go @@ -0,0 +1,61 @@ +package fasthttpproxy + +import ( + "bufio" + "encoding/base64" + "fmt" + "net" + "strings" + + "github.com/valyala/fasthttp" +) + +// FasthttpHTTPDialer returns a fasthttp.DialFunc that dials using +// the provided HTTP proxy. +// +// Example usage: +// c := &fasthttp.Client{ +// Dial: fasthttpproxy.FasthttpHTTPDialer("username:password@localhost:9050"), +// } +func FasthttpHTTPDialer(proxy string) fasthttp.DialFunc { + return func(addr string) (net.Conn, error) { + var auth string + + if strings.Contains(proxy, "@") { + split := strings.Split(proxy, "@") + auth = base64.StdEncoding.EncodeToString([]byte(split[0])) + proxy = split[1] + + } + + conn, err := fasthttp.Dial(proxy) + if err != nil { + return nil, err + } + + req := "CONNECT " + addr + " HTTP/1.1\r\n" + if auth != "" { + req += "Proxy-Authorization: Basic " + auth + "\r\n" + } + req += "\r\n" + + if _, err := conn.Write([]byte(req)); err != nil { + return nil, err + } + + res := fasthttp.AcquireResponse() + defer fasthttp.ReleaseResponse(res) + + res.SkipBody = true + + if err := res.Read(bufio.NewReader(conn)); err != nil { + conn.Close() + return nil, err + } + if res.Header.StatusCode() != 200 { + conn.Close() + return nil, fmt.Errorf("could not connect to proxy") + } + return conn, nil + } +}