mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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
|
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
|
// NewV2Repository returns a repository (v2 only). It creates a HTTP transport
|
||||||
// providing timeout settings and authentication support, and also verifies the
|
// providing timeout settings and authentication support, and also verifies the
|
||||||
// remote API version.
|
// 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
|
// TODO(dmcgowan): Call close idle connections when complete, use keep alive
|
||||||
base := &http.Transport{
|
base := &http.Transport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Proxy: http.ProxyFromEnvironment,
|
||||||
Dial: (&net.Dialer{
|
Dial: func(network, address string) (net.Conn, error) {
|
||||||
Timeout: 30 * time.Second,
|
dialer := &net.Dialer{
|
||||||
KeepAlive: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
DualStack: true,
|
KeepAlive: 30 * time.Second,
|
||||||
}).Dial,
|
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,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
TLSClientConfig: endpoint.TLSConfig,
|
TLSClientConfig: endpoint.TLSConfig,
|
||||||
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
// TODO(dmcgowan): Call close idle connections when complete and use keep alive
|
||||||
|
|
Loading…
Reference in a new issue