7
7
"net/http"
8
8
"net/url"
9
9
"strings"
10
+ "sync"
10
11
"sync/atomic"
11
12
"time"
12
13
@@ -270,13 +271,18 @@ type timeoutResponseWriter struct {
270
271
ctx context.Context
271
272
w http.ResponseWriter
272
273
wrote int32
274
+ mu sync.Mutex
273
275
}
274
276
275
277
func (t * timeoutResponseWriter ) Header () http.Header {
278
+ t .mu .Lock ()
279
+ defer t .mu .Unlock ()
276
280
return t .w .Header ()
277
281
}
278
282
279
283
func (t * timeoutResponseWriter ) Write (bytes []byte ) (int , error ) {
284
+ t .mu .Lock ()
285
+ defer t .mu .Unlock ()
280
286
if t .ctx .Err () == context .DeadlineExceeded {
281
287
if atomic .LoadInt32 (& t .wrote ) == 0 {
282
288
return 0 , context .DeadlineExceeded
@@ -287,12 +293,14 @@ func (t *timeoutResponseWriter) Write(bytes []byte) (int, error) {
287
293
// through
288
294
}
289
295
290
- atomic . AddInt32 ( & t .wrote , 1 )
296
+ t .wrote = 1
291
297
292
298
return t .w .Write (bytes )
293
299
}
294
300
295
301
func (t * timeoutResponseWriter ) WriteHeader (statusCode int ) {
302
+ t .mu .Lock ()
303
+ defer t .mu .Unlock ()
296
304
if t .ctx .Err () == context .DeadlineExceeded {
297
305
if atomic .LoadInt32 (& t .wrote ) == 0 {
298
306
return
@@ -303,7 +311,7 @@ func (t *timeoutResponseWriter) WriteHeader(statusCode int) {
303
311
// through
304
312
}
305
313
306
- atomic . AddInt32 ( & t .wrote , 1 )
314
+ t .wrote = 1
307
315
308
316
t .w .WriteHeader (statusCode )
309
317
}
@@ -324,8 +332,10 @@ func (a *API) timeoutMiddleware(timeout time.Duration) func(http.Handler) http.H
324
332
325
333
err := ctx .Err ()
326
334
335
+ timeoutWriter .mu .Lock ()
336
+ defer timeoutWriter .mu .Unlock ()
327
337
if err == context .DeadlineExceeded {
328
- if atomic . LoadInt32 ( & timeoutWriter .wrote ) == 0 {
338
+ if timeoutWriter .wrote == 0 {
329
339
// writer wasn't written to, so we're sending the error payload
330
340
331
341
httpError := & HTTPError {
0 commit comments