Browse code

builder: correct output buffering order

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2018/05/26 09:30:42
Showing 1 changed files
... ...
@@ -193,10 +193,8 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
193 193
 
194 194
 	w.Header().Set("Content-Type", "application/json")
195 195
 
196
-	var output writeCloseFlusher = ioutils.NewWriteFlusher(w)
197
-	defer output.Close()
198
-
199 196
 	body := r.Body
197
+	var ww io.Writer = w
200 198
 	if body != nil {
201 199
 		// there is a possibility that output is written before request body
202 200
 		// has been fully read so we need to protect against it.
... ...
@@ -204,18 +202,25 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
204 204
 		// https://github.com/golang/go/issues/15527
205 205
 		// https://github.com/golang/go/issues/22209
206 206
 		// has been fixed
207
-		body, output = wrapOutputBufferedUntilRequestRead(body, output)
207
+		body, ww = wrapOutputBufferedUntilRequestRead(body, ww)
208 208
 	}
209
+
210
+	output := ioutils.NewWriteFlusher(ww)
211
+	defer output.Close()
212
+
209 213
 	errf := func(err error) error {
214
+
210 215
 		if httputils.BoolValue(r, "q") && notVerboseBuffer.Len() > 0 {
211 216
 			output.Write(notVerboseBuffer.Bytes())
212 217
 		}
218
+
219
+		logrus.Debugf("isflushed %v", output.Flushed())
213 220
 		// Do not write the error in the http output if it's still empty.
214 221
 		// This prevents from writing a 200(OK) when there is an internal error.
215 222
 		if !output.Flushed() {
216 223
 			return err
217 224
 		}
218
-		_, err = w.Write(streamformatter.FormatError(err))
225
+		_, err = output.Write(streamformatter.FormatError(err))
219 226
 		if err != nil {
220 227
 			logrus.Warnf("could not write error response: %v", err)
221 228
 		}
... ...
@@ -311,16 +316,20 @@ func buildProgressWriter(out io.Writer, wantAux bool, createProgressReader func(
311 311
 	}
312 312
 }
313 313
 
314
-type writeCloseFlusher interface {
314
+type flusher interface {
315 315
 	Flush()
316
-	Flushed() bool
317
-	io.WriteCloser
318 316
 }
319 317
 
320
-func wrapOutputBufferedUntilRequestRead(rc io.ReadCloser, out writeCloseFlusher) (io.ReadCloser, writeCloseFlusher) {
318
+func wrapOutputBufferedUntilRequestRead(rc io.ReadCloser, out io.Writer) (io.ReadCloser, io.Writer) {
319
+	var fl flusher = &ioutils.NopFlusher{}
320
+	if f, ok := out.(flusher); ok {
321
+		fl = f
322
+	}
323
+
321 324
 	w := &wcf{
322
-		buf:               bytes.NewBuffer(nil),
323
-		writeCloseFlusher: out,
325
+		buf:     bytes.NewBuffer(nil),
326
+		Writer:  out,
327
+		flusher: fl,
324 328
 	}
325 329
 	r := bufio.NewReader(rc)
326 330
 	_, err := r.Peek(1)
... ...
@@ -355,7 +364,8 @@ func (r *rcNotifier) Close() error {
355 355
 }
356 356
 
357 357
 type wcf struct {
358
-	writeCloseFlusher
358
+	io.Writer
359
+	flusher
359 360
 	mu      sync.Mutex
360 361
 	ready   bool
361 362
 	buf     *bytes.Buffer
... ...
@@ -370,7 +380,7 @@ func (w *wcf) Flush() {
370 370
 		return
371 371
 	}
372 372
 	w.mu.Unlock()
373
-	w.writeCloseFlusher.Flush()
373
+	w.flusher.Flush()
374 374
 }
375 375
 
376 376
 func (w *wcf) Flushed() bool {
... ...
@@ -388,17 +398,17 @@ func (w *wcf) Write(b []byte) (int, error) {
388 388
 		return n, err
389 389
 	}
390 390
 	w.mu.Unlock()
391
-	return w.writeCloseFlusher.Write(b)
391
+	return w.Writer.Write(b)
392 392
 }
393 393
 
394 394
 func (w *wcf) notify() {
395 395
 	w.mu.Lock()
396 396
 	if !w.ready {
397 397
 		if w.buf.Len() > 0 {
398
-			io.Copy(w.writeCloseFlusher, w.buf)
398
+			io.Copy(w.Writer, w.buf)
399 399
 		}
400 400
 		if w.flushed {
401
-			w.writeCloseFlusher.Flush()
401
+			w.flusher.Flush()
402 402
 		}
403 403
 		w.ready = true
404 404
 	}