Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .spelling
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ hashtable
hashtables
homebrew
hotfix
HttpBin's
init
Invoke-RestMethod
Invoke-WebRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function ExecuteRequestWithOutFile
[string]
$cmdletName,
[string]
$uri = "http://httpbin.org/get"
$uri = (Get-WebListenerUrl -Test 'Get')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove parentheses.
We use this many times - can we move the line to BeforeAll?

It seems the time has come to add ValidateSet() to Get-WebListenerUrl parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm mistaken, the Parens are required when assign a default value with a statement in a Param block. At your suggestion I tried removing them but I get all kinds of errors.

As for moving this to the BeforeAll block, I don't think that makes sense in this context since this is part of the ExecuteRequestWithOutFile function.

For the more general concern, we could create a variable, but, as we move the other tests over you will see that it will get less possible to do so in the BeforeAll Block without losing meaning in the It blocks (in the case where there will be a query string required as well). I would prefer we keep the URL generation to each It block for consistency.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry - My thoughts was about many Get-WebListenerUrl -Test 'Get' in the file - I see only 10 times so I think we can keep it as is.

)

$result = [PSObject]@{Output = $null; Error = $null}
Expand Down Expand Up @@ -82,7 +82,7 @@ function ExecuteRequestWithHeaders
[string]
$cmdletName,
[string]
$uri = "http://httpbin.org/get"
$uri = (Get-WebListenerUrl -Test 'Get')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove parentheses.

Copy link
Contributor Author

@markekraus markekraus Sep 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same parse issue when trying to remove.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closed.

)

$result = [PSObject]@{Output = $null; Error = $null}
Expand Down Expand Up @@ -442,13 +442,13 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
It "Validate Invoke-WebRequest -DisableKeepAlive" {

# Operation options
$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$command = "Invoke-WebRequest -Uri $uri -TimeoutSec 5 -DisableKeepAlive"

$result = ExecuteWebCommand -command $command
ValidateResponse -response $result

$result.Output.Headers["Connection"] | Should Be "Close"
$result.Output.Headers.Connection | Should Be "Close"
}

