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 fcabe09c187..ed3b1ccc272 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 @@ -1257,7 +1257,7 @@ internal virtual HttpResponseMessage GetResponse(HttpClient client, HttpRequestM // recreate the HttpClient with redirection enabled since the first call suppressed redirection using (client = GetHttpClient(false)) - using (HttpRequestMessage redirectRequest = GetRequest(response.Headers.Location, stripAuthorization:true)) + using (HttpRequestMessage redirectRequest = GetRequest(new Uri(request.RequestUri, response.Headers.Location), stripAuthorization:true)) { FillRequestStream(redirectRequest); _cancelToken = new CancellationTokenSource(); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index 27087ccb9e9..463bec06a30 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -363,6 +363,8 @@ $redirectTests = @( @{redirectType = 'TemporaryRedirect'; redirectedMethod = 'GET'} @{redirectType = 'RedirectKeepVerb'; redirectedMethod = 'GET'} # Synonym for TemporaryRedirect + + @{redirectType = 'relative'; redirectedMethod = 'GET'} ) $PendingCertificateTest = $false diff --git a/test/tools/WebListener/Controllers/RedirectController.cs b/test/tools/WebListener/Controllers/RedirectController.cs index ac5e14f26a6..8a65c5626c9 100644 --- a/test/tools/WebListener/Controllers/RedirectController.cs +++ b/test/tools/WebListener/Controllers/RedirectController.cs @@ -30,12 +30,19 @@ public IActionResult Index(int count) url = $"{url}/Redirect/{nextHop}"; } - if (Request.Query.TryGetValue("type", out StringValues type) && Enum.TryParse(type.FirstOrDefault(), out HttpStatusCode status)) + var typeIsPresent = Request.Query.TryGetValue("type", out StringValues type); + + if (typeIsPresent && Enum.TryParse(type.FirstOrDefault(), out HttpStatusCode status)) { Response.StatusCode = (int)status; url = $"{url}?type={type.FirstOrDefault()}"; Response.Headers.Add("Location", url); } + else if (typeIsPresent && String.Equals(type.FirstOrDefault(), "relative", StringComparison.InvariantCultureIgnoreCase)) + { + url = new Uri($"{url}?type={type.FirstOrDefault()}").PathAndQuery; + Response.Redirect(url, false); + } else { Response.Redirect(url, false); diff --git a/test/tools/WebListener/README.md b/test/tools/WebListener/README.md index f589a54432a..bc5cfc98e33 100644 --- a/test/tools/WebListener/README.md +++ b/test/tools/WebListener/README.md @@ -489,6 +489,7 @@ Invoke-RestMethod -Uri $uri -Body $body -Method 'Put' Will `302` redirect to `/Get/`. If a number is supplied, redirect will occur that many times. Can be used to test maximum redirects. If the `type` query field is supplied the corresponding `System.Net.HttpStatusCode` will be returned instead of `302`. +If `type` is `relative`, the redirect URI will be relative instead of absolute. ```powershell $uri = Get-WebListenerUrl -Test 'Redirect' -TestValue '2'