From 211ee632dcf7716f256f3002dbf1fc109c35a04f Mon Sep 17 00:00:00 2001 From: Mark Kraus Date: Sat, 13 Jan 2018 01:51:04 -0600 Subject: [PATCH] [Feature] Replace HttpListener Redirect Tests with WebListener (#5872) - adds type query to Redirect listener and adjusts logic to accommodate - Replaces HttpListener Redirect Tests with WebListener --- .../WebCmdlets.Tests.ps1 | 62 +++++++++---------- .../Controllers/RedirectController.cs | 24 +++++-- test/tools/WebListener/README.md | 3 +- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 index e44dc0c67..67992b9c7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1 @@ -757,51 +757,49 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" { It "Validates Invoke-WebRequest with -PreserveAuthorizationOnRedirect preserves the authorization header on redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) - - $response = ExecuteRedirectRequest -Uri "http://localhost:8080/PowerShell?test=redirect&type=$redirectType" -PreserveAuthorizationOnRedirect + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Uri $uri -PreserveAuthorizationOnRedirect $response.Error | Should BeNullOrEmpty - # ensure Authorization header has been preserved. - $response.Content.Headers -contains "Authorization" | Should Be $true + $response.Content.Headers."Authorization" | Should BeExactly "test" } It "Validates Invoke-WebRequest preserves the authorization header on multiple redirects: " -TestCases $redirectTests { param($redirectType) - - $response = ExecuteRedirectRequest -Uri "http://localhost:8080/PowerShell?test=redirect&type=$redirectType&multiredirect=true" -PreserveAuthorizationOnRedirect + $uri = Get-WebListenerUrl -Test 'Redirect' -TestValue 3 -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Uri $uri -PreserveAuthorizationOnRedirect $response.Error | Should BeNullOrEmpty - # ensure Authorization header was stripped - $response.Content.Headers -contains "Authorization" | Should Be $true + $response.Content.Headers."Authorization" | Should BeExactly "test" } It "Validates Invoke-WebRequest strips the authorization header on various redirects: " -TestCases $redirectTests { param($redirectType) - - $response = ExecuteRedirectRequest -Uri "http://localhost:8080/PowerShell?test=redirect&type=$redirectType" + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Uri $uri $response.Error | Should BeNullOrEmpty # ensure user-agent is present (i.e., no false positives ) - $response.Content.Headers -contains "User-Agent" | Should Be $true + $response.Content.Headers."User-Agent" | Should Not BeNullOrEmpty # ensure Authorization header has been removed. - $response.Content.Headers -contains "Authorization" | Should Be $false + $response.Content.Headers."Authorization" | Should BeNullOrEmpty } # NOTE: Only testing redirection of POST -> GET for unique underlying values of HttpStatusCode. # Some names overlap in underlying value. It "Validates Invoke-WebRequest strips the authorization header redirects and switches from POST to GET when it handles the redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) - - $response = ExecuteRedirectRequest -Uri "http://localhost:8080/PowerShell?test=redirect&type=$redirectType" -Method 'POST' + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Uri $uri -Method 'POST' $response.Error | Should BeNullOrEmpty # ensure user-agent is present (i.e., no false positives ) - $response.Content.Headers -contains "User-Agent" | Should Be $true + $response.Content.Headers."User-Agent" | Should Not BeNullOrEmpty # ensure Authorization header has been removed. - $response.Content.Headers -contains "Authorization" | Should Be $false + $response.Content.Headers."Authorization" | Should BeNullOrEmpty # ensure POST was changed to GET for selected redirections and remains as POST for others. - $response.Content.HttpMethod | Should Be $redirectedMethod + $response.Content.Method | Should Be $redirectedMethod } #endregion Redirect tests @@ -1753,50 +1751,50 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" { It "Validates Invoke-RestMethod with -PreserveAuthorizationOnRedirect preserves the authorization header on redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) - - $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri "http://localhost:8081/PowerShell?test=redirect&type=$redirectType" -PreserveAuthorizationOnRedirect + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri $uri -PreserveAuthorizationOnRedirect $response.Error | Should BeNullOrEmpty # ensure Authorization header has been preserved. - $response.Content.Headers -contains "Authorization" | Should Be $true + $response.Content.Headers."Authorization" | Should BeExactly "test" } It "Validates Invoke-RestMethod preserves the authorization header on multiple redirects: " -TestCases $redirectTests { param($redirectType) - - $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri "http://localhost:8081/PowerShell?test=redirect&type=$redirectType&multiredirect=true" -PreserveAuthorizationOnRedirect + $uri = Get-WebListenerUrl -Test 'Redirect' -TestValue 3 -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri $uri -PreserveAuthorizationOnRedirect $response.Error | Should BeNullOrEmpty # ensure Authorization header was stripped - $response.Content.Headers -contains "Authorization" | Should Be $true + $response.Content.Headers."Authorization" | Should BeExactly "test" } It "Validates Invoke-RestMethod strips the authorization header on various redirects: " -TestCases $redirectTests { param($redirectType) - - $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri "http://localhost:8081/PowerShell?test=redirect&type=$redirectType" + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri $uri $response.Error | Should BeNullOrEmpty # ensure user-agent is present (i.e., no false positives ) - $response.Output.Headers -contains "User-Agent" | Should Be $true + $response.Content.Headers."User-Agent" | Should Not BeNullOrEmpty # ensure Authorization header has been removed. - $response.Content.Headers -contains "Authorization" | Should Be $false + $response.Content.Headers."Authorization" | Should BeNullOrEmpty } # NOTE: Only testing redirection of POST -> GET for unique underlying values of HttpStatusCode. # Some names overlap in underlying value. It "Validates Invoke-RestMethod strips the authorization header redirects and switches from POST to GET when it handles the redirect: " -TestCases $redirectTests { param($redirectType, $redirectedMethod) - - $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri "http://localhost:8081/PowerShell?test=redirect&type=$redirectType" -Method 'POST' + $uri = Get-WebListenerUrl -Test 'Redirect' -Query @{type = $redirectType} + $response = ExecuteRedirectRequest -Cmdlet 'Invoke-RestMethod' -Uri $uri -Method 'POST' $response.Error | Should BeNullOrEmpty # ensure user-agent is present (i.e., no false positives ) - $response.Content.Headers -contains "User-Agent" | Should Be $true + $response.Content.Headers."User-Agent" | Should Not BeNullOrEmpty # ensure Authorization header has been removed. - $response.Content.Headers -contains "Authorization" | Should Be $false + $response.Content."Authorization" | Should BeNullOrEmpty # ensure POST was changed to GET for selected redirections and remains as POST for others. - $response.Content.HttpMethod | Should Be $redirectedMethod + $response.Content.Method | Should Be $redirectedMethod } #endregion Redirect tests diff --git a/test/tools/WebListener/Controllers/RedirectController.cs b/test/tools/WebListener/Controllers/RedirectController.cs index b0ed768d2..faa7747a7 100644 --- a/test/tools/WebListener/Controllers/RedirectController.cs +++ b/test/tools/WebListener/Controllers/RedirectController.cs @@ -3,29 +3,45 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Net; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.Extensions.Primitives; using mvc.Models; + namespace mvc.Controllers { public class RedirectController : Controller { public IActionResult Index(int count) { - string url; + string url = Regex.Replace(input: Request.GetDisplayUrl(), pattern: "\\/Redirect.*", replacement: "", options: RegexOptions.IgnoreCase); if (count <= 1) { - url = "/Get/"; + url = $"{url}/Get/"; } else { int nextHop = count - 1; - url = String.Format("/Redirect/{0}", nextHop); + url = $"{url}/Redirect/{nextHop}"; } - Response.Redirect(url, false); + + if (Request.Query.TryGetValue("type", out StringValues type) && Enum.TryParse(type.FirstOrDefault(), out HttpStatusCode status)) + { + Response.StatusCode = (int)status; + url = $"{url}?type={type.FirstOrDefault()}"; + Response.Headers.Add("Location", url); + } + else + { + Response.Redirect(url, false); + } + ViewData["Url"] = url; + return View(); } public IActionResult Error() diff --git a/test/tools/WebListener/README.md b/test/tools/WebListener/README.md index 4be07b522..91eb1e987 100644 --- a/test/tools/WebListener/README.md +++ b/test/tools/WebListener/README.md @@ -426,7 +426,8 @@ Invoke-RestMethod -Uri $uri -Body $body -Method 'Put' ### /Redirect/ -Will 302 redirect to `/Get/`. If a number is supplied, redirect will occur that many times. Can be used to test maximum redirects. +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`. ```powershell $uri = Get-WebListenerUrl -Test 'Redirect' -TestValue '2'