diff --git a/api/api.go b/api/api.go index d861140c0f..bbcbd17fd2 100644 --- a/api/api.go +++ b/api/api.go @@ -364,6 +364,7 @@ func createRouter(c *context, enableCors bool) *mux.Router { "/containers/{name:.*}/json": getContainerJSON, "/containers/{name:.*}/top": proxyContainer, "/containers/{name:.*}/logs": proxyContainer, + "/containers/{name:.*}/stats": proxyContainer, "/containers/{name:.*}/attach/ws": notImplementedHandler, "/exec/{execid:.*}/json": proxyContainer, }, diff --git a/api/flusher.go b/api/flusher.go new file mode 100644 index 0000000000..7e802cdc1a --- /dev/null +++ b/api/flusher.go @@ -0,0 +1,40 @@ +package api + +import ( + "io" + "net/http" + "sync" + + "github.com/docker/docker/pkg/ioutils" +) + +type WriteFlusher struct { + sync.Mutex + w io.Writer + flusher http.Flusher +} + +func (wf *WriteFlusher) Write(b []byte) (n int, err error) { + wf.Lock() + defer wf.Unlock() + n, err = wf.w.Write(b) + wf.flusher.Flush() + return n, err +} + +// Flush the stream immediately. +func (wf *WriteFlusher) Flush() { + wf.Lock() + defer wf.Unlock() + wf.flusher.Flush() +} + +func NewWriteFlusher(w io.Writer) *WriteFlusher { + var flusher http.Flusher + if f, ok := w.(http.Flusher); ok { + flusher = f + } else { + flusher = &ioutils.NopFlusher{} + } + return &WriteFlusher{w: w, flusher: flusher} +} diff --git a/api/utils.go b/api/utils.go index 33d4687b2f..76c18f453c 100644 --- a/api/utils.go +++ b/api/utils.go @@ -67,7 +67,7 @@ func proxy(tlsConfig *tls.Config, addr string, w http.ResponseWriter, r *http.Re copyHeader(w.Header(), resp.Header) w.WriteHeader(resp.StatusCode) - io.Copy(w, resp.Body) + io.Copy(NewWriteFlusher(w), resp.Body) return nil }