File tree 3 files changed +56
-6
lines changed
3 files changed +56
-6
lines changed Original file line number Diff line number Diff line change @@ -352,10 +352,16 @@ func (r *Response) bodyIsWritable() bool {
352
352
return ok
353
353
}
354
354
355
- // isProtocolSwitch reports whether r is a response to a successful
356
- // protocol upgrade.
355
+ // isProtocolSwitch reports whether the response code and header
356
+ // indicate a successful protocol upgrade response .
357
357
func (r * Response ) isProtocolSwitch () bool {
358
- return r .StatusCode == StatusSwitchingProtocols &&
359
- r .Header .Get ("Upgrade" ) != "" &&
360
- httpguts .HeaderValuesContainsToken (r .Header ["Connection" ], "Upgrade" )
358
+ return isProtocolSwitchResponse (r .StatusCode , r .Header )
359
+ }
360
+
361
+ // isProtocolSwitchResponse reports whether the response code and header
362
+ // indicate a successful protocol upgrade response.
363
+ func isProtocolSwitchResponse (code int , h Header ) bool {
364
+ return code == StatusSwitchingProtocols &&
365
+ h .Get ("Upgrade" ) != "" &&
366
+ httpguts .HeaderValuesContainsToken (h ["Connection" ], "Upgrade" )
361
367
}
Original file line number Diff line number Diff line change @@ -6443,3 +6443,44 @@ func BenchmarkResponseStatusLine(b *testing.B) {
6443
6443
}
6444
6444
})
6445
6445
}
6446
+ func TestDisableKeepAliveUpgrade (t * testing.T ) {
6447
+ if testing .Short () {
6448
+ t .Skip ("skipping in short mode" )
6449
+ }
6450
+
6451
+ setParallel (t )
6452
+ defer afterTest (t )
6453
+
6454
+ s := httptest .NewServer (HandlerFunc (func (w ResponseWriter , r * Request ) {
6455
+ c , _ , err := w .(Hijacker ).Hijack ()
6456
+ if err != nil {
6457
+ return
6458
+ }
6459
+ defer c .Close ()
6460
+
6461
+ c .Write ([]byte ("hello" ))
6462
+ }))
6463
+ defer s .Close ()
6464
+
6465
+ s .Client ().Transport .(* Transport ).DisableKeepAlives = true
6466
+
6467
+ resp , err := s .Client ().Get ("/" )
6468
+ if err != nil {
6469
+ t .Fatalf ("failed to perform request: %v" , err )
6470
+ }
6471
+ defer resp .Body .Close ()
6472
+
6473
+ rwc , ok := resp .Body .(io.ReadWriteCloser )
6474
+ if ! ok {
6475
+ t .Fatalf ("body is not a io.ReadWriteCloser: %T" , resp .Body )
6476
+ }
6477
+
6478
+ b , err := ioutil .ReadAll (rwc )
6479
+ if err != nil {
6480
+ t .Fatalf ("failed to read response body: %v" , err )
6481
+ }
6482
+
6483
+ if string (b ) != "hello" {
6484
+ t .Fatalf ("unexpected value read from rwc: %q" , b )
6485
+ }
6486
+ }
Original file line number Diff line number Diff line change @@ -1290,7 +1290,10 @@ func (cw *chunkWriter) writeHeader(p []byte) {
1290
1290
if ! connectionHeaderSet {
1291
1291
setHeader .connection = "keep-alive"
1292
1292
}
1293
- } else if ! w .req .ProtoAtLeast (1 , 1 ) || w .wantsClose {
1293
+ } else if ! w .req .ProtoAtLeast (1 , 1 ) ||
1294
+ // Only close if the request indicates the client wants to close
1295
+ // and we are not upgrading the connection.
1296
+ (w .wantsClose && ! isProtocolSwitchResponse (w .status , header )) {
1294
1297
w .closeAfterReply = true
1295
1298
}
1296
1299
You can’t perform that action at this time.
0 commit comments