client: deterministically resolve http scheme

The docker client has historically used Transport.TLSClientConfig to set
the scheme for the API client. A recent moved the resolution to use the
http.Transport directly, rather than save the TLSClientConfig state on a
client struct. This caused issues when mutliple calls made with a single
client would have this field set in the http package on pre-1.7
installations. This fix detects the presence of the TLSClientConfig once
and sets the scheme accordingly.

We still don't know why this issue doesn't happen with Go 1.7 but it
must be more deterministic in the newer version.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day
2016-10-11 15:53:14 -07:00
parent bc55f969b0
commit 4d1a6a43cd
3 changed files with 17 additions and 22 deletions
+3 -5
View File
@@ -100,10 +100,8 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q
req.Host = "docker"
}
scheme := resolveScheme(cli.client.Transport)
req.URL.Host = cli.addr
req.URL.Scheme = scheme
req.URL.Scheme = cli.scheme
if expectedPayload && req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "text/plain")
@@ -111,11 +109,11 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q
resp, err := ctxhttp.Do(ctx, cli.client, req)
if err != nil {
if scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") {
if cli.scheme != "https" && strings.Contains(err.Error(), "malformed HTTP response") {
return serverResp, fmt.Errorf("%v.\n* Are you trying to connect to a TLS-enabled daemon without TLS?", err)
}
if scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err)
}