@@ -1483,6 +1483,44 @@ func TestTransportDialPreservesNetOpProxyError(t *testing.T) {
1483
1483
}
1484
1484
}
1485
1485
1486
+ // Issue 36431: calls to RoundTrip should not mutate t.ProxyConnectHeader.
1487
+ //
1488
+ // (A bug caused dialConn to instead write the per-request Proxy-Authorization
1489
+ // header through to the shared Header instance, introducing a data race.)
1490
+ func TestTransportProxyDialDoesNotMutateProxyConnectHeader (t * testing.T ) {
1491
+ setParallel (t )
1492
+ defer afterTest (t )
1493
+
1494
+ proxy := httptest .NewTLSServer (NotFoundHandler ())
1495
+ defer proxy .Close ()
1496
+ c := proxy .Client ()
1497
+
1498
+ tr := c .Transport .(* Transport )
1499
+ tr .Proxy = func (* Request ) (* url.URL , error ) {
1500
+ u , _ := url .Parse (proxy .URL )
1501
+ u .User = url .UserPassword ("aladdin" , "opensesame" )
1502
+ return u , nil
1503
+ }
1504
+ h := tr .ProxyConnectHeader
1505
+ if h == nil {
1506
+ h = make (Header )
1507
+ }
1508
+ tr .ProxyConnectHeader = h .Clone ()
1509
+
1510
+ req , err := NewRequest ("GET" , "https://golang.fake.tld/" , nil )
1511
+ if err != nil {
1512
+ t .Fatal (err )
1513
+ }
1514
+ _ , err = c .Do (req )
1515
+ if err == nil {
1516
+ t .Errorf ("unexpected Get success" )
1517
+ }
1518
+
1519
+ if ! reflect .DeepEqual (tr .ProxyConnectHeader , h ) {
1520
+ t .Errorf ("tr.ProxyConnectHeader = %v; want %v" , tr .ProxyConnectHeader , h )
1521
+ }
1522
+ }
1523
+
1486
1524
// TestTransportGzipRecursive sends a gzip quine and checks that the
1487
1525
// client gets the same value back. This is more cute than anything,
1488
1526
// but checks that we don't recurse forever, and checks that
0 commit comments