fix streaming output to flush per write
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
Jeromy committed
Oct 21, 2015 at 14:51 UTC
4470826fe284853a1fcdb9eaf03cd342ecc5d73b
1 file changed
+33
-1
commands/http/handler.go
+33
-1
@@ -245,13 +245,45 @@ func sendResponse(w http.ResponseWriter, r *http.Request, res cmds.Response, req
245
}
246
247
w.WriteHeader(status)
248
- _, err = io.Copy(w, out)
248
+ err = flushCopy(w, out)
249
if err != nil {
250
log.Error("err: ", err)
251
w.Header().Set(StreamErrHeader, sanitizedErrStr(err))
252
}
253
}
254
255
+func flushCopy(w io.Writer, r io.Reader) error {
256
+ buf := make([]byte, 4096)
257
+ f, ok := w.(http.Flusher)
258
+ if !ok {
259
+ _, err := io.Copy(w, r)
260
+ return err
261
+ }
262
+ for {
263
+ n, err := r.Read(buf)
264
+ switch err {
265
+ case io.EOF:
266
+ return nil
267
+ case nil:
268
+ // continue
269
+ default:
270
+ return err
271
+ }
272
+
273
+ nw, err := w.Write(buf[:n])
274
+ if err != nil {
275
+ return err
276
+ }
277
+
278
+ if nw != n {
279
+ return fmt.Errorf("http write failed to write full amount: %d != %d", nw, n)
280
+ }
281
+
282
+ f.Flush()
283
+ }
284
+ return nil
285
+}
286
+
287
func sanitizedErrStr(err error) string {
288
s := err.Error()
289
s = strings.Split(s, "\n")[0]