Files
fasthttp/fasthttpproxy/http.go
T
Aoang ea6052464e Add Go 1.19 Support (#1355)
* Update Go Version to Go1.19.x And add cache

* Fix CI Line endings

* Update test CI Go Version to Go1.19.x And add cache

* Update Gosec Security Scanner CI to securego/gosec@v2.12.0

* Format comment

Go 1.19 adds support for links, lists, and clearer headings in doc comments. As part of this change, gofmt now reformats doc comments to make their rendered meaning clearer. See “Go Doc Comments” for syntax details and descriptions of common mistakes now highlighted by gofmt. As another part of this change, the new package go/doc/comment provides parsing and reformatting of doc comments as well as support for rendering them to HTML, Markdown, and text.

ref: https://tip.golang.org/doc/go1.19
ref: https://tip.golang.org/doc/comment

* Fix doc structure
2022-08-14 11:31:57 +02:00

80 lines
1.8 KiB
Go

package fasthttpproxy
import (
"bufio"
"encoding/base64"
"fmt"
"net"
"strings"
"time"
"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 FasthttpHTTPDialerTimeout(proxy, 0)
}
// FasthttpHTTPDialerTimeout returns a fasthttp.DialFunc that dials using
// the provided HTTP proxy using the given timeout.
//
// Example usage:
//
// c := &fasthttp.Client{
// Dial: fasthttpproxy.FasthttpHTTPDialerTimeout("username:password@localhost:9050", time.Second * 2),
// }
func FasthttpHTTPDialerTimeout(proxy string, timeout time.Duration) fasthttp.DialFunc {
var auth string
if strings.Contains(proxy, "@") {
split := strings.Split(proxy, "@")
auth = base64.StdEncoding.EncodeToString([]byte(split[0]))
proxy = split[1]
}
return func(addr string) (net.Conn, error) {
var conn net.Conn
var err error
if timeout == 0 {
conn, err = fasthttp.Dial(proxy)
} else {
conn, err = fasthttp.DialTimeout(proxy, timeout)
}
if err != nil {
return nil, err
}
req := fmt.Sprintf("CONNECT %s HTTP/1.1\r\nHost: %s\r\n", addr, addr)
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: %s status code: %d", proxy, res.Header.StatusCode())
}
return conn, nil
}
}