It "Validate Invoke-WebRequest -MaximumRedirection" {
Expand Down Expand Up @@ -641,10 +641,10 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {

It "Validate Invoke-WebRequest -Headers --> Set KeepAlive to false via headers" {

$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$result = ExecuteRequestWithHeaders -cmdletName Invoke-WebRequest -uri $uri
ValidateResponse -response $result
$result.Output.Headers["Connection"] | Should Be "Close"
$result.Output.Headers.Connection | Should Be "Close"
}

# Validate all available user agents for Invoke-WebRequest
Expand All @@ -658,7 +658,7 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
foreach ($agentName in $agents.Keys)
{
$expectedAgent = $agents[$agentName]
$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$userAgent = "[Microsoft.PowerShell.Commands.PSUserAgent]::$agentName"
$command = "Invoke-WebRequest -Uri $uri -UserAgent ($userAgent) -TimeoutSec 5"

Expand All @@ -669,17 +669,17 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {

# Validate response content
$jsonContent = $result.Output.Content | ConvertFrom-Json
$jsonContent.headers.Host | Should Match "httpbin.org"
$jsonContent.headers.Host | Should Be $uri.Authority
$jsonContent.headers.'User-Agent' | Should Match $expectedAgent
}
}

It "Validate Invoke-WebRequest -OutFile" {

$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$result = ExecuteRequestWithOutFile -cmdletName "Invoke-WebRequest" -uri $uri
$jsonContent = $result.Output | ConvertFrom-Json
$jsonContent.headers.Host | Should Match "httpbin.org"
$jsonContent.headers.Host | Should Be $uri.Authority
$jsonContent.headers.'User-Agent' | Should Match "WindowsPowerShell"
}

Expand Down Expand Up @@ -715,7 +715,8 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {

It "Validate Invoke-WebRequest body is converted to query params for CustomMethod GET" {

$command = "Invoke-WebRequest -Uri 'http://httpbin.org/get' -CustomMethod GET -Body @{'testparam'='testvalue'}"
$uri = Get-WebListenerUrl -Test 'Get'
$command = "Invoke-WebRequest -Uri '$uri' -CustomMethod GET -Body @{'testparam'='testvalue'}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo '$uri' -> $uri

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a big fan of unencapsulated strings in evaluated commands. the command would become

Invoke-WebRequest -Uri http://localhost:8083/Get -CustomMethod GET -Body @{'testparam'='testvalue'}

Which is improper IMO. Does this have to be done? I feel like this change was actually an improvement and I made it everywhere purposefully.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Binding is not preprocessor, we don't parse the variable value, so we shouldn't quote variables. Uri get right string.
My thoughts was that we should use the file pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this instance the $Command string is later evaluated by Invoke-Expression. $uri is expanded before that evaluation. In instances where the url may contain a $, it would be expanded first during the $command assignment and then when the Invoke-Expression is run on $command the $ in the url would attempt to be expanded again.

# $Field1 is a literal field name, not a variable
$uri = 'http://localhost:8083/Get?$Field1=Value1'
$Command = "Write-Output $uri"
Invoke-Expression $Command

Result:

http://localhost:8083/Get?=Value1

vs:

$uri = 'http://localhost:8083/Get?$Field1=Value1'
$Command = "Write-Output '$uri'"
Invoke-Expression $Command

Result:

http://localhost:8083/Get?$Field1=Value1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry again - I lost the context.
Closed.

$result = ExecuteWebCommand -command $command
($result.Output.Content | ConvertFrom-Json).args.testparam | Should Be "testvalue"
}
Expand Down Expand Up @@ -1262,16 +1263,15 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
It "Validate Invoke-RestMethod -DisableKeepAlive" {

# Operation options
$command = "Invoke-RestMethod -Uri 'http://httpbin.org/get' -TimeoutSec 5 -DisableKeepAlive"
$uri = Get-WebListenerUrl -Test 'Get'
$command = "Invoke-RestMethod -Uri '$uri' -TimeoutSec 5 -DisableKeepAlive"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo '$uri' -> $uri

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closed.


$result = ExecuteWebCommand -command $command

# Validate response
$result.Output.headers.Host | Should Match "httpbin.org"
$result.Output.headers.Host | Should Be $uri.Authority
$result.Output.headers.'User-Agent' | Should Match "WindowsPowerShell"

# Unfortunately, the connection information is not display in the output of Invoke-RestMethod
#$result.Output.Headers["Connection"] | Should Be "Close"
$result.Output.Headers.Connection | Should Be "Close"
}

It "Validate Invoke-RestMethod -MaximumRedirection" {
Expand Down Expand Up @@ -1445,15 +1445,13 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {

It "Validate Invoke-RestMethod -Headers --> Set KeepAlive to false via headers" {

$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$result = ExecuteRequestWithHeaders -cmdletName Invoke-RestMethod -uri $uri

# Validate response
$result.Output.url | Should Match $uri
$result.Output.headers.'User-Agent' | Should Match "WindowsPowerShell"

# Unfortunately, the connection information is not display in the output of Invoke-RestMethod
#$result.Output.Headers["Connection"] | Should Be "Close"
$result.Output.Headers.Connection | Should Be "Close"
}

# Validate all available user agents for Invoke-RestMethod
Expand All @@ -1467,7 +1465,7 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
foreach ($agentName in $agents.Keys)
{
$expectedAgent = $agents[$agentName]
$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$userAgent = "[Microsoft.PowerShell.Commands.PSUserAgent]::$agentName"
$command = "Invoke-RestMethod -Uri $uri -UserAgent ($userAgent) -TimeoutSec 5"

Expand All @@ -1476,17 +1474,17 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
$result = ExecuteWebCommand -command $command

# Validate response
$result.Output.headers.Host | Should Match "httpbin.org"
$result.Output.headers.Host | Should Be $uri.Authority
$result.Output.headers.'User-Agent' | Should Match $expectedAgent
}
}

It "Validate Invoke-RestMethod -OutFile" {

$uri = "http://httpbin.org/get"
$uri = Get-WebListenerUrl -Test 'Get'
$result = ExecuteRequestWithOutFile -cmdletName "Invoke-RestMethod" -uri $uri
$jsonContent = $result.Output | ConvertFrom-Json
$jsonContent.headers.Host | Should Match "httpbin.org"
$jsonContent.headers.Host | Should Be $uri.Authority
$jsonContent.headers.'User-Agent' | Should Match "WindowsPowerShell"
}

Expand Down Expand Up @@ -1521,7 +1519,8 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {

It "Validate Invoke-RestMethod body is converted to query params for CustomMethod GET" {

$command = "Invoke-RestMethod -Uri 'http://httpbin.org/get' -CustomMethod GET -Body @{'testparam'='testvalue'}"
$uri = Get-WebListenerUrl -Test 'Get'
$command = "Invoke-RestMethod -Uri '$uri' -CustomMethod GET -Body @{'testparam'='testvalue'}"
$result = ExecuteWebCommand -command $command
$result.Output.args.testparam | Should Be "testvalue"
}
Expand Down
6 changes: 6 additions & 0 deletions test/tools/Modules/WebListener/WebListener.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ function Get-WebListenerUrl {
[OutputType([Uri])]
param (
[switch]$Https,
[ValidateSet(
'Cert',
'Get',
'Home',
'/'
)]
[String]$Test
)
process {
Expand Down
9 changes: 9 additions & 0 deletions test/tools/WebListener/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

namespace mvc.Controllers
{
internal static class Constants
{
public const string HeaderSeparator = ", ";
}
}
41 changes: 41 additions & 0 deletions test/tools/WebListener/Controllers/GetController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http.Extensions;
using mvc.Models;

namespace mvc.Controllers
{
public class GetController : Controller
{
public JsonResult Index()
{
Hashtable args = new Hashtable();
foreach (var key in Request.Query.Keys)
{
args.Add(key, String.Join(Constants.HeaderSeparator, Request.Query[key]));
}
Hashtable headers = new Hashtable();
foreach (var key in Request.Headers.Keys)
{
headers.Add(key, String.Join(Constants.HeaderSeparator, Request.Headers[key]));
}
Hashtable output = new Hashtable
{
{"args" , args},
{"headers", headers},
{"origin" , Request.HttpContext.Connection.RemoteIpAddress.ToString()},
{"url" , UriHelper.GetDisplayUrl(Request)}
};
return Json(output);
}
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
30 changes: 29 additions & 1 deletion test/tools/WebListener/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WebListener App

ASP.NET Core 2.0 app for testing HTTP and HTTPS Requests. The default page will return a list of available tests.
ASP.NET Core 2.0 app for testing HTTP and HTTPS Requests.

# Run with `dotnet`

Expand Down Expand Up @@ -30,6 +30,10 @@ $Listener = Start-WebListener -HttpPort 8083 -HttpsPort 8084

# Tests

## / 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.

## /Cert/

Returns a JSON object containing the details of the Client Certificate if one is provided in the request.
Expand All @@ -54,3 +58,27 @@ Response when certificate is not provided in request:
"Status": "FAILED"
}
```


## /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).

```powershell
Invoke-WebRequest -Uri 'http://localhost:8083/Get/' -Body @{TestField = 'TestValue'}
```

```json
{
"url": "http://localhost:8083/Get/?TestField=TestValue",
"args": {
"TestField": "TestValue"
},
"headers": {
"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"
}
```
1 change: 1 addition & 0 deletions test/tools/WebListener/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<ul>
<li><a href="/">/</a> - This page</li>
<li><a href="/Cert/">/Cert/</a> - Client Certificate Details</li>
<li><a href="/Get/">/Get/</a> - Emulates functionality of https://httpbin.org/get by returning GET headers, Arguments, and Request URL</li>
</ul>