@@ -2440,6 +2440,7 @@ func testTransportCancelRequest(t *testing.T, mode testMode) {
2440
2440
if d > 0 {
2441
2441
t .Logf ("pending requests = %d after %v (want 0)" , n , d )
2442
2442
}
2443
+ return false
2443
2444
}
2444
2445
return true
2445
2446
})
@@ -2599,6 +2600,65 @@ func testCancelRequestWithChannel(t *testing.T, mode testMode) {
2599
2600
if d > 0 {
2600
2601
t .Logf ("pending requests = %d after %v (want 0)" , n , d )
2601
2602
}
2603
+ return false
2604
+ }
2605
+ return true
2606
+ })
2607
+ }
2608
+
2609
+ // Issue 51354
2610
+ func TestCancelRequestWithBodyWithChannel (t * testing.T ) {
2611
+ run (t , testCancelRequestWithBodyWithChannel , []testMode {http1Mode })
2612
+ }
2613
+ func testCancelRequestWithBodyWithChannel (t * testing.T , mode testMode ) {
2614
+ if testing .Short () {
2615
+ t .Skip ("skipping test in -short mode" )
2616
+ }
2617
+
2618
+ const msg = "Hello"
2619
+ unblockc := make (chan struct {})
2620
+ ts := newClientServerTest (t , mode , HandlerFunc (func (w ResponseWriter , r * Request ) {
2621
+ io .WriteString (w , msg )
2622
+ w .(Flusher ).Flush () // send headers and some body
2623
+ <- unblockc
2624
+ })).ts
2625
+ defer close (unblockc )
2626
+
2627
+ c := ts .Client ()
2628
+ tr := c .Transport .(* Transport )
2629
+
2630
+ req , _ := NewRequest ("POST" , ts .URL , strings .NewReader ("withbody" ))
2631
+ cancel := make (chan struct {})
2632
+ req .Cancel = cancel
2633
+
2634
+ res , err := c .Do (req )
2635
+ if err != nil {
2636
+ t .Fatal (err )
2637
+ }
2638
+ body := make ([]byte , len (msg ))
2639
+ n , _ := io .ReadFull (res .Body , body )
2640
+ if n != len (body ) || ! bytes .Equal (body , []byte (msg )) {
2641
+ t .Errorf ("Body = %q; want %q" , body [:n ], msg )
2642
+ }
2643
+ close (cancel )
2644
+
2645
+ tail , err := io .ReadAll (res .Body )
2646
+ res .Body .Close ()
2647
+ if err != ExportErrRequestCanceled {
2648
+ t .Errorf ("Body.Read error = %v; want errRequestCanceled" , err )
2649
+ } else if len (tail ) > 0 {
2650
+ t .Errorf ("Spurious bytes from Body.Read: %q" , tail )
2651
+ }
2652
+
2653
+ // Verify no outstanding requests after readLoop/writeLoop
2654
+ // goroutines shut down.
2655
+ waitCondition (t , 10 * time .Millisecond , func (d time.Duration ) bool {
2656
+ n := tr .NumPendingRequestsForTesting ()
2657
+ if n > 0 {
2658
+ if d > 0 {
2659
+ t .Logf ("pending requests = %d after %v (want 0)" , n , d )
2660
+ }
2661
+ return false
2602
2662
}
2603
2663
return true
2604
2664
})
0 commit comments