Replace Remaining HttpBin.org Tests with WebListener (#5665)

•Replaces all remaining test that rely on httpbin.org
•Adds Put, Post, Patch, and Delete tests to WebListener by means of routes to Get test and modifications to the Get controller.
•Adds responsephrase option to the Response test to accommodate error message tests
•removed redundant GET tests from irm and iwr tests.
•Fixed markdown linting errors in README.md for WebListener
This commit is contained in:
Mark Kraus 2017-12-13 09:28:05 -06:00 committed by Travis Plunk
parent 02cc3db3fb
commit acf68f462c
7 changed files with 341 additions and 163 deletions

View file

@ -3,7 +3,7 @@
#
# This is a Pester test suite which validate the Web cmdlets.
#
# Note: These tests use data from http://httpbin.org/
# Note: These tests use data from WebListener
#
# Invokes the given command via script block invocation.
@ -642,7 +642,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
# patch Returns PATCH data.
# put Returns PUT data.
# delete Returns DELETE data
$testMethods = @("GET", "POST", "PATCH", "PUT", "DELETE")
$testMethods = @("POST", "PATCH", "PUT", "DELETE")
$contentTypes = @("text/plain", "application/xml", "application/json")
foreach ($contentType in $contentTypes)
@ -650,20 +650,11 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
foreach ($method in $testMethods)
{
# Operation options
$operation = $method.ToLower()
$uri = "http://httpbin.org/$operation"
$uri = Get-WebListenerUrl -Test $method
$body = GetTestData -contentType $contentType
$command = "Invoke-WebRequest -Uri $uri -Body '$body' -Method $method -ContentType $contentType"
if ($method -eq "GET")
{
$command = "Invoke-WebRequest -Uri $uri"
}
else
{
$command = "Invoke-WebRequest -Uri $uri -Body '$body' -Method $method -ContentType $contentType -TimeoutSec 5"
}
It "$command" {
It "Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Body [body data]" {
$result = ExecuteWebCommand -command $command
ValidateResponse -response $result
@ -671,22 +662,9 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
# Validate response content
$jsonContent = $result.Output.Content | ConvertFrom-Json
$jsonContent.url | Should Match $uri
# For a GET request, there is no data property to validate.
if ($method -ne "GET")
{
$jsonContent.headers.'Content-Type' | Should Match $contentType
# Validate that the response Content.data field is the same as what we sent.
if ($contentType -eq "application/xml")
{
$jsonContent.data | Should Be $body
}
else
{
$jsonContent.data | Should Match $body
}
}
$jsonContent.headers.'Content-Type' | Should Match $contentType
# Validate that the response Content.data field is the same as what we sent.
$jsonContent.data | Should Be $body
}
}
}
@ -760,9 +738,12 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
It "Validate Invoke-WebRequest default ContentType for CustomMethod POST" {
$command = "Invoke-WebRequest -Uri 'http://httpbin.org/post' -CustomMethod POST -Body 'testparam=testvalue'"
$uri = Get-WebListenerUrl -Test 'Post'
$command = "Invoke-WebRequest -Uri '$uri' -CustomMethod POST -Body 'testparam=testvalue'"
$result = ExecuteWebCommand -command $command
($result.Output.Content | ConvertFrom-Json).form.testparam | Should Be "testvalue"
$jsonResult = $result.Output.Content | ConvertFrom-Json
$jsonResult.form.testparam | Should Be "testvalue"
$jsonResult.Headers.'Content-Type' | Should Be "application/x-www-form-urlencoded"
}
It "Validate Invoke-WebRequest body is converted to query params for CustomMethod GET" {
@ -775,14 +756,20 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
It "Validate Invoke-WebRequest returns HTTP errors in exception" {
$command = "Invoke-WebRequest -Uri http://httpbin.org/status/418"
$query = @{
body = "I am a teapot!!!"
statuscode = 418
responsephrase = "I am a teapot"
}
$uri = Get-WebListenerUrl -Test 'Response' -Query $query
$command = "Invoke-WebRequest -Uri '$uri'"
$result = ExecuteWebCommand -command $command
$result.Error.ErrorDetails.Message | Should Match "\-=\[ teapot \]"
$result.Error.Exception | Should BeOfType Microsoft.PowerShell.Commands.HttpResponseException
$result.Error.ErrorDetails.Message | Should Be $query.body
$result.Error.Exception | Should BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException'
$result.Error.Exception.Response.StatusCode | Should Be 418
$result.Error.Exception.Response.ReasonPhrase | Should Be "I'm a teapot"
$result.Error.Exception.Message | Should Match ": 418 \(I'm a teapot\)\."
$result.Error.Exception.Response.ReasonPhrase | Should Be $query.responsephrase
$result.Error.Exception.Message | Should Match ": 418 \($($query.responsephrase)\)\."
$result.Error.FullyQualifiedErrorId | Should Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand"
}
@ -1622,7 +1609,9 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
It "Validate Invoke-RestMethod error with -Proxy option - '<name>'" -TestCases $testCase {
param($proxy_address, $name, $protocol)
$command = "Invoke-RestMethod -Uri '${protocol}://httpbin.org/' -Proxy '${proxy_address}'"
# A non-loopback URI is required but the external resource will not be accessed
$uri = 'http://httpbin.org'
$command = "Invoke-RestMethod -Uri '$uri' -Proxy '${proxy_address}'"
$result = ExecuteWebCommand -command $command
$result.Error.FullyQualifiedErrorId | Should Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand"
@ -1679,7 +1668,7 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
# patch Returns PATCH data.
# put Returns PUT data.
# delete Returns DELETE data
$testMethods = @("GET", "POST", "PATCH", "PUT", "DELETE")
$testMethods = @("POST", "PATCH", "PUT", "DELETE")
$contentTypes = @("text/plain", "application/xml", "application/json")
foreach ($contentType in $contentTypes)
@ -1687,41 +1676,20 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
foreach ($method in $testMethods)
{
# Operation options
$operation = $method.ToLower()
$uri = "http://httpbin.org/$operation"
$uri = Get-WebListenerUrl -Test $method
$body = GetTestData -contentType $contentType
$command = "Invoke-RestMethod -Uri $uri -Body '$body' -Method $method -ContentType $contentType"
if ($method -eq "GET")
{
$command = "Invoke-RestMethod -Uri $uri"
}
else
{
$command = "Invoke-RestMethod -Uri $uri -Body '$body' -Method $method -ContentType $contentType -TimeoutSec 5"
}
It "$command" {
It "Invoke-RestMethod -Uri $uri -Method $method -ContentType $contentType -Body [body data]" {
$result = ExecuteWebCommand -command $command
# Validate response
$result.Output.url | Should Match $uri
$result.Output.headers.'Content-Type' | Should Match $contentType
# For a GET request, there is no data property to validate.
if ($method -ne "GET")
{
$result.Output.headers.'Content-Type' | Should Match $contentType
# Validate that the response Content.data field is the same as what we sent.
if ($contentType -eq "application/xml")
{
$result.Output.data | Should Be $body
}
else
{
$result.Output.data | Should Match $body
}
}
# Validate that the response Content.data field is the same as what we sent.
$result.Output.data | Should Be $body
}
}
}
@ -1794,9 +1762,11 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
It "Validate Invoke-RestMethod default ContentType for CustomMethod POST" {
$command = "Invoke-RestMethod -Uri 'http://httpbin.org/post' -CustomMethod POST -Body 'testparam=testvalue'"
$uri = Get-WebListenerUrl -Test 'Post'
$command = "Invoke-RestMethod -Uri '$uri' -CustomMethod POST -Body 'testparam=testvalue'"
$result = ExecuteWebCommand -command $command
$result.Output.form.testparam | Should Be "testvalue"
$result.Output.Headers.'Content-Type' | Should Be "application/x-www-form-urlencoded"
}
It "Validate Invoke-RestMethod body is converted to query params for CustomMethod GET" {
@ -1809,14 +1779,20 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
It "Validate Invoke-RestMethod returns HTTP errors in exception" {
$command = "Invoke-RestMethod -Uri http://httpbin.org/status/418"
$query = @{
body = "I am a teapot!!!"
statuscode = 418
responsephrase = "I am a teapot"
}
$uri = Get-WebListenerUrl -Test 'Response' -Query $query
$command = "Invoke-RestMethod -Uri '$uri'"
$result = ExecuteWebCommand -command $command
$result.Error.ErrorDetails.Message | Should Match "\-=\[ teapot \]"
$result.Error.Exception | Should BeOfType Microsoft.PowerShell.Commands.HttpResponseException
$result.Error.ErrorDetails.Message | Should Be $query.body
$result.Error.Exception | Should BeOfType 'Microsoft.PowerShell.Commands.HttpResponseException'
$result.Error.Exception.Response.StatusCode | Should Be 418
$result.Error.Exception.Response.ReasonPhrase | Should Be "I'm a teapot"
$result.Error.Exception.Message | Should Match ": 418 \(I'm a teapot\)\."
$result.Error.Exception.Response.ReasonPhrase | Should Be $query.responsephrase
$result.Error.Exception.Message | Should Match ": 418 \($($query.responsephrase)\)\."
$result.Error.FullyQualifiedErrorId | Should Be "WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand"
}
@ -2489,48 +2465,50 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
Describe "Validate Invoke-WebRequest and Invoke-RestMethod -InFile" -Tags "Feature" {
Context "InFile parameter negative tests" {
$testCases = @(
BeforeAll {
$uri = Get-WebListenerUrl -Test 'Post'
$testCases = @(
#region INVOKE-WEBREQUEST
@{
Name = 'Validate error for Invoke-WebRequest -InFile ""'
ScriptBlock = {Invoke-WebRequest -Uri http://httpbin.org/post -Method Post -InFile ""}
ExpectedFullyQualifiedErrorId = 'WebCmdletInFileNotFilePathException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
@{
Name = 'Validate error for Invoke-WebRequest -InFile ""'
ScriptBlock = {Invoke-WebRequest -Uri $uri -Method Post -InFile ""}
ExpectedFullyQualifiedErrorId = 'WebCmdletInFileNotFilePathException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
@{
Name = 'Validate error for Invoke-WebRequest -InFile'
ScriptBlock = {Invoke-WebRequest -Uri http://httpbin.org/post -Method Post -InFile}
ExpectedFullyQualifiedErrorId = 'MissingArgument,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
@{
Name = 'Validate error for Invoke-WebRequest -InFile'
ScriptBlock = {Invoke-WebRequest -Uri $uri -Method Post -InFile}
ExpectedFullyQualifiedErrorId = 'MissingArgument,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
@{
Name = "Validate error for Invoke-WebRequest -InFile $TestDrive\content.txt"
ScriptBlock = {Invoke-WebRequest -Uri http://httpbin.org/post -Method Post -InFile $TestDrive\content.txt}
ExpectedFullyQualifiedErrorId = 'PathNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
@{
Name = "Validate error for Invoke-WebRequest -InFile $TestDrive\content.txt"
ScriptBlock = {Invoke-WebRequest -Uri $uri -Method Post -InFile $TestDrive\content.txt}
ExpectedFullyQualifiedErrorId = 'PathNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand'
}
#endregion
#region INVOKE-RESTMETHOD
@{
Name = "Validate error for Invoke-RestMethod -InFile ''"
ScriptBlock = {Invoke-RestMethod -Uri http://httpbin.org/post -Method Post -InFile ''}
ExpectedFullyQualifiedErrorId = 'WebCmdletInFileNotFilePathException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
@{
Name = "Validate error for Invoke-RestMethod -InFile ''"
ScriptBlock = {Invoke-RestMethod -Uri $uri -Method Post -InFile ''}
ExpectedFullyQualifiedErrorId = 'WebCmdletInFileNotFilePathException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
@{
Name = "Validate error for Invoke-RestMethod -InFile <null>"
ScriptBlock = {Invoke-RestMethod -Uri http://httpbin.org/post -Method Post -InFile}
ExpectedFullyQualifiedErrorId = 'MissingArgument,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
@{
Name = "Validate error for Invoke-RestMethod -InFile <null>"
ScriptBlock = {Invoke-RestMethod -Uri $uri -Method Post -InFile}
ExpectedFullyQualifiedErrorId = 'MissingArgument,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
@{
Name = "Validate error for Invoke-RestMethod -InFile $TestDrive\content.txt"
ScriptBlock = {Invoke-RestMethod -Uri http://httpbin.org/post -Method Post -InFile $TestDrive\content.txt}
ExpectedFullyQualifiedErrorId = 'PathNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
@{
Name = "Validate error for Invoke-RestMethod -InFile $TestDrive\content.txt"
ScriptBlock = {Invoke-RestMethod -Uri $uri -Method Post -InFile $TestDrive\content.txt}
ExpectedFullyQualifiedErrorId = 'PathNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
#endregion
)
)
}
It "<Name>" -TestCases $testCases {
param ($scriptblock, $expectedFullyQualifiedErrorId)
@ -2551,18 +2529,21 @@ Describe "Validate Invoke-WebRequest and Invoke-RestMethod -InFile" -Tags "Featu
BeforeAll {
$filePath = Join-Path $TestDrive test.txt
New-Item -Path $filePath -Value "hello" -ItemType File -Force
New-Item -Path $filePath -Value "hello=world" -ItemType File -Force
$uri = Get-WebListenerUrl -Test 'Post'
}
It "Invoke-WebRequest -InFile" {
$result = Invoke-WebRequest -InFile $filePath -Uri http://httpbin.org/post -Method Post
$result = Invoke-WebRequest -InFile $filePath -Uri $uri -Method Post
$content = $result.Content | ConvertFrom-Json
$content.form | Should Match "hello"
$content.form.hello.Count | Should Be 1
$content.form.hello[0] | Should Match "world"
}
It "Invoke-RestMethod -InFile" {
$result = Invoke-RestMethod -InFile $filePath -Uri http://httpbin.org/post -Method Post
$result.form | Should Match "hello"
$result = Invoke-RestMethod -InFile $filePath -Uri $uri -Method Post
$result.form.hello.Count | Should Be 1
$result.form.hello[0] | Should Match "world"
}
}
}

View file

@ -1,4 +1,4 @@
Class WebListener
Class WebListener
{
[int]$HttpPort
[int]$HttpsPort
@ -8,7 +8,7 @@ Class WebListener
WebListener () { }
[String] GetStatus()
[String] GetStatus()
{
return $This.Job.JobStateInfo.State
}
@ -16,23 +16,23 @@ Class WebListener
[WebListener]$WebListener
function Get-WebListener
function Get-WebListener
{
[CmdletBinding(ConfirmImpact = 'Low')]
[OutputType([WebListener])]
param()
process
process
{
return [WebListener]$Script:WebListener
}
}
function Start-WebListener
function Start-WebListener
{
[CmdletBinding(ConfirmImpact = 'Low')]
[OutputType([WebListener])]
param
param
(
[ValidateRange(1,65535)]
[int]$HttpPort = 8083,
@ -46,8 +46,8 @@ function Start-WebListener
[ValidateRange(1,65535)]
[int]$TlsPort = 8086
)
process
process
{
$runningListener = Get-WebListener
if ($null -ne $runningListener -and $runningListener.GetStatus() -eq 'Running')
@ -60,7 +60,7 @@ function Start-WebListener
$serverPfx = 'ServerCert.pfx'
$serverPfxPassword = 'password'
$initCompleteMessage = 'Now listening on'
$serverPfxPath = Join-Path $MyInvocation.MyCommand.Module.ModuleBase $serverPfx
$timeOut = (get-date).AddSeconds($initTimeoutSeconds)
$Job = Start-Job {
@ -69,7 +69,7 @@ function Start-WebListener
dotnet $using:appDll $using:serverPfxPath $using:serverPfxPassword $using:HttpPort $using:HttpsPort $using:Tls11Port $using:TlsPort
}
$Script:WebListener = [WebListener]@{
HttpPort = $HttpPort
HttpPort = $HttpPort
HttpsPort = $HttpsPort
Tls11Port = $Tls11Port
TlsPort = $TlsPort
@ -83,8 +83,8 @@ function Start-WebListener
$isRunning = $initStatus -match $initCompleteMessage
}
while (-not $isRunning -and (get-date) -lt $timeOut)
if (-not $isRunning)
if (-not $isRunning)
{
$Job | Stop-Job -PassThru | Receive-Job
$Job | Remove-Job
@ -94,13 +94,13 @@ function Start-WebListener
}
}
function Stop-WebListener
function Stop-WebListener
{
[CmdletBinding(ConfirmImpact = 'Low')]
[OutputType([Void])]
param()
process
process
{
$Script:WebListener.job | Stop-Job -PassThru | Remove-Job
$Script:WebListener = $null
@ -131,10 +131,14 @@ function Get-WebListenerUrl {
'Cert',
'Compression',
'Delay',
'Delete',
'Encoding',
'Get',
'Home',
'Multipart',
'Patch',
'Post',
'Put',
'Redirect',
'Response',
'ResponseHeaders',
@ -173,7 +177,7 @@ function Get-WebListenerUrl {
{
$Uri.Path = '{0}/{1}' -f $Test, $TestValue
}
else
else
{
$Uri.Path = $Test
}

View file

@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
@ -29,8 +30,26 @@ namespace mvc.Controllers
{"args" , args},
{"headers", headers},
{"origin" , Request.HttpContext.Connection.RemoteIpAddress.ToString()},
{"url" , UriHelper.GetDisplayUrl(Request)}
{"url" , UriHelper.GetDisplayUrl(Request)},
{"method" , Request.Method}
};
if (Request.HasFormContentType)
{
Hashtable form = new Hashtable();
foreach (var key in Request.Form.Keys)
{
form.Add(key,Request.Form[key]);
}
output["form"] = form;
}
string data = new StreamReader(Request.Body).ReadToEnd();
if (!String.IsNullOrEmpty(data))
{
output["data"] = data;
}
return Json(output);
}
public IActionResult Error()

View file

@ -12,6 +12,7 @@ using Microsoft.Extensions.Primitives;
using mvc.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.AspNetCore.Http.Features;
namespace mvc.Controllers
{
@ -36,6 +37,12 @@ namespace mvc.Controllers
Response.StatusCode = statusCode;
}
StringValues responsePhrase;
if ( Request.Query.TryGetValue("responsephrase", out responsePhrase))
{
Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = responsePhrase.FirstOrDefault();
}
StringValues body;
if (Request.Query.TryGetValue("body", out body))
{

View file

@ -2,9 +2,9 @@
ASP.NET Core 2.0 app for testing HTTP and HTTPS Requests.
# Run with `dotnet`
## Run with `dotnet`
```
```bash
dotnet restore
dotnet publish --output bin --configuration Release
cd bin
@ -13,7 +13,7 @@ dotnet WebListener.dll ServerCert.pfx password 8083 8084 8085 8086
The test site can then be accessed via `http://localhost:8083/`, `https://localhost:8084/`, `https://localhost:8085/`, or `https://localhost:8086/`.
The `WebListener.dll` takes 6 arguments:
The `WebListener.dll` takes 6 arguments:
* The path to the Server Certificate
* The Server Certificate Password
@ -22,7 +22,7 @@ The `WebListener.dll` takes 6 arguments:
* The TCP Port to bind on for HTTPS using TLS 1.1
* The TCP Port to bind on for HTTPS using TLS 1.0
# Run With WebListener Module
## Run With WebListener Module
```powershell
Import-Module .\build.psm1
@ -30,13 +30,13 @@ Publish-PSTestTools
$Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084 -Tls11Port 8085 -TlsPort = 8086
```
# Tests
## Tests
## / or /Home/
### / or /Home/
Returns a static HTML page containing links and descriptions of the available tests in WebListener. This can be used as a default or general test where no specific test functionality or return data is required.
## /Auth/Basic/
### /Auth/Basic/
Provides a mock Basic authentication challenge. If a basic authorization header is sent, then the same results as /Get/ are returned.
@ -51,7 +51,7 @@ Invoke-RestMethod -Uri $uri -Credential $credential -SkipCertificateCheck
"headers":{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Authorization": "Basic dGVzdHVzZXI6dGVzdHBhc3N3b3Jk",
"Authorization": "Basic dGVzdHVzZXI6dGVzdHBhc3N3b3Jk",
"Host": "localhost:8084"
},
"origin": "127.0.0.1",
@ -60,7 +60,7 @@ Invoke-RestMethod -Uri $uri -Credential $credential -SkipCertificateCheck
}
```
## /Auth/Negotiate/
### /Auth/Negotiate/
Provides a mock Negotiate authentication challenge. If a basic authorization header is sent, then the same results as /Get/ are returned.
@ -74,7 +74,7 @@ Invoke-RestMethod -Uri $uri -UseDefaultCredential -SkipCertificateCheck
"headers":{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Authorization": "Negotiate jjaguasgtisi7tiqkagasjjajvs",
"Authorization": "Negotiate jjaguasgtisi7tiqkagasjjajvs",
"Host": "localhost:8084"
},
"origin": "127.0.0.1",
@ -83,7 +83,7 @@ Invoke-RestMethod -Uri $uri -UseDefaultCredential -SkipCertificateCheck
}
```
## /Auth/NTLM/
### /Auth/NTLM/
Provides a mock NTLM authentication challenge. If a basic authorization header is sent, then the same results as /Get/ are returned.
@ -97,7 +97,7 @@ Invoke-RestMethod -Uri $uri -UseDefaultCredential -SkipCertificateCheck
"headers":{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Authorization": "NTLM jjaguasgtisi7tiqkagasjjajvs",
"Authorization": "NTLM jjaguasgtisi7tiqkagasjjajvs",
"Host": "localhost:8084"
},
"origin": "127.0.0.1",
@ -106,17 +106,18 @@ Invoke-RestMethod -Uri $uri -UseDefaultCredential -SkipCertificateCheck
}
```
## /Cert/
### /Cert/
Returns a JSON object containing the details of the Client Certificate if one is provided in the request.
```powershell
$certificate = Get-WebListenerClientCertificate
$uri = Get-WebListenerUrl -Test 'Cert' -Https
$uri = Get-WebListenerUrl -Test 'Cert' -Https
Invoke-RestMethod -Uri $uri -Certificate $certificate
```
Response when certificate is provided in request:
```json
{
"Status": "OK",
@ -131,13 +132,15 @@ Response when certificate is provided in request:
```
Response when certificate is not provided in request:
```json
{
"Status": "FAILED"
}
```
## /Compression/Deflate/
### /Compression/Deflate/
Returns the same results as the Get test with deflate compression.
```powershell
@ -157,7 +160,8 @@ Invoke-RestMethod -Uri $uri
}
```
## /Compression/Gzip/
### /Compression/Gzip/
Returns the same results as the Get test with gzip compression.
```powershell
@ -177,7 +181,7 @@ Invoke-RestMethod -Uri $uri
}
```
## /Delay/
### /Delay/
Returns the same results as the Get test. If a number is supplied, the server will wait that many seconds before returning a response. This can be used to test timeouts.
@ -191,7 +195,6 @@ After 5 Seconds:
```json
{
"args": {
},
"origin": "127.0.0.1",
"headers": {
@ -202,7 +205,33 @@ After 5 Seconds:
}
```
## /Encoding/Utf8/
### /Delete/
Returns the same results as the Get test. Will only accept the `DELETE` request method.
```powershell
$uri = Get-WebListenerUrl -Test 'Delete'
$Body = @{id = 12345} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $uri -Body $body -Method 'Delete'
```
```json
{
"method": "DELETE",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Host": "localhost:8083",
"Content-Length": "12"
},
"origin": "127.0.0.1",
"url": "http://localhost:8083/Delete",
"args": {},
"data": "{\"id\":12345}"
}
```
### /Encoding/Utf8/
Returns page containing UTF-8 data.
@ -211,8 +240,7 @@ $uri = Get-WebListenerUrl -Test 'Encoding' -TestValue 'Utf8'
Invoke-RestMethod -Uri $uri
```
## /Get/
### /Get/
Returns a JSON object containing the Request URL, Request Headers, GET Query Fields and Values, and Origin IP. This emulates the functionality of [HttpBin's get test](https://httpbin.org/get).
@ -223,25 +251,28 @@ Invoke-RestMethod -Uri $uri -Body @{TestField = 'TestValue'}
```json
{
"url": "http://localhost:8083/Get/?TestField=TestValue",
"origin": "127.0.0.1",
"url": "http://localhost:8083/Get?TestField=TestValue",
"method": "GET",
"args": {
"TestField": "TestValue"
},
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"User-Agent": "Mozilla/5.0 (Windows NT; Microsoft Windows 10.0.15063 ; en-US) WindowsPowerShell/6.0.0",
"Host": "localhost:8083"
},
"origin": "127.0.0.1"
}
}
```
## /Multipart/
### /Multipart/
#### GET
### GET
Provides an HTML form for `multipart/form-data` submission.
### POST
#### POST
Accepts a `multipart/form-data` submission and returns a JSON object containing information about the submission including the items and files submitted.
```powershell
@ -285,7 +316,115 @@ Invoke-RestMethod -Uri $uri -Body $multipartData -Method 'POST'
}
```
## /Redirect/
### /Patch/
Returns the same results as the Get test. Will only accept the `PATCH` request method.
```powershell
$uri = Get-WebListenerUrl -Test 'Patch'
$Body = @{id = 12345} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $uri -Body $body -Method 'Patch'
```
```json
{
"method": "PATCH",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Host": "localhost:8083",
"Content-Length": "12"
},
"origin": "127.0.0.1",
"url": "http://localhost:8083/Patch",
"args": {},
"data": "{\"id\":12345}"
}
```
### /Post/
Returns the same results as the Get test. Will only accept the `POST` request method. If the POST request is sent with a forms based content type the body will be interpreted as a form instead of raw data.
```powershell
$uri = Get-WebListenerUrl -Test 'Post'
$Body = @{id = 12345}
Invoke-RestMethod -Uri $uri -Body $body -Method 'Post'
```
```json
{
"method": "POST",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Host": "localhost:8083",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "8"
},
"form": {
"id": [
"12345"
]
},
"origin": "127.0.0.1",
"url": "http://localhost:8083/Post",
"args": {}
}
```
Otherwise, the body will be interpreted as raw data.
```powershell
$uri = Get-WebListenerUrl -Test 'Post'
$Body = @{id = 12345} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $uri -Body $body -Method 'Post' -ContentType 'application/json'
```
```json
{
"method": "POST",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Host": "localhost:8083",
"Content-Type": "application/json",
"Content-Length": "12"
},
"origin": "127.0.0.1",
"url": "http://localhost:8083/Post",
"args": {},
"data": "{\"id\":12345}"
}
```
### /Put/
Returns the same results as the Get test. Will only accept the `PUT` request method.
```powershell
$uri = Get-WebListenerUrl -Test 'Put'
$Body = @{id = 12345} | ConvertTo-Json -Compress
Invoke-RestMethod -Uri $uri -Body $body -Method 'Put'
```
```json
{
"method": "PUT",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.15063; en-US) PowerShell/6.0.0",
"Connection": "Keep-Alive",
"Host": "localhost:8083",
"Content-Length": "12"
},
"origin": "127.0.0.1",
"url": "http://localhost:8083/Put",
"args": {},
"data": "{\"id\":12345}"
}
```
### /Redirect/
Will 302 redirect to `/Get/`. If a number is supplied, redirect will occur that many times. Can be used to test maximum redirects.
@ -320,6 +459,7 @@ Location: /Redirect/1
```
Request 2:
```none
GET http://localhost:8083/Redirect/1 HTTP/1.1
Connection: Keep-Alive
@ -328,6 +468,7 @@ Host: localhost:8083
```
Response 2:
```none
HTTP/1.1 302 Found
Date: Fri, 15 Sep 2017 10:46:41 GMT
@ -342,7 +483,7 @@ Location: /Get/
<p>You should be redirected automatically to target URL: <a href="/Get/">/Get/</a>. If not click the link.
```
## /Response/
### /Response/
Will return a response crafted from the query string. The following four fields are supported:
@ -350,10 +491,12 @@ Will return a response crafted from the query string. The following four fields
* `statuscode` - the HTTP Status Code to return
* `contenttype` - The `Content-Type` response header
* `headers` - a JSON string containing response headers. `Content-Type` will be ignored in `headers`. Use `contenttype` instead.
* `responsephrase` - the HTTP response phrase to return
```powershell
$Query = @{
statsucode = 200
responsephrase = 'OK'
contenttype = 'application/json'
body = '{"key1": "value1"}'
headers = @{
@ -377,13 +520,13 @@ Response Body:
{"key1": "value1"}
```
## /ResponseHeaders/
### /ResponseHeaders/
Will return the response headers passed in query string. The response body will be the supplied headers as a JSON object.
```powershell
$uri = Get-WebListenerUrl -Test 'ResponseHeaders' -Query @{'Content-Type' = 'custom'; 'x-header-01' = 'value01'; 'x-header-02' = 'value02'}
Invoke-RestMethod -Uri $uri
Invoke-RestMethod -Uri $uri
```
Response Headers:

View file

@ -4,6 +4,8 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
@ -46,13 +48,31 @@ namespace mvc
routes.MapRoute(
name: "redirect",
template: "Redirect/{count?}",
defaults: new {controller = "Redirect", action = "Index"}
);
defaults: new {controller = "Redirect", action = "Index"});
routes.MapRoute(
name: "delay",
template: "Delay/{seconds?}",
defaults: new {controller = "Delay", action = "Index"}
);
defaults: new {controller = "Delay", action = "Index"});
routes.MapRoute(
name: "post",
template: "Post",
defaults: new {controller = "Get", action = "Index"},
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("POST") }));
routes.MapRoute(
name: "put",
template: "Put",
defaults: new {controller = "Get", action = "Index"},
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("PUT") }));
routes.MapRoute(
name: "patch",
template: "Patch",
defaults: new {controller = "Get", action = "Index"},
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("PATCH") }));
routes.MapRoute(
name: "delete",
template: "Delete",
defaults: new {controller = "Get", action = "Index"},
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint("DELETE") }));
});
}
}

View file

@ -8,9 +8,13 @@
<li><a href="/Compression/Deflate/">/Compression/Deflate/</a> - Returns deflate compressed response</li>
<li><a href="/Compression/GZip/">/Compression/Gzip/</a> - Returns gzip compressed response</li>
<li><a href="/Delay/">/Delay/{seconds}</a> - Delays response for <i>seconds</i> seconds.</li>
<li>/Delete/ - returns data from a DELETE request</li>
<li><a href="/Encoding/Utf8/">/Encoding/Utf8/</a> - Returns page containing UTF-8 data.</li>
<li><a href="/Get/">/Get/</a> - Emulates functionality of https://httpbin.org/get by returning GET headers, Arguments, and Request URL</li>
<li><a href="/Multipart/">/Multipart/</a> - Multipart/form-data submission testing</li>
<li>/Patch/ - returns data from a PATCH request</li>
<li>/Post/ - returns data from a POST request</li>
<li>/Put/ - returns data from a PUT request</li>
<li><a href="/Redirect/">/Redirect/{count}</a> - 302 redirect <i>count</i> times.</li>
<li><a href="/Response/?statuscode=200&contenttype=application%2Fjson&body=%22Body%20text%22&headers=%7B%22x-header%22%3A%20%22Response%20Header%20Value%22%7D">/Response/?statuscode=&lt;StatusCode&gt;&amp;body=&lt;ResponseBody&gt;&amp;contenttype=&lt;ResponseContentType&gt;&amp;headers=&lt;JsonHeadersObject&gt;</a> - Returns the given response.</li>
<li><a href="/ResponseHeaders/?key=val">/ResponseHeaders/?key=val</a> - Returns given response headers.</li>