diff --git a/client/container_attach.go b/client/container_attach.go index ba92117d3e..a3a009050d 100644 --- a/client/container_attach.go +++ b/client/container_attach.go @@ -2,6 +2,7 @@ package client // import "github.com/docker/docker/client" import ( "context" + "net/http" "net/url" "github.com/docker/docker/api/types" @@ -52,8 +53,7 @@ func (cli *Client) ContainerAttach(ctx context.Context, container string, option query.Set("logs", "1") } - headers := map[string][]string{ + return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, http.Header{ "Content-Type": {"text/plain"}, - } - return cli.postHijacked(ctx, "/containers/"+container+"/attach", query, nil, headers) + }) } diff --git a/client/container_exec.go b/client/container_exec.go index 6a2cb006f8..402d1b8394 100644 --- a/client/container_exec.go +++ b/client/container_exec.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" + "net/http" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions" @@ -46,10 +47,9 @@ func (cli *Client) ContainerExecAttach(ctx context.Context, execID string, confi if versions.LessThan(cli.ClientVersion(), "1.42") { config.ConsoleSize = nil } - headers := map[string][]string{ + return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, http.Header{ "Content-Type": {"application/json"}, - } - return cli.postHijacked(ctx, "/exec/"+execID+"/start", nil, config, headers) + }) } // ContainerExecInspect returns information about a specific exec process on the docker host. diff --git a/client/distribution_inspect.go b/client/distribution_inspect.go index efab066d3b..0fb156245f 100644 --- a/client/distribution_inspect.go +++ b/client/distribution_inspect.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" + "net/http" "net/url" "github.com/docker/docker/api/types/registry" @@ -19,10 +20,10 @@ func (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegist if err := cli.NewVersionError("1.30", "distribution inspect"); err != nil { return distributionInspect, err } - var headers map[string][]string + var headers http.Header if encodedRegistryAuth != "" { - headers = map[string][]string{ + headers = http.Header{ registry.AuthHeader: {encodedRegistryAuth}, } } diff --git a/client/image_build.go b/client/image_build.go index d16e1d8ea9..d1f32ac904 100644 --- a/client/image_build.go +++ b/client/image_build.go @@ -23,13 +23,13 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio return types.ImageBuildResponse{}, err } - headers := http.Header(make(map[string][]string)) buf, err := json.Marshal(options.AuthConfigs) if err != nil { return types.ImageBuildResponse{}, err } - headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) + headers := http.Header{} + headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) headers.Set("Content-Type", "application/x-tar") serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) @@ -37,11 +37,9 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio return types.ImageBuildResponse{}, err } - osType := getDockerOS(serverResp.header.Get("Server")) - return types.ImageBuildResponse{ Body: serverResp.body, - OSType: osType, + OSType: getDockerOS(serverResp.header.Get("Server")), }, nil } diff --git a/client/image_create.go b/client/image_create.go index 6a9b708f7d..b35781c233 100644 --- a/client/image_create.go +++ b/client/image_create.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" + "net/http" "net/url" "strings" @@ -33,6 +34,7 @@ func (cli *Client) ImageCreate(ctx context.Context, parentReference string, opti } func (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.post(ctx, "/images/create", query, nil, headers) + return cli.post(ctx, "/images/create", query, nil, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } diff --git a/client/image_load.go b/client/image_load.go index 91016e493c..c825206ea5 100644 --- a/client/image_load.go +++ b/client/image_load.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" + "net/http" "net/url" "github.com/docker/docker/api/types" @@ -17,8 +18,9 @@ func (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) ( if quiet { v.Set("quiet", "1") } - headers := map[string][]string{"Content-Type": {"application/x-tar"}} - resp, err := cli.postRaw(ctx, "/images/load", v, input, headers) + resp, err := cli.postRaw(ctx, "/images/load", v, input, http.Header{ + "Content-Type": {"application/x-tar"}, + }) if err != nil { return types.ImageLoadResponse{}, err } diff --git a/client/image_push.go b/client/image_push.go index dd1b8f3471..87e315475b 100644 --- a/client/image_push.go +++ b/client/image_push.go @@ -4,6 +4,7 @@ import ( "context" "errors" "io" + "net/http" "net/url" "github.com/docker/distribution/reference" @@ -50,6 +51,7 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im } func (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.post(ctx, "/images/"+imageID+"/push", query, nil, headers) + return cli.post(ctx, "/images/"+imageID+"/push", query, nil, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } diff --git a/client/image_search.go b/client/image_search.go index 5f0c49ed30..8971b139ae 100644 --- a/client/image_search.go +++ b/client/image_search.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" + "net/http" "net/url" "strconv" @@ -48,6 +49,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options types.I } func (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.get(ctx, "/images/search", query, headers) + return cli.get(ctx, "/images/search", query, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } diff --git a/client/plugin_install.go b/client/plugin_install.go index 3a740ec4f6..7eb6a7ec1f 100644 --- a/client/plugin_install.go +++ b/client/plugin_install.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "io" + "net/http" "net/url" "github.com/docker/distribution/reference" @@ -68,13 +69,15 @@ func (cli *Client) PluginInstall(ctx context.Context, name string, options types } func (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.get(ctx, "/plugins/privileges", query, headers) + return cli.get(ctx, "/plugins/privileges", query, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } func (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.post(ctx, "/plugins/pull", query, privileges, headers) + return cli.post(ctx, "/plugins/pull", query, privileges, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } func (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) { diff --git a/client/plugin_push.go b/client/plugin_push.go index 18f9754c4c..8f68a86eee 100644 --- a/client/plugin_push.go +++ b/client/plugin_push.go @@ -3,14 +3,16 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" + "net/http" "github.com/docker/docker/api/types/registry" ) // PluginPush pushes a plugin to a registry func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers) + resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, http.Header{ + registry.AuthHeader: {registryAuth}, + }) if err != nil { return nil, err } diff --git a/client/plugin_upgrade.go b/client/plugin_upgrade.go index 995d1fd2ca..646335016f 100644 --- a/client/plugin_upgrade.go +++ b/client/plugin_upgrade.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "io" + "net/http" "net/url" "github.com/docker/distribution/reference" @@ -35,6 +36,7 @@ func (cli *Client) PluginUpgrade(ctx context.Context, name string, options types } func (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) { - headers := map[string][]string{registry.AuthHeader: {registryAuth}} - return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, headers) + return cli.post(ctx, "/plugins/"+name+"/upgrade", query, privileges, http.Header{ + registry.AuthHeader: {registryAuth}, + }) } diff --git a/client/request.go b/client/request.go index 4ca1ac7db2..edae0611e5 100644 --- a/client/request.go +++ b/client/request.go @@ -28,17 +28,17 @@ type serverResponse struct { } // head sends an http request to the docker API using the method HEAD. -func (cli *Client) head(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { +func (cli *Client) head(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) { return cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers) } // get sends an http request to the docker API using the method GET with a specific Go context. -func (cli *Client) get(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { +func (cli *Client) get(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) { return cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers) } // post sends an http request to the docker API using the method POST with a specific Go context. -func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { +func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) { body, headers, err := encodeBody(obj, headers) if err != nil { return serverResponse{}, err @@ -46,11 +46,11 @@ func (cli *Client) post(ctx context.Context, path string, query url.Values, obj return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) } -func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { +func (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) { return cli.sendRequest(ctx, http.MethodPost, path, query, body, headers) } -func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) { +func (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) { body, headers, err := encodeBody(obj, headers) if err != nil { return serverResponse{}, err @@ -59,7 +59,7 @@ func (cli *Client) put(ctx context.Context, path string, query url.Values, obj i } // putRaw sends an http request to the docker API using the method PUT. -func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers map[string][]string) (serverResponse, error) { +func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) { // PUT requests are expected to always have a body (apparently) // so explicitly pass an empty body to sendRequest to signal that // it should set the Content-Type header if not already present. @@ -70,13 +70,11 @@ func (cli *Client) putRaw(ctx context.Context, path string, query url.Values, bo } // delete sends an http request to the docker API using the method DELETE. -func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers map[string][]string) (serverResponse, error) { +func (cli *Client) delete(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) { return cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers) } -type headers map[string][]string - -func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) { +func encodeBody(obj interface{}, headers http.Header) (io.Reader, http.Header, error) { if obj == nil { return nil, headers, nil } @@ -98,7 +96,7 @@ func encodeBody(obj interface{}, headers headers) (io.Reader, headers, error) { return body, headers, nil } -func (cli *Client) buildRequest(method, path string, body io.Reader, headers headers) (*http.Request, error) { +func (cli *Client) buildRequest(method, path string, body io.Reader, headers http.Header) (*http.Request, error) { req, err := http.NewRequest(method, path, body) if err != nil { return nil, err @@ -123,7 +121,7 @@ func (cli *Client) buildRequest(method, path string, body io.Reader, headers hea return req, nil } -func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers headers) (serverResponse, error) { +func (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) { req, err := cli.buildRequest(method, cli.getAPIPath(ctx, path, query), body, headers) if err != nil { return serverResponse{}, err @@ -161,19 +159,19 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp return serverResp, err } - if nErr, ok := err.(*url.Error); ok { - if nErr, ok := nErr.Err.(*net.OpError); ok { + if uErr, ok := err.(*url.Error); ok { + if nErr, ok := uErr.Err.(*net.OpError); ok { if os.IsPermission(nErr.Err) { return serverResp, errors.Wrapf(err, "permission denied while trying to connect to the Docker daemon socket at %v", cli.host) } } } - if err, ok := err.(net.Error); ok { - if err.Timeout() { + if nErr, ok := err.(net.Error); ok { + if nErr.Timeout() { return serverResp, ErrorConnectionFailed(cli.host) } - if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "dial unix") { + if strings.Contains(nErr.Error(), "connection refused") || strings.Contains(nErr.Error(), "dial unix") { return serverResp, ErrorConnectionFailed(cli.host) } } @@ -253,7 +251,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error { return errors.Wrap(errors.New(errorMessage), "Error response from daemon") } -func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request { +func (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request { // Add CLI Config's HTTP Headers BEFORE we set the Docker headers // then the user can't change OUR headers for k, v := range cli.customHTTPHeaders { diff --git a/client/service_create.go b/client/service_create.go index 76771690c8..2905f1e85b 100644 --- a/client/service_create.go +++ b/client/service_create.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "net/http" "strings" "github.com/docker/distribution/reference" @@ -47,7 +48,7 @@ func (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, } } - headers := map[string][]string{} + headers := http.Header{} if versions.LessThan(cli.version, "1.30") { // the custom "version" header was used by engine API before 20.10 // (API 1.30) to switch between client- and server-side lookup of diff --git a/client/service_update.go b/client/service_update.go index f30aaa0893..a27cea0d96 100644 --- a/client/service_update.go +++ b/client/service_update.go @@ -3,6 +3,7 @@ package client // import "github.com/docker/docker/client" import ( "context" "encoding/json" + "net/http" "net/url" "github.com/docker/docker/api/types" @@ -53,7 +54,7 @@ func (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version } } - headers := map[string][]string{} + headers := http.Header{} if versions.LessThan(cli.version, "1.30") { // the custom "version" header was used by engine API before 20.10 // (API 1.30) to switch between client- and server-side lookup of