From 523841f2f9c92e0730f3a087c175c3cc1bf46952 Mon Sep 17 00:00:00 2001 From: yangshukui Date: Thu, 8 Jun 2017 15:46:50 +0800 Subject: [PATCH] Add a error check in postHijacked to avoid docker exec command blocking. When user execute docker exec command, docker daemon maybe have err return because of ExecExists check, and then the hijack stream will not be close, it can lead to docker exec command block. Signed-off-by: yangshukui Upstream-commit: 26231b29e7881d25822bffd740d5f73fc2687460 Component: engine --- components/engine/client/hijack.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/components/engine/client/hijack.go b/components/engine/client/hijack.go index 74c53f52b3..2b61a80950 100644 --- a/components/engine/client/hijack.go +++ b/components/engine/client/hijack.go @@ -1,9 +1,11 @@ package client import ( + "bytes" "crypto/tls" "errors" "fmt" + "io/ioutil" "net" "net/http" "net/http/httputil" @@ -72,11 +74,23 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu defer clientconn.Close() // Server hijacks the connection, error 'connection closed' expected - _, err = clientconn.Do(req) + resp, err := clientconn.Do(req) + if err != nil { + return types.HijackedResponse{}, err + } - rwc, br := clientconn.Hijack() + defer resp.Body.Close() + switch resp.StatusCode { + case http.StatusOK, http.StatusSwitchingProtocols: + rwc, br := clientconn.Hijack() + return types.HijackedResponse{Conn: rwc, Reader: br}, err + } - return types.HijackedResponse{Conn: rwc, Reader: br}, err + errbody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return types.HijackedResponse{}, err + } + return types.HijackedResponse{}, fmt.Errorf("Error response from daemon: %s", bytes.TrimSpace(errbody)) } func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {