Merge pull request #27306 from stevvooe/deterministic-client-scheme
client: deterministically resolve http scheme
This commit is contained in:
commit
d3ee780bc5
3 changed files with 17 additions and 22 deletions
|
@ -63,6 +63,8 @@ const DefaultVersion string = "1.23"
|
|||
// Client is the API client that performs all operations
|
||||
// against a docker server.
|
||||
type Client struct {
|
||||
// scheme sets the scheme for the client
|
||||
scheme string
|
||||
// host holds the server address to connect to
|
||||
host string
|
||||
// proto holds the client protocol i.e. unix.
|
||||
|
@ -143,7 +145,19 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
|
|||
}
|
||||
}
|
||||
|
||||
scheme := "http"
|
||||
tlsConfig := resolveTLSConfig(client.Transport)
|
||||
if tlsConfig != nil {
|
||||
// TODO(stevvooe): This isn't really the right way to write clients in Go.
|
||||
// `NewClient` should probably only take an `*http.Client` and work from there.
|
||||
// Unfortunately, the model of having a host-ish/url-thingy as the connection
|
||||
// string has us confusing protocol and transport layers. We continue doing
|
||||
// this to avoid breaking existing clients but this should be addressed.
|
||||
scheme = "https"
|
||||
}
|
||||
|
||||
return &Client{
|
||||
scheme: scheme,
|
||||
host: host,
|
||||
proto: proto,
|
||||
addr: addr,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -26,20 +26,3 @@ func resolveTLSConfig(transport http.RoundTripper) *tls.Config {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// resolveScheme detects a tls config on the transport and returns the
|
||||
// appropriate http scheme.
|
||||
//
|
||||
// TODO(stevvooe): This isn't really the right way to write clients in Go.
|
||||
// `NewClient` should probably only take an `*http.Client` and work from there.
|
||||
// Unfortunately, the model of having a host-ish/url-thingy as the connection
|
||||
// string has us confusing protocol and transport layers. We continue doing
|
||||
// this to avoid breaking existing clients but this should be addressed.
|
||||
func resolveScheme(transport http.RoundTripper) string {
|
||||
c := resolveTLSConfig(transport)
|
||||
if c != nil {
|
||||
return "https"
|
||||
}
|
||||
|
||||
return "http"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue