@@ -1509,6 +1509,53 @@ func TestSameHostRedirectKeepsCredentials(t *testing.T) {
15091509 require .Truef (t , credsSeen , "credentials should be forwarded on same-host redirect" )
15101510}
15111511
1512+ func TestRedirectBackToOriginalHostKeepsCredentialsStripped (t * testing.T ) {
1513+ // Mirror net/http's sticky behaviour: once a redirect chain leaves the
1514+ // original host, credentials must stay stripped for the rest of the chain,
1515+ // even when a later hop redirects back to the original host.
1516+ credsSeen := false
1517+ final := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1518+ if r .Header .Get ("Authorization" ) != "" {
1519+ credsSeen = true
1520+ }
1521+ fmt .Fprint (w , ExpectedMessage )
1522+ }))
1523+ t .Cleanup (final .Close )
1524+
1525+ // middle listens on 127.0.0.1 but is reached via "localhost", so the hop
1526+ // from the origin (127.0.0.1) to middle is cross-host. It then redirects
1527+ // back to final, which shares the original "127.0.0.1" hostname.
1528+ middle := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1529+ http .Redirect (w , r , final .URL , http .StatusFound )
1530+ }))
1531+ t .Cleanup (middle .Close )
1532+ middlePort := middle .Listener .Addr ().(* net.TCPAddr ).Port
1533+ middleLocalhostURL := fmt .Sprintf ("http://localhost:%d" , middlePort )
1534+
1535+ origin := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1536+ http .Redirect (w , r , middleLocalhostURL , http .StatusFound )
1537+ }))
1538+ t .Cleanup (origin .Close )
1539+
1540+ cfg := HTTPClientConfig {
1541+ FollowRedirects : true ,
1542+ Authorization : & Authorization {
1543+ Type : "Bearer" ,
1544+ Credentials : "secret-token" ,
1545+ },
1546+ }
1547+ client , err := NewClientFromConfig (cfg , "test" )
1548+ require .NoError (t , err )
1549+
1550+ resp , err := client .Get (origin .URL )
1551+ require .NoError (t , err )
1552+ defer resp .Body .Close ()
1553+ _ , err = io .ReadAll (resp .Body )
1554+ require .NoError (t , err )
1555+
1556+ require .Falsef (t , credsSeen , "credentials must stay stripped after leaving the original host, even when redirected back to it" )
1557+ }
1558+
15121559func TestRoundTripperCrossHostRedirectDropsCredentials (t * testing.T ) {
15131560 // Verify that a custom http.Client built from NewRoundTripperFromConfig
15141561 // (not NewClientFromConfig) also strips credentials on cross-host redirects,
0 commit comments