tls handshake timeout in http.Client

545 views
Skip to first unread message

Daniel Gottlieb

unread,
Jan 13, 2014, 3:48:46 PM1/13/14
to golan...@googlegroups.com
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?
Reply all
Reply to author
Forward
0 new messages