@@ -347,7 +347,7 @@ type response struct {
347
347
// written.
348
348
trailers []string
349
349
350
- handlerDone bool // set true when the handler exits
350
+ handlerDone atomicBool // set true when the handler exits
351
351
352
352
// Buffers for Date and Content-Length
353
353
dateBuf [len (TimeFormat )]byte
@@ -358,6 +358,11 @@ type response struct {
358
358
closeNotifyCh <- chan bool
359
359
}
360
360
361
+ type atomicBool int32
362
+
363
+ func (b * atomicBool ) isSet () bool { return atomic .LoadInt32 ((* int32 )(b )) != 0 }
364
+ func (b * atomicBool ) setTrue () { atomic .StoreInt32 ((* int32 )(b ), 1 ) }
365
+
361
366
// declareTrailer is called for each Trailer header when the
362
367
// response header is written. It notes that a header will need to be
363
368
// written in the trailers at the end of the response.
@@ -911,7 +916,7 @@ func (cw *chunkWriter) writeHeader(p []byte) {
911
916
// send a Content-Length header.
912
917
// Further, we don't send an automatic Content-Length if they
913
918
// set a Transfer-Encoding, because they're generally incompatible.
914
- if w .handlerDone && ! trailers && ! hasTE && bodyAllowedForStatus (w .status ) && header .get ("Content-Length" ) == "" && (! isHEAD || len (p ) > 0 ) {
919
+ if w .handlerDone . isSet () && ! trailers && ! hasTE && bodyAllowedForStatus (w .status ) && header .get ("Content-Length" ) == "" && (! isHEAD || len (p ) > 0 ) {
915
920
w .contentLength = int64 (len (p ))
916
921
setHeader .contentLength = strconv .AppendInt (cw .res .clenBuf [:0 ], int64 (len (p )), 10 )
917
922
}
@@ -1234,7 +1239,7 @@ func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err er
1234
1239
}
1235
1240
1236
1241
func (w * response ) finishRequest () {
1237
- w .handlerDone = true
1242
+ w .handlerDone . setTrue ()
1238
1243
1239
1244
if ! w .wroteHeader {
1240
1245
w .WriteHeader (StatusOK )
@@ -1498,6 +1503,9 @@ func (w *response) sendExpectationFailed() {
1498
1503
// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
1499
1504
// and a Hijacker.
1500
1505
func (w * response ) Hijack () (rwc net.Conn , buf * bufio.ReadWriter , err error ) {
1506
+ if w .handlerDone .isSet () {
1507
+ panic ("net/http: Hijack called after ServeHTTP finished" )
1508
+ }
1501
1509
if w .wroteHeader {
1502
1510
w .cw .flush ()
1503
1511
}
@@ -1521,6 +1529,9 @@ func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
1521
1529
}
1522
1530
1523
1531
func (w * response ) CloseNotify () <- chan bool {
1532
+ if w .handlerDone .isSet () {
1533
+ panic ("net/http: CloseNotify called after ServeHTTP finished" )
1534
+ }
1524
1535
c := w .conn
1525
1536
c .mu .Lock ()
1526
1537
defer c .mu .Unlock ()
0 commit comments