-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Description
What version of Go are you using (go version
)?
$ go version go version go1.16.10 linux/amd64
Does this issue reproduce with the latest release?
go1.16.10, which is the latest release of go1.16, is affected.
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOHOSTARCH="amd64" GOHOSTOS="linux"
What did you do?
go run the source code below:
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
)
func main() {
tr := http.DefaultTransport.(*http.Transport).Clone()
dialContext := tr.DialContext
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
conn, err := dialContext(ctx, network, addr)
if err != nil {
return conn, err
}
fmt.Printf("%v -> %v\n", addr, conn.RemoteAddr())
return conn, nil
}
c := http.Client{
Transport: tr,
}
for i := 0; i < 2; i++ {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://example.com", nil)
if err != nil {
panic(err)
}
req.Close = true
resp, err := c.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
io.ReadAll(resp.Body)
fmt.Println("body read")
}
}
With go1.16.9, it outputs:
example.com:443 -> 93.184.216.34:443
body read
example.com:443 -> 93.184.216.34:443
body read
IP address lookup is done per request and connection is not reused. Note that connection is HTTP/2.
With go1.16.10, it outputs:
example.com:443 -> 93.184.216.34:443
body read
body read
Notice that IP address lookup is done once and the connection is reused for the second request.
This contradicts the documentation of Request.Close:
// Close indicates whether to close the connection after
// replying to this request (for servers) or after sending this
// request and reading its response (for clients).
//
// For server requests, the HTTP server handles this automatically
// and this field is not needed by Handlers.
//
// For client requests, setting this field prevents re-use of
// TCP connections between requests to the same hosts, as if
// Transport.DisableKeepAlives were set.
Close bool
If Transport.DisableKeepAlives is set to true, go1.16.10 does not reuse connection.
So go1.16.10 has a different behaviour between Transport.DisableKeepAlives and Request.Close.
What did you expect to see?
go1.16.10 should not reuse connection if Request.Close is set to true.
What did you see instead?
go1.16.10 reuses connection even if Request.Close is set to true.
tomasbareikis-home24 and aurelijusbanelis
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.