diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs index ba03ffe24..435eafb79 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/Common/WebRequestPSCmdlet.Common.cs @@ -1287,7 +1287,7 @@ namespace Microsoft.PowerShell.Commands _cancelToken = new CancellationTokenSource(); HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult(); - if (stripAuthorization && IsRedirectCode(response.StatusCode)) + if (stripAuthorization && IsRedirectCode(response.StatusCode) && response.Headers.Location != null) { _cancelToken.Cancel(); _cancelToken = null; diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index d60a2187f..8c4c49dc8 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -822,6 +822,27 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } + It "Validates Invoke-WebRequest handles responses without Location header for requests with Authorization header and redirect: " -TestCases $redirectTests { + param($redirectType, $redirectedMethod) + # Skip relative test as it is not a valid response type. + if ($redirectType -eq 'relative') { return } + + # When an Authorization request header is present, + # and -PreserveAuthorizationOnRedirect is not present, + # PowerShell should throw an HTTP Response Exception + # for a redirect response which does not contain a Location response header. + # The correct redirect status code should be included in the exception. + + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $command = "Invoke-WebRequest -Uri '$uri' -Headers @{Authorization = 'foo'}" + $response = ExecuteWebCommand -command $command + + $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' + $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode + $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty + } + #endregion Redirect tests Context "Invoke-WebRequest SkipHeaderVerification Tests" { @@ -2137,6 +2158,27 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { $response.Content.Method | Should -Be $redirectedMethod } + It "Validates Invoke-RestMethod handles responses without Location header for requests with Authorization header and redirect: " -TestCases $redirectTests { + param($redirectType, $redirectedMethod) + # Skip relative test as it is not a valid response type. + if ($redirectType -eq 'relative') { return } + + # When an Authorization request header is present, + # and -PreserveAuthorizationOnRedirect is not present, + # PowerShell should throw an HTTP Response Exception + # for a redirect response which does not contain a Location response header. + # The correct redirect status code should be included in the exception. + + $StatusCode = [int][System.Net.HttpStatusCode]$redirectType + $uri = Get-WebListenerUrl -Test Response -Query @{statuscode = $StatusCode} + $command = "Invoke-RestMethod -Uri '$uri' -Headers @{Authorization = 'foo'}" + $response = ExecuteWebCommand -command $command + + $response.Error.Exception | Should -BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException' + $response.Error.Exception.Response.StatusCode | Should -Be $StatusCode + $response.Error.Exception.Response.Headers.Location | Should -BeNullOrEmpty + } + #endregion Redirect tests Context "Invoke-RestMethod SkipHeaderVerification Tests" {