Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use the configured timeout as hard deadline for the raw connection wh… #110

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cffi_dist/.tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nodejs 20.10.0
golang 1.20
2 changes: 1 addition & 1 deletion cffi_dist/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
github.com/bogdanfinn/fhttp v0.5.27
github.com/bogdanfinn/tls-client v1.7.2
github.com/bogdanfinn/tls-client v1.7.3-proxy-connect
github.com/google/uuid v1.3.0
)

Expand Down
4 changes: 2 additions & 2 deletions cffi_dist/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/bogdanfinn/fhttp v0.5.27 h1:+glR3k8v5nxfUSk7+J3M246zEQ2yadhS0vLq1utK71A=
github.com/bogdanfinn/fhttp v0.5.27/go.mod h1:oJiYPG3jQTKzk/VFmogH8jxjH5yiv2rrOH48Xso2lrE=
github.com/bogdanfinn/tls-client v1.7.2 h1:vpL5qBYUfT9ueygEf1yLfymrXyUEZQatL25amfqGV8M=
github.com/bogdanfinn/tls-client v1.7.2/go.mod h1:pOGa2euqTbEkGNqE5idx5jKKfs9ytlyn3fwEw8RSP+g=
github.com/bogdanfinn/tls-client v1.7.3-proxy-connect h1:+9Yy9Q3DEsy0D6ZeerATNfV0S+36B4tl1AtkKPaWntQ=
github.com/bogdanfinn/tls-client v1.7.3-proxy-connect/go.mod h1:pOGa2euqTbEkGNqE5idx5jKKfs9ytlyn3fwEw8RSP+g=
github.com/bogdanfinn/utls v1.6.1 h1:dKDYAcXEyFFJ3GaWaN89DEyjyRraD1qb4osdEK89ass=
github.com/bogdanfinn/utls v1.6.1/go.mod h1:VXIbRZaiY/wHZc6Hu+DZ4O2CgTzjhjCg/Ou3V4r/39Y=
github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg=
Expand Down
8 changes: 4 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func NewHttpClient(logger Logger, options ...HttpClientOption) (HttpClient, erro
return nil, err
}

client, clientProfile, err := buildFromConfig(config)
client, clientProfile, err := buildFromConfig(logger, config)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -112,12 +112,12 @@ func validateConfig(_ *httpClientConfig) error {
return nil
}

func buildFromConfig(config *httpClientConfig) (*http.Client, profiles.ClientProfile, error) {
func buildFromConfig(logger Logger, config *httpClientConfig) (*http.Client, profiles.ClientProfile, error) {
var dialer proxy.ContextDialer
dialer = newDirectDialer(config.timeout, config.localAddr, config.dialer)

if config.proxyUrl != "" {
proxyDialer, err := newConnectDialer(config.proxyUrl, config.timeout, config.localAddr, config.dialer)
proxyDialer, err := newConnectDialer(config.proxyUrl, config.timeout, config.localAddr, config.dialer, logger)
if err != nil {
return nil, profiles.ClientProfile{}, err
}
Expand Down Expand Up @@ -221,7 +221,7 @@ func (c *httpClient) applyProxy() error {

if c.config.proxyUrl != "" {
c.logger.Debug("proxy url %s supplied - using proxy connect dialer", c.config.proxyUrl)
proxyDialer, err := newConnectDialer(c.config.proxyUrl, c.config.timeout, c.config.localAddr, c.config.dialer)
proxyDialer, err := newConnectDialer(c.config.proxyUrl, c.config.timeout, c.config.localAddr, c.config.dialer, c.logger)
if err != nil {
c.logger.Error("failed to create proxy connect dialer: %s", err.Error())
return err
Expand Down
29 changes: 27 additions & 2 deletions connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io"
"net"
"net/url"
"os"
"sync"
"time"

Expand Down Expand Up @@ -74,6 +75,7 @@ func (s *socksContextDialer) DialContext(ctx context.Context, network, address s

// connectDialer allows to configure one-time use HTTP CONNECT client
type connectDialer struct {
logger Logger
ProxyUrl url.URL
DefaultHeader http.Header

Expand All @@ -92,7 +94,7 @@ type connectDialer struct {
// newConnectDialer creates a dialer to issue CONNECT requests and tunnel traffic via HTTP/S proxy.
// proxyUrlStr must provide Scheme and Host, may provide credentials and port.
// Example: https://username:[email protected]:443
func newConnectDialer(proxyUrlStr string, timeout time.Duration, localAddr *net.TCPAddr, configDialer net.Dialer) (proxy.ContextDialer, error) {
func newConnectDialer(proxyUrlStr string, timeout time.Duration, localAddr *net.TCPAddr, configDialer net.Dialer, logger Logger) (proxy.ContextDialer, error) {
proxyUrl, err := url.Parse(proxyUrlStr)
if err != nil {
return nil, err
Expand Down Expand Up @@ -126,6 +128,7 @@ func newConnectDialer(proxyUrlStr string, timeout time.Duration, localAddr *net.
}

dialer := &connectDialer{
logger: logger,
ProxyUrl: *proxyUrl,
Dialer: _dialer,
Timeout: timeout,
Expand Down Expand Up @@ -219,6 +222,7 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
_ = rawConn.Close()
return nil, errors.New("Proxy responded with non 200 code: " + resp.Status)
}

return newHttp2Conn(rawConn, pw, resp.Body), nil
}

Expand All @@ -227,14 +231,29 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
req.ProtoMajor = 1
req.ProtoMinor = 1

err := req.Write(rawConn)
deadline := time.Now().Add(c.Timeout)
err := rawConn.SetDeadline(deadline)
if err != nil {
_ = rawConn.Close()
return nil, err
}

err = req.Write(rawConn)
if err != nil {
if errors.Is(err, os.ErrDeadlineExceeded) {
c.logger.Error("deadline exceeded while trying to write proxy connection")
}

_ = rawConn.Close()
return nil, err
}

resp, err := http.ReadResponse(bufio.NewReader(rawConn), req)
if err != nil {
if errors.Is(err, os.ErrDeadlineExceeded) {
c.logger.Error("deadline exceeded while trying to read proxy connection")
}

_ = rawConn.Close()
return nil, err
}
Expand All @@ -243,6 +262,9 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
_ = rawConn.Close()
return nil, errors.New("Proxy responded with non 200 code: " + resp.Status)
}

rawConn.SetDeadline(time.Time{})

return rawConn, nil
}

Expand All @@ -255,6 +277,7 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
cc := c.cachedH2ClientConn
c.cacheH2Mu.Unlock()
unlocked = true

proxyConn, err := connectHttp2(rc, cc)
if err == nil {
return proxyConn, err
Expand All @@ -273,6 +296,7 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
switch c.ProxyUrl.Scheme {
case "http":
rawConn, err = c.Dialer.DialContext(ctx, network, c.ProxyUrl.Host)

if err != nil {
return nil, err
}
Expand Down Expand Up @@ -320,6 +344,7 @@ func (c *connectDialer) DialContext(ctx context.Context, network, address string
_ = rawConn.Close()
return nil, err
}

if c.EnableH2ConnReuse {
c.cacheH2Mu.Lock()
c.cachedH2ClientConn = h2clientConn
Expand Down