diff --git a/pkg/client/request.go b/pkg/client/request.go index 2aceb7ae479..31a09e71d93 100644 --- a/pkg/client/request.go +++ b/pkg/client/request.go @@ -269,6 +269,26 @@ func (r *Request) Watch() (watch.Interface, error) { return watch.NewStreamWatcher(tools.NewAPIEventDecoder(response.Body)), nil } +// Stream formats and executes the request, and offers streaming of the response. +// Returns io.ReadCloser which could be used for streaming of the response, or an error +func (r *Request) Stream() (io.ReadCloser, error) { + if r.err != nil { + return nil, r.err + } + req, err := http.NewRequest(r.verb, r.finalURL(), nil) + if err != nil { + return nil, err + } + if r.c.auth != nil { + req.SetBasicAuth(r.c.auth.User, r.c.auth.Password) + } + response, err := r.c.httpClient.Do(req) + if err != nil { + return nil, err + } + return response.Body, nil +} + // Do formats and executes the request. Returns the API object received, or an error. func (r *Request) Do() Result { for { diff --git a/pkg/client/request_test.go b/pkg/client/request_test.go index 904706bc092..c682b78fdb2 100644 --- a/pkg/client/request_test.go +++ b/pkg/client/request_test.go @@ -434,3 +434,37 @@ func TestWatch(t *testing.T) { t.Fatal("Unexpected non-close") } } + +func TestStream(t *testing.T) { + auth := AuthInfo{User: "user", Password: "pass"} + expectedBody := "expected body" + + testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + checkAuth(t, auth, r) + flusher, ok := w.(http.Flusher) + if !ok { + panic("need flusher!") + } + w.Header().Set("Transfer-Encoding", "chunked") + w.WriteHeader(http.StatusOK) + w.Write([]byte(expectedBody)) + flusher.Flush() + })) + + c, err := New(testServer.URL, "v1beta1", &auth) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + readCloser, err := c.Get().Path("path/to/stream/thing").Stream() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + defer readCloser.Close() + buf := new(bytes.Buffer) + buf.ReadFrom(readCloser) + resultBody := buf.String() + + if expectedBody != resultBody { + t.Errorf("Expected %s, got %s", expectedBody, resultBody) + } +}