From c648e163ebbe3bc5bf9b10b9390e41c0785a409b Mon Sep 17 00:00:00 2001 From: Stephen J Day Date: Thu, 8 Sep 2016 20:44:25 -0700 Subject: [PATCH] client: remove transport package This package doesn't really seem to do anything of real interest. Removing it and replacing with a few helper functions. Most of this was maintaining a fork of ctxhttp to support a mock that was unnecessary. We could probably do with a further refactor of the client interface. There is a lot of confusion of between transport, http layer and application layer that makes for some awkward code. This change improves the situation to the point where no breaking changes are introduced. Signed-off-by: Stephen J Day --- checkpoint_create_test.go | 4 +- checkpoint_delete_test.go | 4 +- checkpoint_list_test.go | 4 +- client.go | 20 +++-- client_mock_test.go | 37 +------- client_test.go | 2 +- container_commit_test.go | 4 +- container_copy_test.go | 20 ++--- container_create_test.go | 8 +- container_diff_test.go | 4 +- container_exec_test.go | 12 +-- container_export_test.go | 4 +- container_inspect_test.go | 8 +- container_kill_test.go | 4 +- container_list_test.go | 4 +- container_logs_test.go | 4 +- container_pause_test.go | 4 +- container_remove_test.go | 4 +- container_rename_test.go | 4 +- container_resize_test.go | 8 +- container_restart_test.go | 4 +- container_start_test.go | 4 +- container_stats_test.go | 4 +- container_stop_test.go | 4 +- container_top_test.go | 4 +- container_unpause_test.go | 4 +- container_update_test.go | 4 +- container_wait_test.go | 4 +- events_test.go | 6 +- hijack.go | 7 +- image_build_test.go | 4 +- image_create_test.go | 4 +- image_history_test.go | 4 +- image_import_test.go | 4 +- image_inspect_test.go | 6 +- image_list_test.go | 4 +- image_load_test.go | 4 +- image_pull_test.go | 14 +-- image_push_test.go | 14 +-- image_remove_test.go | 4 +- image_save_test.go | 4 +- image_search_test.go | 12 +-- image_tag_test.go | 6 +- info_test.go | 6 +- network_connect_test.go | 6 +- network_create_test.go | 4 +- network_disconnect_test.go | 4 +- network_inspect_test.go | 6 +- network_list_test.go | 4 +- network_remove_test.go | 4 +- node_inspect_test.go | 6 +- node_list_test.go | 4 +- node_remove_test.go | 4 +- node_update_test.go | 4 +- plugin_disable_test.go | 4 +- plugin_enable_test.go | 4 +- plugin_inspect_test.go | 4 +- plugin_list_test.go | 4 +- plugin_push_test.go | 4 +- plugin_remove_test.go | 4 +- plugin_set_test.go | 4 +- request.go | 17 ++-- request_test.go | 5 +- service_create_test.go | 4 +- service_inspect_test.go | 6 +- service_list_test.go | 4 +- service_remove_test.go | 4 +- service_update_test.go | 4 +- swarm_init_test.go | 4 +- swarm_inspect_test.go | 4 +- swarm_join_test.go | 4 +- swarm_leave_test.go | 4 +- swarm_update_test.go | 4 +- task_inspect_test.go | 4 +- task_list_test.go | 4 +- transport.go | 51 +++++++++++ transport/cancellable/LICENSE | 27 ------ transport/cancellable/canceler.go | 23 ----- transport/cancellable/canceler_go14.go | 27 ------ transport/cancellable/cancellable.go | 115 ------------------------- transport/client.go | 47 ---------- transport/transport.go | 57 ------------ volume_create_test.go | 4 +- volume_inspect_test.go | 6 +- volume_list_test.go | 4 +- volume_remove_test.go | 4 +- 86 files changed, 276 insertions(+), 533 deletions(-) create mode 100644 transport.go delete mode 100644 transport/cancellable/LICENSE delete mode 100644 transport/cancellable/canceler.go delete mode 100644 transport/cancellable/canceler_go14.go delete mode 100644 transport/cancellable/cancellable.go delete mode 100644 transport/client.go delete mode 100644 transport/transport.go diff --git a/checkpoint_create_test.go b/checkpoint_create_test.go index e2ae36e1e0..96e5187618 100644 --- a/checkpoint_create_test.go +++ b/checkpoint_create_test.go @@ -15,7 +15,7 @@ import ( func TestCheckpointCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.CheckpointCreate(context.Background(), "nothing", types.CheckpointCreateOptions{ CheckpointID: "noting", @@ -33,7 +33,7 @@ func TestCheckpointCreate(t *testing.T) { expectedURL := "/containers/container_id/checkpoints" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/checkpoint_delete_test.go b/checkpoint_delete_test.go index 097ab37693..23931c6523 100644 --- a/checkpoint_delete_test.go +++ b/checkpoint_delete_test.go @@ -13,7 +13,7 @@ import ( func TestCheckpointDeleteError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.CheckpointDelete(context.Background(), "container_id", "checkpoint_id") @@ -26,7 +26,7 @@ func TestCheckpointDelete(t *testing.T) { expectedURL := "/containers/container_id/checkpoints/checkpoint_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/checkpoint_list_test.go b/checkpoint_list_test.go index 5960436eb1..e636995bc1 100644 --- a/checkpoint_list_test.go +++ b/checkpoint_list_test.go @@ -15,7 +15,7 @@ import ( func TestCheckpointListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.CheckpointList(context.Background(), "container_id") @@ -28,7 +28,7 @@ func TestCheckpointList(t *testing.T) { expectedURL := "/containers/container_id/checkpoints" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/client.go b/client.go index 6a85121c6d..deccb4ab74 100644 --- a/client.go +++ b/client.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "github.com/docker/docker/client/transport" + "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" ) @@ -26,8 +26,8 @@ type Client struct { addr string // basePath holds the path to prepend to the requests. basePath string - // transport is the interface to send request with, it implements transport.Client. - transport transport.Client + // client used to send and receive http requests. + client *http.Client // version of the server to talk to. version string // custom http headers configured by users. @@ -86,9 +86,15 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map return nil, err } - transport, err := transport.NewTransportWithHTTP(proto, addr, client) - if err != nil { - return nil, err + if client == nil { + client = &http.Client{} + } + + if client.Transport == nil { + // setup the transport, if not already present + transport := new(http.Transport) + sockets.ConfigureTransport(transport, proto, addr) + client.Transport = transport } return &Client{ @@ -96,7 +102,7 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map proto: proto, addr: addr, basePath: basePath, - transport: transport, + client: client, version: version, customHTTPHeaders: httpHeaders, }, nil diff --git a/client_mock_test.go b/client_mock_test.go index 33c247266c..0ab935d536 100644 --- a/client_mock_test.go +++ b/client_mock_test.go @@ -2,48 +2,17 @@ package client import ( "bytes" - "crypto/tls" "encoding/json" "io/ioutil" "net/http" "github.com/docker/docker/api/types" - "github.com/docker/docker/client/transport" ) -type mockClient struct { - do func(*http.Request) (*http.Response, error) -} - -// TLSConfig returns the TLS configuration. -func (m *mockClient) TLSConfig() *tls.Config { - return &tls.Config{} -} - -// Scheme returns protocol scheme to use. -func (m *mockClient) Scheme() string { - return "http" -} - -// Secure returns true if there is a TLS configuration. -func (m *mockClient) Secure() bool { - return false -} - -// NewMockClient returns a mocked client that runs the function supplied as `client.Do` call -func newMockClient(tlsConfig *tls.Config, doer func(*http.Request) (*http.Response, error)) transport.Client { - if tlsConfig != nil { - panic("this actually gets set!") +func newMockClient(doer func(*http.Request) (*http.Response, error)) *http.Client { + return &http.Client{ + Transport: transportFunc(doer), } - - return &mockClient{ - do: doer, - } -} - -// Do executes the supplied function for the mock. -func (m mockClient) Do(req *http.Request) (*http.Response, error) { - return m.do(req) } func errorMock(statusCode int, message string) func(req *http.Request) (*http.Response, error) { diff --git a/client_test.go b/client_test.go index 60af3db029..60e44dc299 100644 --- a/client_test.go +++ b/client_test.go @@ -173,7 +173,7 @@ func TestParseHost(t *testing.T) { func TestUpdateClientVersion(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { splitQuery := strings.Split(req.URL.Path, "/") queryVersion := splitQuery[1] b, err := json.Marshal(types.Version{ diff --git a/container_commit_test.go b/container_commit_test.go index 3fc3e5cfd0..8f1b58be81 100644 --- a/container_commit_test.go +++ b/container_commit_test.go @@ -15,7 +15,7 @@ import ( func TestContainerCommitError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerCommit(context.Background(), "nothing", types.ContainerCommitOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -34,7 +34,7 @@ func TestContainerCommit(t *testing.T) { expectedChanges := []string{"change1", "change2"} client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_copy_test.go b/container_copy_test.go index 39cd05ac2d..7eded611fd 100644 --- a/container_copy_test.go +++ b/container_copy_test.go @@ -17,7 +17,7 @@ import ( func TestContainerStatPathError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerStatPath(context.Background(), "container_id", "path") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -27,7 +27,7 @@ func TestContainerStatPathError(t *testing.T) { func TestContainerStatPathNoHeaderError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), @@ -44,7 +44,7 @@ func TestContainerStatPath(t *testing.T) { expectedURL := "/containers/container_id/archive" expectedPath := "path/to/file" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -87,7 +87,7 @@ func TestContainerStatPath(t *testing.T) { func TestCopyToContainerError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -97,7 +97,7 @@ func TestCopyToContainerError(t *testing.T) { func TestCopyToContainerNotStatusOKError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNoContent, "No content")), + client: newMockClient(errorMock(http.StatusNoContent, "No content")), } err := client.CopyToContainer(context.Background(), "container_id", "path/to/file", bytes.NewReader([]byte("")), types.CopyToContainerOptions{}) if err == nil || err.Error() != "unexpected status code from daemon: 204" { @@ -109,7 +109,7 @@ func TestCopyToContainer(t *testing.T) { expectedURL := "/containers/container_id/archive" expectedPath := "path/to/file" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -153,7 +153,7 @@ func TestCopyToContainer(t *testing.T) { func TestCopyFromContainerError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -163,7 +163,7 @@ func TestCopyFromContainerError(t *testing.T) { func TestCopyFromContainerNotStatusOKError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNoContent, "No content")), + client: newMockClient(errorMock(http.StatusNoContent, "No content")), } _, _, err := client.CopyFromContainer(context.Background(), "container_id", "path/to/file") if err == nil || err.Error() != "unexpected status code from daemon: 204" { @@ -173,7 +173,7 @@ func TestCopyFromContainerNotStatusOKError(t *testing.T) { func TestCopyFromContainerNoHeaderError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), @@ -190,7 +190,7 @@ func TestCopyFromContainer(t *testing.T) { expectedURL := "/containers/container_id/archive" expectedPath := "path/to/file" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_create_test.go b/container_create_test.go index 4c14cdc5d1..5325156beb 100644 --- a/container_create_test.go +++ b/container_create_test.go @@ -16,7 +16,7 @@ import ( func TestContainerCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerCreate(context.Background(), nil, nil, nil, "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -25,7 +25,7 @@ func TestContainerCreateError(t *testing.T) { // 404 doesn't automagitally means an unknown image client = &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, err = client.ContainerCreate(context.Background(), nil, nil, nil, "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -35,7 +35,7 @@ func TestContainerCreateError(t *testing.T) { func TestContainerCreateImageNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "No such image")), + client: newMockClient(errorMock(http.StatusNotFound, "No such image")), } _, err := client.ContainerCreate(context.Background(), &container.Config{Image: "unknown_image"}, nil, nil, "unknown") if err == nil || !IsErrImageNotFound(err) { @@ -46,7 +46,7 @@ func TestContainerCreateImageNotFound(t *testing.T) { func TestContainerCreateWithName(t *testing.T) { expectedURL := "/containers/create" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_diff_test.go b/container_diff_test.go index 03ea3354d2..1ce1117684 100644 --- a/container_diff_test.go +++ b/container_diff_test.go @@ -15,7 +15,7 @@ import ( func TestContainerDiffError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerDiff(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -27,7 +27,7 @@ func TestContainerDiffError(t *testing.T) { func TestContainerDiff(t *testing.T) { expectedURL := "/containers/container_id/changes" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_exec_test.go b/container_exec_test.go index abe824e47b..42146ae8a5 100644 --- a/container_exec_test.go +++ b/container_exec_test.go @@ -16,7 +16,7 @@ import ( func TestContainerExecCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerExecCreate(context.Background(), "container_id", types.ExecConfig{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -27,7 +27,7 @@ func TestContainerExecCreateError(t *testing.T) { func TestContainerExecCreate(t *testing.T) { expectedURL := "/containers/container_id/exec" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -71,7 +71,7 @@ func TestContainerExecCreate(t *testing.T) { func TestContainerExecStartError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerExecStart(context.Background(), "nothing", types.ExecStartCheck{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -82,7 +82,7 @@ func TestContainerExecStartError(t *testing.T) { func TestContainerExecStart(t *testing.T) { expectedURL := "/exec/exec_id/start" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -115,7 +115,7 @@ func TestContainerExecStart(t *testing.T) { func TestContainerExecInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerExecInspect(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -126,7 +126,7 @@ func TestContainerExecInspectError(t *testing.T) { func TestContainerExecInspect(t *testing.T) { expectedURL := "/exec/exec_id/json" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_export_test.go b/container_export_test.go index 10eba33d2f..5849fe9252 100644 --- a/container_export_test.go +++ b/container_export_test.go @@ -13,7 +13,7 @@ import ( func TestContainerExportError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerExport(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerExportError(t *testing.T) { func TestContainerExport(t *testing.T) { expectedURL := "/containers/container_id/export" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/container_inspect_test.go b/container_inspect_test.go index 0dc8ac3753..f1a6f4ac7d 100644 --- a/container_inspect_test.go +++ b/container_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestContainerInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerInspect(context.Background(), "nothing") @@ -26,7 +26,7 @@ func TestContainerInspectError(t *testing.T) { func TestContainerInspectContainerNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, err := client.ContainerInspect(context.Background(), "unknown") @@ -38,7 +38,7 @@ func TestContainerInspectContainerNotFound(t *testing.T) { func TestContainerInspect(t *testing.T) { expectedURL := "/containers/container_id/json" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -76,7 +76,7 @@ func TestContainerInspect(t *testing.T) { func TestContainerInspectNode(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { content, err := json.Marshal(types.ContainerJSON{ ContainerJSONBase: &types.ContainerJSONBase{ ID: "container_id", diff --git a/container_kill_test.go b/container_kill_test.go index a34a7b5b11..9477b0abd2 100644 --- a/container_kill_test.go +++ b/container_kill_test.go @@ -13,7 +13,7 @@ import ( func TestContainerKillError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerKill(context.Background(), "nothing", "SIGKILL") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerKillError(t *testing.T) { func TestContainerKill(t *testing.T) { expectedURL := "/containers/container_id/kill" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_list_test.go b/container_list_test.go index 3aa2101f27..5068b7573e 100644 --- a/container_list_test.go +++ b/container_list_test.go @@ -16,7 +16,7 @@ import ( func TestContainerListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerList(context.Background(), types.ContainerListOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -28,7 +28,7 @@ func TestContainerList(t *testing.T) { expectedURL := "/containers/json" expectedFilters := `{"before":{"container":true},"label":{"label1":true,"label2":true}}` client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_logs_test.go b/container_logs_test.go index d7f0adc9c0..99e31842c9 100644 --- a/container_logs_test.go +++ b/container_logs_test.go @@ -19,7 +19,7 @@ import ( func TestContainerLogsError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerLogs(context.Background(), "container_id", types.ContainerLogsOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -83,7 +83,7 @@ func TestContainerLogs(t *testing.T) { } for _, logCase := range cases { client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/container_pause_test.go b/container_pause_test.go index ebd12a6ac7..0ee2f05d7e 100644 --- a/container_pause_test.go +++ b/container_pause_test.go @@ -13,7 +13,7 @@ import ( func TestContainerPauseError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerPause(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerPauseError(t *testing.T) { func TestContainerPause(t *testing.T) { expectedURL := "/containers/container_id/pause" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_remove_test.go b/container_remove_test.go index 6e135d6ef2..798c08b333 100644 --- a/container_remove_test.go +++ b/container_remove_test.go @@ -14,7 +14,7 @@ import ( func TestContainerRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -25,7 +25,7 @@ func TestContainerRemoveError(t *testing.T) { func TestContainerRemove(t *testing.T) { expectedURL := "/containers/container_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_rename_test.go b/container_rename_test.go index 9344bab7db..732ebff5f7 100644 --- a/container_rename_test.go +++ b/container_rename_test.go @@ -13,7 +13,7 @@ import ( func TestContainerRenameError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerRename(context.Background(), "nothing", "newNothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerRenameError(t *testing.T) { func TestContainerRename(t *testing.T) { expectedURL := "/containers/container_id/rename" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_resize_test.go b/container_resize_test.go index e0056c88d1..5b2efecdce 100644 --- a/container_resize_test.go +++ b/container_resize_test.go @@ -14,7 +14,7 @@ import ( func TestContainerResizeError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerResizeError(t *testing.T) { func TestContainerExecResizeError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -34,7 +34,7 @@ func TestContainerExecResizeError(t *testing.T) { func TestContainerResize(t *testing.T) { client := &Client{ - transport: newMockClient(nil, resizeTransport("/containers/container_id/resize")), + client: newMockClient(resizeTransport("/containers/container_id/resize")), } err := client.ContainerResize(context.Background(), "container_id", types.ResizeOptions{ @@ -48,7 +48,7 @@ func TestContainerResize(t *testing.T) { func TestContainerExecResize(t *testing.T) { client := &Client{ - transport: newMockClient(nil, resizeTransport("/exec/exec_id/resize")), + client: newMockClient(resizeTransport("/exec/exec_id/resize")), } err := client.ContainerExecResize(context.Background(), "exec_id", types.ResizeOptions{ diff --git a/container_restart_test.go b/container_restart_test.go index 080656d368..8c3cfd6a6f 100644 --- a/container_restart_test.go +++ b/container_restart_test.go @@ -14,7 +14,7 @@ import ( func TestContainerRestartError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } timeout := 0 * time.Second err := client.ContainerRestart(context.Background(), "nothing", &timeout) @@ -26,7 +26,7 @@ func TestContainerRestartError(t *testing.T) { func TestContainerRestart(t *testing.T) { expectedURL := "/containers/container_id/restart" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_start_test.go b/container_start_test.go index 79f85b332a..5826fa8bc7 100644 --- a/container_start_test.go +++ b/container_start_test.go @@ -16,7 +16,7 @@ import ( func TestContainerStartError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerStart(context.Background(), "nothing", types.ContainerStartOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -27,7 +27,7 @@ func TestContainerStartError(t *testing.T) { func TestContainerStart(t *testing.T) { expectedURL := "/containers/container_id/start" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_stats_test.go b/container_stats_test.go index 22ecd6170f..76e4a09ddf 100644 --- a/container_stats_test.go +++ b/container_stats_test.go @@ -13,7 +13,7 @@ import ( func TestContainerStatsError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerStats(context.Background(), "nothing", false) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -37,7 +37,7 @@ func TestContainerStats(t *testing.T) { } for _, c := range cases { client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/container_stop_test.go b/container_stop_test.go index 4b052f9908..c32cd691c4 100644 --- a/container_stop_test.go +++ b/container_stop_test.go @@ -14,7 +14,7 @@ import ( func TestContainerStopError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } timeout := 0 * time.Second err := client.ContainerStop(context.Background(), "nothing", &timeout) @@ -26,7 +26,7 @@ func TestContainerStopError(t *testing.T) { func TestContainerStop(t *testing.T) { expectedURL := "/containers/container_id/stop" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_top_test.go b/container_top_test.go index 4df7d82d84..7802be063e 100644 --- a/container_top_test.go +++ b/container_top_test.go @@ -16,7 +16,7 @@ import ( func TestContainerTopError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerTop(context.Background(), "nothing", []string{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -33,7 +33,7 @@ func TestContainerTop(t *testing.T) { expectedTitles := []string{"title1", "title2"} client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_unpause_test.go b/container_unpause_test.go index a5b21bf56c..2c42727191 100644 --- a/container_unpause_test.go +++ b/container_unpause_test.go @@ -13,7 +13,7 @@ import ( func TestContainerUnpauseError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerUnpause(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -24,7 +24,7 @@ func TestContainerUnpauseError(t *testing.T) { func TestContainerUnpause(t *testing.T) { expectedURL := "/containers/container_id/unpause" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_update_test.go b/container_update_test.go index 46e34d6936..e151637a2b 100644 --- a/container_update_test.go +++ b/container_update_test.go @@ -16,7 +16,7 @@ import ( func TestContainerUpdateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerUpdate(context.Background(), "nothing", container.UpdateConfig{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -28,7 +28,7 @@ func TestContainerUpdate(t *testing.T) { expectedURL := "/containers/container_id/update" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/container_wait_test.go b/container_wait_test.go index bf2ba6b925..dab5acbdd3 100644 --- a/container_wait_test.go +++ b/container_wait_test.go @@ -18,7 +18,7 @@ import ( func TestContainerWaitError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } code, err := client.ContainerWait(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -32,7 +32,7 @@ func TestContainerWaitError(t *testing.T) { func TestContainerWait(t *testing.T) { expectedURL := "/containers/container_id/wait" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/events_test.go b/events_test.go index f7cb33f611..48b948fa37 100644 --- a/events_test.go +++ b/events_test.go @@ -34,7 +34,7 @@ func TestEventsErrorInOptions(t *testing.T) { } for _, e := range errorCases { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.Events(context.Background(), e.options) if err == nil || !strings.Contains(err.Error(), e.expectedError) { @@ -45,7 +45,7 @@ func TestEventsErrorInOptions(t *testing.T) { func TestEventsErrorFromServer(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.Events(context.Background(), types.EventsOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -93,7 +93,7 @@ func TestEvents(t *testing.T) { for _, eventsCase := range eventsCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/hijack.go b/hijack.go index e3f63e20c2..f3461ecf78 100644 --- a/hijack.go +++ b/hijack.go @@ -47,7 +47,12 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu req.Header.Set("Connection", "Upgrade") req.Header.Set("Upgrade", "tcp") - conn, err := dial(cli.proto, cli.addr, cli.transport.TLSConfig()) + tlsConfig, err := resolveTLSConfig(cli.client.Transport) + if err != nil { + return types.HijackedResponse{}, err + } + + conn, err := dial(cli.proto, cli.addr, tlsConfig) if err != nil { if strings.Contains(err.Error(), "connection refused") { return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?") diff --git a/image_build_test.go b/image_build_test.go index 8261c54854..ec0cbe2ee4 100644 --- a/image_build_test.go +++ b/image_build_test.go @@ -18,7 +18,7 @@ import ( func TestImageBuildError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageBuild(context.Background(), nil, types.ImageBuildOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -157,7 +157,7 @@ func TestImageBuild(t *testing.T) { for _, buildCase := range buildCases { expectedURL := "/build" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/image_create_test.go b/image_create_test.go index a2e001be5d..5c2edd2ad5 100644 --- a/image_create_test.go +++ b/image_create_test.go @@ -15,7 +15,7 @@ import ( func TestImageCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageCreate(context.Background(), "reference", types.ImageCreateOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -30,7 +30,7 @@ func TestImageCreate(t *testing.T) { expectedReference := fmt.Sprintf("%s@%s", expectedImage, expectedTag) expectedRegistryAuth := "eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsiYXV0aCI6ImRHOTBid289IiwiZW1haWwiOiJqb2huQGRvZS5jb20ifX0=" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/image_history_test.go b/image_history_test.go index c9516151b7..729edb1ad5 100644 --- a/image_history_test.go +++ b/image_history_test.go @@ -15,7 +15,7 @@ import ( func TestImageHistoryError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageHistory(context.Background(), "nothing") if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -26,7 +26,7 @@ func TestImageHistoryError(t *testing.T) { func TestImageHistory(t *testing.T) { expectedURL := "/images/image_id/history" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/image_import_test.go b/image_import_test.go index b64ca74d7b..e309be74e6 100644 --- a/image_import_test.go +++ b/image_import_test.go @@ -15,7 +15,7 @@ import ( func TestImageImportError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageImport(context.Background(), types.ImageImportSource{}, "image:tag", types.ImageImportOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -26,7 +26,7 @@ func TestImageImportError(t *testing.T) { func TestImageImport(t *testing.T) { expectedURL := "/images/create" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/image_inspect_test.go b/image_inspect_test.go index 5c7ca2721f..74a4e49805 100644 --- a/image_inspect_test.go +++ b/image_inspect_test.go @@ -16,7 +16,7 @@ import ( func TestImageInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.ImageInspectWithRaw(context.Background(), "nothing") @@ -27,7 +27,7 @@ func TestImageInspectError(t *testing.T) { func TestImageInspectImageNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, _, err := client.ImageInspectWithRaw(context.Background(), "unknown") @@ -40,7 +40,7 @@ func TestImageInspect(t *testing.T) { expectedURL := "/images/image_id/json" expectedTags := []string{"tag1", "tag2"} client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_list_test.go b/image_list_test.go index 99ed1964a2..2a52279081 100644 --- a/image_list_test.go +++ b/image_list_test.go @@ -16,7 +16,7 @@ import ( func TestImageListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageList(context.Background(), types.ImageListOptions{}) @@ -82,7 +82,7 @@ func TestImageList(t *testing.T) { } for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_load_test.go b/image_load_test.go index 0ee7cf35a6..68dc14ff22 100644 --- a/image_load_test.go +++ b/image_load_test.go @@ -13,7 +13,7 @@ import ( func TestImageLoadError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageLoad(context.Background(), nil, true) @@ -51,7 +51,7 @@ func TestImageLoad(t *testing.T) { } for _, loadCase := range loadCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_pull_test.go b/image_pull_test.go index c33a6dcc8a..fe6bafed97 100644 --- a/image_pull_test.go +++ b/image_pull_test.go @@ -15,7 +15,7 @@ import ( func TestImagePullReferenceParseError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { return nil, nil }), } @@ -28,7 +28,7 @@ func TestImagePullReferenceParseError(t *testing.T) { func TestImagePullAnyError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -38,7 +38,7 @@ func TestImagePullAnyError(t *testing.T) { func TestImagePullStatusUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } _, err := client.ImagePull(context.Background(), "myimage", types.ImagePullOptions{}) if err == nil || err.Error() != "Error response from daemon: Unauthorized error" { @@ -48,7 +48,7 @@ func TestImagePullStatusUnauthorizedError(t *testing.T) { func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "", fmt.Errorf("Error requesting privilege") @@ -63,7 +63,7 @@ func TestImagePullWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "a-auth-header", nil @@ -79,7 +79,7 @@ func TestImagePullWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) func TestImagePullWithPrivilegedFuncNoError(t *testing.T) { expectedURL := "/images/create" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -163,7 +163,7 @@ func TestImagePullWithoutErrors(t *testing.T) { } for _, pullCase := range pullCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_push_test.go b/image_push_test.go index d32f3ef3c7..b52da8b8dc 100644 --- a/image_push_test.go +++ b/image_push_test.go @@ -15,7 +15,7 @@ import ( func TestImagePushReferenceError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { return nil, nil }), } @@ -33,7 +33,7 @@ func TestImagePushReferenceError(t *testing.T) { func TestImagePushAnyError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -43,7 +43,7 @@ func TestImagePushAnyError(t *testing.T) { func TestImagePushStatusUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } _, err := client.ImagePush(context.Background(), "myimage", types.ImagePushOptions{}) if err == nil || err.Error() != "Error response from daemon: Unauthorized error" { @@ -53,7 +53,7 @@ func TestImagePushStatusUnauthorizedError(t *testing.T) { func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "", fmt.Errorf("Error requesting privilege") @@ -68,7 +68,7 @@ func TestImagePushWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "a-auth-header", nil @@ -84,7 +84,7 @@ func TestImagePushWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) func TestImagePushWithPrivilegedFuncNoError(t *testing.T) { expectedURL := "/images/myimage/push" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -149,7 +149,7 @@ func TestImagePushWithoutErrors(t *testing.T) { } for _, pullCase := range pullCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { expectedURL := fmt.Sprintf(expectedURLFormat, pullCase.expectedImage) if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) diff --git a/image_remove_test.go b/image_remove_test.go index 696d06729d..7b004f70e6 100644 --- a/image_remove_test.go +++ b/image_remove_test.go @@ -15,7 +15,7 @@ import ( func TestImageRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{}) @@ -49,7 +49,7 @@ func TestImageRemove(t *testing.T) { } for _, removeCase := range removeCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_save_test.go b/image_save_test.go index 8ee40c43ae..8f0cf88640 100644 --- a/image_save_test.go +++ b/image_save_test.go @@ -15,7 +15,7 @@ import ( func TestImageSaveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageSave(context.Background(), []string{"nothing"}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -26,7 +26,7 @@ func TestImageSaveError(t *testing.T) { func TestImageSave(t *testing.T) { expectedURL := "/images/get" client := &Client{ - transport: newMockClient(nil, func(r *http.Request) (*http.Response, error) { + client: newMockClient(func(r *http.Request) (*http.Response, error) { if !strings.HasPrefix(r.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, r.URL) } diff --git a/image_search_test.go b/image_search_test.go index 2f21b2cc14..e46d86437f 100644 --- a/image_search_test.go +++ b/image_search_test.go @@ -18,7 +18,7 @@ import ( func TestImageSearchAnyError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -28,7 +28,7 @@ func TestImageSearchAnyError(t *testing.T) { func TestImageSearchStatusUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } _, err := client.ImageSearch(context.Background(), "some-image", types.ImageSearchOptions{}) if err == nil || err.Error() != "Error response from daemon: Unauthorized error" { @@ -38,7 +38,7 @@ func TestImageSearchStatusUnauthorizedError(t *testing.T) { func TestImageSearchWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "", fmt.Errorf("Error requesting privilege") @@ -53,7 +53,7 @@ func TestImageSearchWithUnauthorizedErrorAndPrivilegeFuncError(t *testing.T) { func TestImageSearchWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusUnauthorized, "Unauthorized error")), + client: newMockClient(errorMock(http.StatusUnauthorized, "Unauthorized error")), } privilegeFunc := func() (string, error) { return "a-auth-header", nil @@ -69,7 +69,7 @@ func TestImageSearchWithUnauthorizedErrorAndAnotherUnauthorizedError(t *testing. func TestImageSearchWithPrivilegedFuncNoError(t *testing.T) { expectedURL := "/images/search" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -126,7 +126,7 @@ func TestImageSearchWithoutErrors(t *testing.T) { expectedFilters := `{"is-automated":{"true":true},"stars":{"3":true}}` client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/image_tag_test.go b/image_tag_test.go index f3571dfdd3..7925db9f1b 100644 --- a/image_tag_test.go +++ b/image_tag_test.go @@ -13,7 +13,7 @@ import ( func TestImageTagError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ImageTag(context.Background(), "image_id", "repo:tag") @@ -26,7 +26,7 @@ func TestImageTagError(t *testing.T) { // of distribution/reference package. func TestImageTagInvalidReference(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ImageTag(context.Background(), "image_id", "aa/asdf$$^/aa") @@ -93,7 +93,7 @@ func TestImageTag(t *testing.T) { } for _, tagCase := range tagCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/info_test.go b/info_test.go index 9d51b1a78b..79f23c8af2 100644 --- a/info_test.go +++ b/info_test.go @@ -15,7 +15,7 @@ import ( func TestInfoServerError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.Info(context.Background()) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -25,7 +25,7 @@ func TestInfoServerError(t *testing.T) { func TestInfoInvalidResponseJSONError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewReader([]byte("invalid json"))), @@ -41,7 +41,7 @@ func TestInfoInvalidResponseJSONError(t *testing.T) { func TestInfo(t *testing.T) { expectedURL := "/info" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_connect_test.go b/network_connect_test.go index 95b149e685..d472f4520c 100644 --- a/network_connect_test.go +++ b/network_connect_test.go @@ -17,7 +17,7 @@ import ( func TestNetworkConnectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.NetworkConnect(context.Background(), "network_id", "container_id", nil) @@ -30,7 +30,7 @@ func TestNetworkConnectEmptyNilEndpointSettings(t *testing.T) { expectedURL := "/networks/network_id/connect" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } @@ -69,7 +69,7 @@ func TestNetworkConnect(t *testing.T) { expectedURL := "/networks/network_id/connect" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_create_test.go b/network_create_test.go index 611ed8173e..0e2457f89c 100644 --- a/network_create_test.go +++ b/network_create_test.go @@ -15,7 +15,7 @@ import ( func TestNetworkCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.NetworkCreate(context.Background(), "mynetwork", types.NetworkCreate{}) @@ -28,7 +28,7 @@ func TestNetworkCreate(t *testing.T) { expectedURL := "/networks/create" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_disconnect_test.go b/network_disconnect_test.go index d9dbb67159..b54a2b1ccf 100644 --- a/network_disconnect_test.go +++ b/network_disconnect_test.go @@ -15,7 +15,7 @@ import ( func TestNetworkDisconnectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.NetworkDisconnect(context.Background(), "network_id", "container_id", false) @@ -28,7 +28,7 @@ func TestNetworkDisconnect(t *testing.T) { expectedURL := "/networks/network_id/disconnect" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_inspect_test.go b/network_inspect_test.go index a6eb626c67..1f926d66ba 100644 --- a/network_inspect_test.go +++ b/network_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestNetworkInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.NetworkInspect(context.Background(), "nothing") @@ -26,7 +26,7 @@ func TestNetworkInspectError(t *testing.T) { func TestNetworkInspectContainerNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, err := client.NetworkInspect(context.Background(), "unknown") @@ -38,7 +38,7 @@ func TestNetworkInspectContainerNotFound(t *testing.T) { func TestNetworkInspect(t *testing.T) { expectedURL := "/networks/network_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_list_test.go b/network_list_test.go index cb66139271..4d443496ac 100644 --- a/network_list_test.go +++ b/network_list_test.go @@ -16,7 +16,7 @@ import ( func TestNetworkListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.NetworkList(context.Background(), types.NetworkListOptions{ @@ -69,7 +69,7 @@ func TestNetworkList(t *testing.T) { for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/network_remove_test.go b/network_remove_test.go index d8cfa0ed6e..2a7b9640c1 100644 --- a/network_remove_test.go +++ b/network_remove_test.go @@ -13,7 +13,7 @@ import ( func TestNetworkRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.NetworkRemove(context.Background(), "network_id") @@ -26,7 +26,7 @@ func TestNetworkRemove(t *testing.T) { expectedURL := "/networks/network_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/node_inspect_test.go b/node_inspect_test.go index bf67728311..fc13283084 100644 --- a/node_inspect_test.go +++ b/node_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestNodeInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.NodeInspectWithRaw(context.Background(), "nothing") @@ -26,7 +26,7 @@ func TestNodeInspectError(t *testing.T) { func TestNodeInspectNodeNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, _, err := client.NodeInspectWithRaw(context.Background(), "unknown") @@ -38,7 +38,7 @@ func TestNodeInspectNodeNotFound(t *testing.T) { func TestNodeInspect(t *testing.T) { expectedURL := "/nodes/node_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/node_list_test.go b/node_list_test.go index 899ac7f455..1b3b35f357 100644 --- a/node_list_test.go +++ b/node_list_test.go @@ -17,7 +17,7 @@ import ( func TestNodeListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.NodeList(context.Background(), types.NodeListOptions{}) @@ -54,7 +54,7 @@ func TestNodeList(t *testing.T) { } for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/node_remove_test.go b/node_remove_test.go index 9fdf2d7eb3..f2f8adc4a3 100644 --- a/node_remove_test.go +++ b/node_remove_test.go @@ -15,7 +15,7 @@ import ( func TestNodeRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: false}) @@ -42,7 +42,7 @@ func TestNodeRemove(t *testing.T) { for _, removeCase := range removeCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/node_update_test.go b/node_update_test.go index 1acf65854a..613ff104eb 100644 --- a/node_update_test.go +++ b/node_update_test.go @@ -15,7 +15,7 @@ import ( func TestNodeUpdateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.NodeUpdate(context.Background(), "node_id", swarm.Version{}, swarm.NodeSpec{}) @@ -28,7 +28,7 @@ func TestNodeUpdate(t *testing.T) { expectedURL := "/nodes/node_id/update" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_disable_test.go b/plugin_disable_test.go index f37c157866..7b50b25730 100644 --- a/plugin_disable_test.go +++ b/plugin_disable_test.go @@ -15,7 +15,7 @@ import ( func TestPluginDisableError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.PluginDisable(context.Background(), "plugin_name") @@ -28,7 +28,7 @@ func TestPluginDisable(t *testing.T) { expectedURL := "/plugins/plugin_name/disable" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_enable_test.go b/plugin_enable_test.go index fc0fe226a9..a2b57be4c2 100644 --- a/plugin_enable_test.go +++ b/plugin_enable_test.go @@ -15,7 +15,7 @@ import ( func TestPluginEnableError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.PluginEnable(context.Background(), "plugin_name") @@ -28,7 +28,7 @@ func TestPluginEnable(t *testing.T) { expectedURL := "/plugins/plugin_name/enable" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_inspect_test.go b/plugin_inspect_test.go index 19f829b2de..df4ca9c841 100644 --- a/plugin_inspect_test.go +++ b/plugin_inspect_test.go @@ -17,7 +17,7 @@ import ( func TestPluginInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.PluginInspectWithRaw(context.Background(), "nothing") @@ -29,7 +29,7 @@ func TestPluginInspectError(t *testing.T) { func TestPluginInspect(t *testing.T) { expectedURL := "/plugins/plugin_name" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_list_test.go b/plugin_list_test.go index 92aee61187..95c51595ca 100644 --- a/plugin_list_test.go +++ b/plugin_list_test.go @@ -17,7 +17,7 @@ import ( func TestPluginListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.PluginList(context.Background()) @@ -29,7 +29,7 @@ func TestPluginListError(t *testing.T) { func TestPluginList(t *testing.T) { expectedURL := "/plugins" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_push_test.go b/plugin_push_test.go index b77ea00273..ed685694ec 100644 --- a/plugin_push_test.go +++ b/plugin_push_test.go @@ -15,7 +15,7 @@ import ( func TestPluginPushError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.PluginPush(context.Background(), "plugin_name", "") @@ -28,7 +28,7 @@ func TestPluginPush(t *testing.T) { expectedURL := "/plugins/plugin_name" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_remove_test.go b/plugin_remove_test.go index de565f441b..fc789fd04d 100644 --- a/plugin_remove_test.go +++ b/plugin_remove_test.go @@ -17,7 +17,7 @@ import ( func TestPluginRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.PluginRemove(context.Background(), "plugin_name", types.PluginRemoveOptions{}) @@ -30,7 +30,7 @@ func TestPluginRemove(t *testing.T) { expectedURL := "/plugins/plugin_name" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/plugin_set_test.go b/plugin_set_test.go index 128dee04be..fa1cde044e 100644 --- a/plugin_set_test.go +++ b/plugin_set_test.go @@ -15,7 +15,7 @@ import ( func TestPluginSetError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.PluginSet(context.Background(), "plugin_name", []string{}) @@ -28,7 +28,7 @@ func TestPluginSet(t *testing.T) { expectedURL := "/plugins/plugin_name/set" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/request.go b/request.go index 7b4f5406b8..f5c239bf25 100644 --- a/request.go +++ b/request.go @@ -13,9 +13,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/versions" - "github.com/docker/docker/client/transport/cancellable" "github.com/pkg/errors" "golang.org/x/net/context" + "golang.org/x/net/context/ctxhttp" ) // serverResponse is a wrapper for http API responses. @@ -98,20 +98,27 @@ func (cli *Client) sendClientRequest(ctx context.Context, method, path string, q // need a valid and meaningful host name. (See #189) req.Host = "docker" } + + scheme, err := resolveScheme(cli.client.Transport) + if err != nil { + return serverResp, err + } + req.URL.Host = cli.addr - req.URL.Scheme = cli.transport.Scheme() + req.URL.Scheme = scheme if expectedPayload && req.Header.Get("Content-Type") == "" { req.Header.Set("Content-Type", "text/plain") } - resp, err := cancellable.Do(ctx, cli.transport, req) + resp, err := ctxhttp.Do(ctx, cli.client, req) if err != nil { - if !cli.transport.Secure() && strings.Contains(err.Error(), "malformed HTTP response") { + + if 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 cli.transport.Secure() && strings.Contains(err.Error(), "bad certificate") { + if 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) } diff --git a/request_test.go b/request_test.go index 446adf9c66..63908aec4b 100644 --- a/request_test.go +++ b/request_test.go @@ -50,7 +50,7 @@ func TestSetHostHeader(t *testing.T) { } client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, testURL) { return nil, fmt.Errorf("Test Case #%d: Expected URL %q, got %q", c, testURL, req.URL) } @@ -65,6 +65,7 @@ func TestSetHostHeader(t *testing.T) { Body: ioutil.NopCloser(bytes.NewReader(([]byte("")))), }, nil }), + proto: proto, addr: addr, basePath: basePath, @@ -82,7 +83,7 @@ func TestSetHostHeader(t *testing.T) { // errors returned as JSON func TestPlainTextError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, plainTextErrorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(plainTextErrorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ContainerList(context.Background(), types.ContainerListOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { diff --git a/service_create_test.go b/service_create_test.go index a79f040c0a..1e07382870 100644 --- a/service_create_test.go +++ b/service_create_test.go @@ -16,7 +16,7 @@ import ( func TestServiceCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{}) if err == nil || err.Error() != "Error response from daemon: Server error" { @@ -27,7 +27,7 @@ func TestServiceCreateError(t *testing.T) { func TestServiceCreate(t *testing.T) { expectedURL := "/services/create" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/service_inspect_test.go b/service_inspect_test.go index e4eafff5d7..e235cf0fef 100644 --- a/service_inspect_test.go +++ b/service_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestServiceInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.ServiceInspectWithRaw(context.Background(), "nothing") @@ -26,7 +26,7 @@ func TestServiceInspectError(t *testing.T) { func TestServiceInspectServiceNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, _, err := client.ServiceInspectWithRaw(context.Background(), "unknown") @@ -38,7 +38,7 @@ func TestServiceInspectServiceNotFound(t *testing.T) { func TestServiceInspect(t *testing.T) { expectedURL := "/services/service_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/service_list_test.go b/service_list_test.go index 6e6851a3a5..728187919f 100644 --- a/service_list_test.go +++ b/service_list_test.go @@ -17,7 +17,7 @@ import ( func TestServiceListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.ServiceList(context.Background(), types.ServiceListOptions{}) @@ -54,7 +54,7 @@ func TestServiceList(t *testing.T) { } for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/service_remove_test.go b/service_remove_test.go index e1316f959b..8e2ac259c1 100644 --- a/service_remove_test.go +++ b/service_remove_test.go @@ -13,7 +13,7 @@ import ( func TestServiceRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ServiceRemove(context.Background(), "service_id") @@ -26,7 +26,7 @@ func TestServiceRemove(t *testing.T) { expectedURL := "/services/service_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/service_update_test.go b/service_update_test.go index bd616c09bf..081649f492 100644 --- a/service_update_test.go +++ b/service_update_test.go @@ -16,7 +16,7 @@ import ( func TestServiceUpdateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ServiceUpdate(context.Background(), "service_id", swarm.Version{}, swarm.ServiceSpec{}, types.ServiceUpdateOptions{}) @@ -51,7 +51,7 @@ func TestServiceUpdate(t *testing.T) { for _, updateCase := range updateCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/swarm_init_test.go b/swarm_init_test.go index 077c8c4efb..811155aff4 100644 --- a/swarm_init_test.go +++ b/swarm_init_test.go @@ -15,7 +15,7 @@ import ( func TestSwarmInitError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.SwarmInit(context.Background(), swarm.InitRequest{}) @@ -28,7 +28,7 @@ func TestSwarmInit(t *testing.T) { expectedURL := "/swarm/init" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/swarm_inspect_test.go b/swarm_inspect_test.go index 7143e77181..6432d172b4 100644 --- a/swarm_inspect_test.go +++ b/swarm_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestSwarmInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.SwarmInspect(context.Background()) @@ -27,7 +27,7 @@ func TestSwarmInspectError(t *testing.T) { func TestSwarmInspect(t *testing.T) { expectedURL := "/swarm" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/swarm_join_test.go b/swarm_join_test.go index 922716d85f..31ef2a76ee 100644 --- a/swarm_join_test.go +++ b/swarm_join_test.go @@ -15,7 +15,7 @@ import ( func TestSwarmJoinError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.SwarmJoin(context.Background(), swarm.JoinRequest{}) @@ -28,7 +28,7 @@ func TestSwarmJoin(t *testing.T) { expectedURL := "/swarm/join" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/swarm_leave_test.go b/swarm_leave_test.go index d0bef2b257..c96dac8120 100644 --- a/swarm_leave_test.go +++ b/swarm_leave_test.go @@ -13,7 +13,7 @@ import ( func TestSwarmLeaveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.SwarmLeave(context.Background(), false) @@ -40,7 +40,7 @@ func TestSwarmLeave(t *testing.T) { for _, leaveCase := range leaveCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/swarm_update_test.go b/swarm_update_test.go index ecf1731e5b..3b23db078f 100644 --- a/swarm_update_test.go +++ b/swarm_update_test.go @@ -15,7 +15,7 @@ import ( func TestSwarmUpdateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.SwarmUpdate(context.Background(), swarm.Version{}, swarm.Spec{}, swarm.UpdateFlags{}) @@ -28,7 +28,7 @@ func TestSwarmUpdate(t *testing.T) { expectedURL := "/swarm/update" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/task_inspect_test.go b/task_inspect_test.go index 2c73b37642..148cdad3a7 100644 --- a/task_inspect_test.go +++ b/task_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestTaskInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, _, err := client.TaskInspectWithRaw(context.Background(), "nothing") @@ -27,7 +27,7 @@ func TestTaskInspectError(t *testing.T) { func TestTaskInspect(t *testing.T) { expectedURL := "/tasks/task_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/task_list_test.go b/task_list_test.go index b520ab589f..2d9b812bc2 100644 --- a/task_list_test.go +++ b/task_list_test.go @@ -17,7 +17,7 @@ import ( func TestTaskListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.TaskList(context.Background(), types.TaskListOptions{}) @@ -54,7 +54,7 @@ func TestTaskList(t *testing.T) { } for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/transport.go b/transport.go new file mode 100644 index 0000000000..43a667272d --- /dev/null +++ b/transport.go @@ -0,0 +1,51 @@ +package client + +import ( + "crypto/tls" + "errors" + "net/http" +) + +var errTLSConfigUnavailable = errors.New("TLSConfig unavailable") + +// transportFunc allows us to inject a mock transport for testing. We define it +// here so we can detect the tlsconfig and return nil for only this type. +type transportFunc func(*http.Request) (*http.Response, error) + +func (tf transportFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return tf(req) +} + +// resolveTLSConfig attempts to resolve the tls configuration from the +// RoundTripper. +func resolveTLSConfig(transport http.RoundTripper) (*tls.Config, error) { + switch tr := transport.(type) { + case *http.Transport: + return tr.TLSClientConfig, nil + case transportFunc: + return nil, nil // detect this type for testing. + default: + return nil, errTLSConfigUnavailable + } +} + +// 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, error) { + c, err := resolveTLSConfig(transport) + if err != nil { + return "", err + } + + if c != nil { + return "https", nil + } + + return "http", nil +} diff --git a/transport/cancellable/LICENSE b/transport/cancellable/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/transport/cancellable/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/transport/cancellable/canceler.go b/transport/cancellable/canceler.go deleted file mode 100644 index 62770b777b..0000000000 --- a/transport/cancellable/canceler.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.5 - -package cancellable - -import ( - "net/http" - - "github.com/docker/docker/client/transport" -) - -func canceler(client transport.Sender, req *http.Request) func() { - // TODO(djd): Respect any existing value of req.Cancel. - ch := make(chan struct{}) - req.Cancel = ch - - return func() { - close(ch) - } -} diff --git a/transport/cancellable/canceler_go14.go b/transport/cancellable/canceler_go14.go deleted file mode 100644 index dd2723d94f..0000000000 --- a/transport/cancellable/canceler_go14.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !go1.5 - -package cancellable - -import ( - "net/http" - - "github.com/docker/docker/client/transport" -) - -type requestCanceler interface { - CancelRequest(*http.Request) -} - -func canceler(client transport.Sender, req *http.Request) func() { - rc, ok := client.(requestCanceler) - if !ok { - return func() {} - } - return func() { - rc.CancelRequest(req) - } -} diff --git a/transport/cancellable/cancellable.go b/transport/cancellable/cancellable.go deleted file mode 100644 index 1f8eac5c1c..0000000000 --- a/transport/cancellable/cancellable.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cancellable provides helper function to cancel http requests. -package cancellable - -import ( - "io" - "net/http" - "sync" - - "github.com/docker/docker/client/transport" - - "golang.org/x/net/context" -) - -func nop() {} - -var ( - testHookContextDoneBeforeHeaders = nop - testHookDoReturned = nop - testHookDidBodyClose = nop -) - -// Do sends an HTTP request with the provided transport.Sender and returns an HTTP response. -// If the client is nil, http.DefaultClient is used. -// If the context is canceled or times out, ctx.Err() will be returned. -// -// FORK INFORMATION: -// -// This function deviates from the upstream version in golang.org/x/net/context/ctxhttp by -// taking a Sender interface rather than a *http.Client directly. That allow us to use -// this function with mocked clients and hijacked connections. -func Do(ctx context.Context, client transport.Sender, req *http.Request) (*http.Response, error) { - if client == nil { - client = http.DefaultClient - } - - // Request cancelation changed in Go 1.5, see canceler.go and canceler_go14.go. - cancel := canceler(client, req) - - type responseAndError struct { - resp *http.Response - err error - } - result := make(chan responseAndError, 1) - - go func() { - resp, err := client.Do(req) - testHookDoReturned() - result <- responseAndError{resp, err} - }() - - var resp *http.Response - - select { - case <-ctx.Done(): - testHookContextDoneBeforeHeaders() - cancel() - // Clean up after the goroutine calling client.Do: - go func() { - if r := <-result; r.resp != nil && r.resp.Body != nil { - testHookDidBodyClose() - r.resp.Body.Close() - } - }() - return nil, ctx.Err() - case r := <-result: - var err error - resp, err = r.resp, r.err - if err != nil { - return resp, err - } - } - - c := make(chan struct{}) - go func() { - select { - case <-ctx.Done(): - cancel() - case <-c: - // The response's Body is closed. - } - }() - resp.Body = ¬ifyingReader{ReadCloser: resp.Body, notify: c} - - return resp, nil -} - -// notifyingReader is an io.ReadCloser that closes the notify channel after -// Close is called or a Read fails on the underlying ReadCloser. -type notifyingReader struct { - io.ReadCloser - notify chan<- struct{} - notifyOnce sync.Once -} - -func (r *notifyingReader) Read(p []byte) (int, error) { - n, err := r.ReadCloser.Read(p) - if err != nil { - r.notifyOnce.Do(func() { - close(r.notify) - }) - } - return n, err -} - -func (r *notifyingReader) Close() error { - err := r.ReadCloser.Close() - r.notifyOnce.Do(func() { - close(r.notify) - }) - return err -} diff --git a/transport/client.go b/transport/client.go deleted file mode 100644 index 13d4b3ab3d..0000000000 --- a/transport/client.go +++ /dev/null @@ -1,47 +0,0 @@ -package transport - -import ( - "crypto/tls" - "net/http" -) - -// Sender is an interface that clients must implement -// to be able to send requests to a remote connection. -type Sender interface { - // Do sends request to a remote endpoint. - Do(*http.Request) (*http.Response, error) -} - -// Client is an interface that abstracts all remote connections. -type Client interface { - Sender - // Secure tells whether the connection is secure or not. - Secure() bool - // Scheme returns the connection protocol the client uses. - Scheme() string - // TLSConfig returns any TLS configuration the client uses. - TLSConfig() *tls.Config -} - -// tlsInfo returns information about the TLS configuration. -type tlsInfo struct { - tlsConfig *tls.Config -} - -// TLSConfig returns the TLS configuration. -func (t *tlsInfo) TLSConfig() *tls.Config { - return t.tlsConfig -} - -// Scheme returns protocol scheme to use. -func (t *tlsInfo) Scheme() string { - if t.tlsConfig != nil { - return "https" - } - return "http" -} - -// Secure returns true if there is a TLS configuration. -func (t *tlsInfo) Secure() bool { - return t.tlsConfig != nil -} diff --git a/transport/transport.go b/transport/transport.go deleted file mode 100644 index ff28af1855..0000000000 --- a/transport/transport.go +++ /dev/null @@ -1,57 +0,0 @@ -// Package transport provides function to send request to remote endpoints. -package transport - -import ( - "fmt" - "net/http" - - "github.com/docker/go-connections/sockets" -) - -// apiTransport holds information about the http transport to connect with the API. -type apiTransport struct { - *http.Client - *tlsInfo - transport *http.Transport -} - -// NewTransportWithHTTP creates a new transport based on the provided proto, address and http client. -// It uses Docker's default http transport configuration if the client is nil. -// It does not modify the client's transport if it's not nil. -func NewTransportWithHTTP(proto, addr string, client *http.Client) (Client, error) { - var transport *http.Transport - - if client != nil { - tr, ok := client.Transport.(*http.Transport) - if !ok { - return nil, fmt.Errorf("unable to verify TLS configuration, invalid transport %v", client.Transport) - } - transport = tr - } else { - transport = defaultTransport(proto, addr) - client = &http.Client{ - Transport: transport, - } - } - - return &apiTransport{ - Client: client, - tlsInfo: &tlsInfo{transport.TLSClientConfig}, - transport: transport, - }, nil -} - -// CancelRequest stops a request execution. -func (a *apiTransport) CancelRequest(req *http.Request) { - a.transport.CancelRequest(req) -} - -// defaultTransport creates a new http.Transport with Docker's -// default transport configuration. -func defaultTransport(proto, addr string) *http.Transport { - tr := new(http.Transport) - sockets.ConfigureTransport(tr, proto, addr) - return tr -} - -var _ Client = &apiTransport{} diff --git a/volume_create_test.go b/volume_create_test.go index d3cfa7132f..75085296cc 100644 --- a/volume_create_test.go +++ b/volume_create_test.go @@ -15,7 +15,7 @@ import ( func TestVolumeCreateError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.VolumeCreate(context.Background(), types.VolumeCreateRequest{}) @@ -28,7 +28,7 @@ func TestVolumeCreate(t *testing.T) { expectedURL := "/volumes/create" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/volume_inspect_test.go b/volume_inspect_test.go index 4b9f47358d..0d1d118828 100644 --- a/volume_inspect_test.go +++ b/volume_inspect_test.go @@ -15,7 +15,7 @@ import ( func TestVolumeInspectError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.VolumeInspect(context.Background(), "nothing") @@ -26,7 +26,7 @@ func TestVolumeInspectError(t *testing.T) { func TestVolumeInspectNotFound(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusNotFound, "Server error")), + client: newMockClient(errorMock(http.StatusNotFound, "Server error")), } _, err := client.VolumeInspect(context.Background(), "unknown") @@ -38,7 +38,7 @@ func TestVolumeInspectNotFound(t *testing.T) { func TestVolumeInspect(t *testing.T) { expectedURL := "/volumes/volume_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/volume_list_test.go b/volume_list_test.go index d30d9fcd52..0af420eaff 100644 --- a/volume_list_test.go +++ b/volume_list_test.go @@ -16,7 +16,7 @@ import ( func TestVolumeListError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } _, err := client.VolumeList(context.Background(), filters.NewArgs()) @@ -59,7 +59,7 @@ func TestVolumeList(t *testing.T) { for _, listCase := range listCases { client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) } diff --git a/volume_remove_test.go b/volume_remove_test.go index 0675bfd458..1fe657349a 100644 --- a/volume_remove_test.go +++ b/volume_remove_test.go @@ -13,7 +13,7 @@ import ( func TestVolumeRemoveError(t *testing.T) { client := &Client{ - transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")), + client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.VolumeRemove(context.Background(), "volume_id", false) @@ -26,7 +26,7 @@ func TestVolumeRemove(t *testing.T) { expectedURL := "/volumes/volume_id" client := &Client{ - transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) { + client: newMockClient(func(req *http.Request) (*http.Response, error) { if !strings.HasPrefix(req.URL.Path, expectedURL) { return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL) }