I have an `
http.Client` (using Go 1.2) that uses the standard recipe for defining a dial timeout:
var client = &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (conn net.Conn, err error) {
return net.DialTimeout(network, addr, 10*time.Second)
},
MaxIdleConnsPerHost: 5,
ResponseHeaderTimeout: 90 * time.Second,
},
}
This client sometimes makes `http` requests and sometimes `https`. I've observed that the handshaking process can hang (handshaking is performed on the returned connection from `Transport.Dial`). The internet is a dangerous place; these things happen. I was hoping this could be resolved by calling `conn.SetDeadline`:
var client = &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (conn net.Conn, err error) {
conn, err = net.DialTimeout(network, addr, 10*time.Second)
if err != nil {
return conn, err
}
// Set a one-time deadline for potential SSL handshaking
conn.SetDeadline(time.Now().Add(90 * time.Second))
return conn, nil
},
MaxIdleConnsPerHost: 5,
ResponseHeaderTimeout: 90 * time.Second,
},
}
I was under the assumption that `ResponseHeaderTimeout` was implemented on top of the same deadline mechanism offered by `net.Conn`, but unfortunately that is not the case. Is there a reasonable workaround for having deadlines/timeouts for the entire lifecycle of a keep-alive http connection (reasonable as in, not having to mostly copy/paste the existing `Transport.RoundTrip(*Request)` method)? Or perhaps I am missing something simple and looking at this in the wrong way?