Set idle timeouts for HTTP reads and writes in communications with the registry
Otherwise, some operations can get stuck indefinitely when the remote side is unresponsive. Fixes #12823 Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
b5420be597
commit
84b2162c1a
1 changed files with 40 additions and 5 deletions
|
@ -45,6 +45,30 @@ func (dcs dumbCredentialStore) Basic(*url.URL) (string, string) {
|
|||
return dcs.auth.Username, dcs.auth.Password
|
||||
}
|
||||
|
||||
// conn wraps a net.Conn, and sets a deadline for every read
|
||||
// and write operation.
|
||||
type conn struct {
|
||||
net.Conn
|
||||
readTimeout time.Duration
|
||||
writeTimeout time.Duration
|
||||
}
|
||||
|
||||
func (c *conn) Read(b []byte) (int, error) {
|
||||
err := c.Conn.SetReadDeadline(time.Now().Add(c.readTimeout))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.Conn.Read(b)
|
||||
}
|
||||
|
||||
func (c *conn) Write(b []byte) (int, error) {
|
||||
err := c.Conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return c.Conn.Write(b)
|
||||
}
|
||||
|
||||
// NewV2Repository returns a repository (v2 only). It creates a HTTP transport
|
||||
// providing timeout settings and authentication support, and also verifies the
|
||||
// remote API version.
|
||||
|
@ -58,11 +82,22 @@ func NewV2Repository(ctx context.Context, repoInfo *registry.RepositoryInfo, end
|
|||
// TODO(dmcgowan): Call close idle connections when complete, use keep alive
|
||||
base := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).Dial,
|
||||
Dial: func(network, address string) (net.Conn, error) {
|
||||
dialer := &net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}
|
||||
netConn, err := dialer.Dial(network, address)
|
||||
if err != nil {
|
||||
return netConn, err
|
||||
}
|
||||
return &conn{
|
||||
Conn: netConn,
|
||||
readTimeout: time.Minute,
|
||||
writeTimeout: time.Minute,
|
||||
}, nil
|
||||
},
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
TLSClientConfig: endpoint.TLSConfig,
|
||||
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
||||
|
|
Loading…
Reference in a new issue