Skip to content

Commit c34a697

Browse files
committed
fix: timeout should close connection also when body reading started
1 parent dd13cb7 commit c34a697

File tree

2 files changed

+22
-23
lines changed

2 files changed

+22
-23
lines changed

helper/clickhouse/clickhouse.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,7 @@ func sendRequestWithProgressCheck(request *http.Request, opts *Options) (*http.R
484484
DisableKeepAlives: true,
485485
}
486486

487-
ctx, cancel := context.WithTimeout(context.Background(), opts.Timeout)
488-
defer cancel()
489-
490-
return httpHelper.DoHTTPOverTCP(ctx, transport, request)
487+
return httpHelper.DoHTTPOverTCP(request.Context(), transport, request, opts.Timeout)
491488
}
492489

493490
func do(ctx context.Context, dsn string, query string, postBody io.Reader, encoding ContentEncoding, opts Options, extData *ExternalData) ([]byte, int64, int64, error) {

helper/http/live-http-client.go

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ import (
55
"bytes"
66
"context"
77
"io"
8+
"net"
89
"net/http"
10+
"time"
911
)
1012

1113
const TCPNetwork string = "tcp"
1214

13-
func DoHTTPOverTCP(ctx context.Context, transport *http.Transport, req *http.Request) (*http.Response, error) {
14-
conn, err := transport.DialContext(context.Background(), TCPNetwork, req.URL.Host)
15+
func DoHTTPOverTCP(ctx context.Context, transport *http.Transport, req *http.Request, timeout time.Duration) (*http.Response, error) {
16+
conn, err := transport.DialContext(ctx, TCPNetwork, req.URL.Host)
17+
if err != nil {
18+
return nil, err
19+
}
20+
err = conn.SetDeadline(time.Now().Add(timeout))
1521
if err != nil {
1622
return nil, err
1723
}
@@ -24,25 +30,21 @@ func DoHTTPOverTCP(ctx context.Context, transport *http.Transport, req *http.Req
2430
var backup_buf bytes.Buffer
2531
reader := bufio.NewReader(io.TeeReader(conn, &backup_buf))
2632

27-
HEADERS:
2833
for {
29-
select {
30-
case <- ctx.Done():
31-
fake_body_delimer := bytes.NewBuffer([]byte{'\r', '\n', '\r', '\n'})
32-
resp, err := http.ReadResponse(bufio.NewReader(io.MultiReader(&backup_buf, fake_body_delimer)), nil)
33-
if err != nil {
34-
return nil, err
35-
}
36-
return resp, ctx.Err()
37-
38-
default:
39-
line, err := reader.ReadString('\n')
40-
if err != nil {
41-
return nil, err
42-
}
43-
if line == "\r\n" {
44-
break HEADERS
34+
line, err := reader.ReadString('\n')
35+
if err != nil {
36+
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
37+
fake_body_delimer := bytes.NewBuffer([]byte{'\r', '\n', '\r', '\n'})
38+
resp, err := http.ReadResponse(bufio.NewReader(io.MultiReader(&backup_buf, fake_body_delimer)), nil)
39+
if err != nil {
40+
return nil, err
41+
}
42+
return resp, netErr
4543
}
44+
return nil, err
45+
}
46+
if line == "\r\n" {
47+
break
4648
}
4749
}
4850

0 commit comments

Comments
 (0)