Skip to content

Commit

Permalink
[+] fix: http closed connections now handled
Browse files Browse the repository at this point in the history
  • Loading branch information
Noooste committed Jul 23, 2024
1 parent 302148b commit 517aceb
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 58 deletions.
3 changes: 2 additions & 1 deletion connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ func (s *Session) initConn(req *Request) (conn *Conn, err error) {
}
} else {
if conn.Conn, err = (&net.Dialer{
Timeout: conn.TimeOut,
Timeout: conn.TimeOut,
KeepAlive: 30 * time.Second,
}).DialContext(s.ctx, "tcp", host); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion connection_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ func (c *proxyDialer) connect(req *http.Request, conn net.Conn, negotiatedProtoc
c.H2Conn = h2clientConn
c.conn = conn
c.h2Mu.Unlock()
return proxyConn, err
return proxyConn, nil
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ func GetLastChromeVersion() *tls.ClientHelloSpec {
return &tls.ClientHelloSpec{
CipherSuites: []uint16{
tls.GREASE_PLACEHOLDER,
tls.TLS_CHACHA20_POLY1305_SHA256,
tls.TLS_AES_128_GCM_SHA256,
tls.TLS_AES_256_GCM_SHA384,
tls.TLS_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
Expand Down
8 changes: 7 additions & 1 deletion response.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
func (s *Session) buildResponse(response *Response, httpResponse *http.Response) (err error) {
response.RawBody = httpResponse.Body
response.HttpResponse = httpResponse
response.Session = s

var (
wg sync.WaitGroup
Expand Down Expand Up @@ -60,7 +61,12 @@ func (s *Session) buildResponse(response *Response, httpResponse *http.Response)
}

func (r *Response) ReadBody() (body []byte, err error) {
defer r.HttpResponse.Body.Close()
defer func() {
_ = r.HttpResponse.Body.Close()
if r.HttpResponse.Close {
r.Session.Connections.Remove(r.HttpResponse.Request.URL)
}
}()
return io.ReadAll(r.HttpResponse.Body)
}

Expand Down
5 changes: 4 additions & 1 deletion session.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ func (s *Session) send(request *Request) (response *Response, err error) {
err = fmt.Errorf("timeout")
}

if strings.Contains(err.Error(), "use of closed network connection") {
s.Connections.Remove(request.parsedUrl)
}

s.dumpRequest(request, response, err)
s.logResponse(response, err)

Expand Down Expand Up @@ -344,7 +348,6 @@ func (s *Session) do(req *Request, args ...any) (resp *Response, err error) {
}
}
}

}

err = s.checkRedirect(req, reqs)
Expand Down
2 changes: 2 additions & 0 deletions structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ type Response struct {
Request *Request
// Length of content in the response.
ContentLength int64

Session *Session
}

// Context represents the context of a request. It holds the session, request,
Expand Down
41 changes: 0 additions & 41 deletions test/connection_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"github.com/Noooste/azuretls-client"
"os"
"testing"
"time"
)

var skipProxy bool
Expand Down Expand Up @@ -46,8 +45,6 @@ func TestProxyDialer(t *testing.T) {
}

func TestProxy(t *testing.T) {
t.SkipNow()

session := azuretls.NewSession()

if err := session.SetProxy(""); err == nil {
Expand Down Expand Up @@ -99,28 +96,8 @@ func TestProxy(t *testing.T) {
}
}

func TestProxy2(t *testing.T) {
t.SkipNow()

session := azuretls.NewSession()

session.H2Proxy = true
if err := session.SetProxy(os.Getenv("NON_SECURE_PROXY")); err != nil {
t.Fatal(err)
}

_, err := session.Get("https://tls.peet.ws/api/all")

if err != nil {
t.Fatal(err)
}
}

func TestProxy3(t *testing.T) {
t.SkipNow()

session := azuretls.NewSession()
session.H2Proxy = true

if err := session.SetProxy(os.Getenv("SECURE_PROXY")); err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -201,21 +178,3 @@ func TestProxy4(t *testing.T) {
t.Fatal("TestProxy failed, IP is not changed")
}
}

func TestBadProxy(t *testing.T) {
session := azuretls.NewSession()
defer session.Close()

session.SetTimeout(1 * time.Second)

if err := session.SetProxy("https://test.com"); err != nil {
t.Fatal(err)
}

_, err := session.Get("https://ipinfo.io/ip")

if err == nil || err.Error() != "proxy connection timeout" {
t.Fatal("TestBadProxy failed, expected error, got", err)
}

}
14 changes: 5 additions & 9 deletions test/connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,10 @@ func concurrency(session *azuretls.Session, wg *sync.WaitGroup, ok *int64) bool
defer wg.Done()

for i := 0; i < 10; i++ {
_, err2 := session.Get("https://example.com/")

if err2 != nil {
fmt.Println(err2)
return false
}

_, err2 = session.Get("http://example.com/")
_, err2 := session.Do(&azuretls.Request{
Method: "GET",
Url: "http://example.com/",
})

if err2 != nil {
fmt.Println(err2)
Expand Down Expand Up @@ -125,6 +121,6 @@ func TestHighConcurrency(t *testing.T) {
wait.Wait()

if atomic.LoadInt64(ok) < count-1 { //~1 request can fail
t.Fatal("TestHighConcurrency failed, expected: ", count, ", got: ", *ok)
t.Fatal("TestHighConcurrency failed, expected: ", count, ", got: ", ok)
}
}
20 changes: 17 additions & 3 deletions transport.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package azuretls

import (
"context"
http "github.com/Noooste/fhttp"
"github.com/Noooste/fhttp/http2"
"net"
"net/url"
"time"
)

func (s *Session) initTransport(browser string) (err error) {
Expand All @@ -27,12 +30,23 @@ func (s *Session) initHTTP1() {
s.Transport = &http.Transport{
TLSHandshakeTimeout: s.TimeOut,
ResponseHeaderTimeout: s.TimeOut,
Proxy: func(req *http.Request) (*url.URL, error) {
if s.ProxyDialer == nil {
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
s.Connections.mu.RLock()
defer s.Connections.mu.RUnlock()
rc := s.Connections.hosts[addr]
return rc.TLS, nil
},
Proxy: func(*http.Request) (*url.URL, error) {
if s.Proxy == "" {
return nil, nil
}
return s.ProxyDialer.ProxyURL, nil

return url.Parse(s.Proxy)
},
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
}

Expand Down

0 comments on commit 517aceb

Please sign in to comment.