@@ -4521,3 +4521,65 @@ func TestClientConnTooIdle(t *testing.T) {
4521
4521
}
4522
4522
}
4523
4523
}
4524
+
4525
+ type fakeConnErr struct {
4526
+ net.Conn
4527
+ writeErr error
4528
+ closed bool
4529
+ }
4530
+
4531
+ func (fce * fakeConnErr ) Write (b []byte ) (n int , err error ) {
4532
+ return 0 , fce .writeErr
4533
+ }
4534
+
4535
+ func (fce * fakeConnErr ) Close () error {
4536
+ fce .closed = true
4537
+ return nil
4538
+ }
4539
+
4540
+ // issue 39337: close the connection on a failed write
4541
+ func TestTransportNewClientConnCloseOnWriteError (t * testing.T ) {
4542
+ tr := & Transport {}
4543
+ writeErr := errors .New ("write error" )
4544
+ fakeConn := & fakeConnErr {writeErr : writeErr }
4545
+ _ , err := tr .NewClientConn (fakeConn )
4546
+ if err != writeErr {
4547
+ t .Fatalf ("expected %v, got %v" , writeErr , err )
4548
+ }
4549
+ if ! fakeConn .closed {
4550
+ t .Error ("expected closed conn" )
4551
+ }
4552
+ }
4553
+
4554
+ func TestTransportRoundtripCloseOnWriteError (t * testing.T ) {
4555
+ req , err := http .NewRequest ("GET" , "https://dummy.tld/" , nil )
4556
+ if err != nil {
4557
+ t .Fatal (err )
4558
+ }
4559
+ st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {}, optOnlyServer )
4560
+ defer st .Close ()
4561
+
4562
+ tr := & Transport {TLSClientConfig : tlsConfigInsecure }
4563
+ defer tr .CloseIdleConnections ()
4564
+ cc , err := tr .dialClientConn (st .ts .Listener .Addr ().String (), false )
4565
+ if err != nil {
4566
+ t .Fatal (err )
4567
+ }
4568
+
4569
+ writeErr := errors .New ("write error" )
4570
+ cc .wmu .Lock ()
4571
+ cc .werr = writeErr
4572
+ cc .wmu .Unlock ()
4573
+
4574
+ _ , err = cc .RoundTrip (req )
4575
+ if err != writeErr {
4576
+ t .Fatalf ("expected %v, got %v" , writeErr , err )
4577
+ }
4578
+
4579
+ cc .mu .Lock ()
4580
+ closed := cc .closed
4581
+ cc .mu .Unlock ()
4582
+ if ! closed {
4583
+ t .Fatal ("expected closed" )
4584
+ }
4585
+ }
0 commit comments