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
528 changes: 182 additions & 346 deletions test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test/tools/Modules/WebListener/WebListener.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function Get-WebListenerUrl {
'Home',
'Multipart',
'Redirect',
'Response',
'ResponseHeaders',
'/'
)]
Expand Down
6 changes: 6 additions & 0 deletions test/tools/WebListener/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@ namespace mvc.Controllers
internal static class Constants
{
public const string HeaderSeparator = ", ";
public const string ApplicationJson = "application/json";
}

internal static class StatusCodes
{
public const Int32 ApplicationError = 500;
}
}
103 changes: 103 additions & 0 deletions test/tools/WebListener/Controllers/ResponseController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Primitives;
using mvc.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace mvc.Controllers
{
public class ResponseController : Controller
{
public String Index()
{
string output = String.Empty;
string contentType = Constants.ApplicationJson;

StringValues contentTypes;
if (Request.Query.TryGetValue("contenttype", out contentTypes))
{
contentType = contentTypes.FirstOrDefault();
}

StringValues statusCodes;
Int32 statusCode;
if (Request.Query.TryGetValue("statuscode", out statusCodes) &&
Int32.TryParse(statusCodes.FirstOrDefault(), out statusCode))
{
Response.StatusCode = statusCode;
}

StringValues body;
if (Request.Query.TryGetValue("body", out body))
{
output = body.FirstOrDefault();
}

StringValues headers;
if (Request.Query.TryGetValue("headers", out headers))
{
try
{
Response.Headers.Clear();
JObject jobject = JObject.Parse(headers.FirstOrDefault());
foreach (JProperty property in (JToken)jobject)
{
// Only set Content-Type through contenttype field.
if (String.Equals(property.Name, "Content-Type", StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
foreach (string entry in GetSingleOrArray<String>(property.Value))
{
Response.Headers.Append(property.Name,entry);
}
}
}
catch (Exception ex)
{
output = JsonConvert.SerializeObject(ex);
Response.StatusCode = StatusCodes.ApplicationError;
contentType = Constants.ApplicationJson;
}
}

// Content-Type must be applied right before it is sent to the client or MVC will overwrite.
Response.OnStarting(state =>
{
var httpContext = (HttpContext) state;
httpContext.Response.ContentType = contentType;
return Task.FromResult(0);
}, HttpContext);

Response.ContentLength = Encoding.UTF8.GetBytes(output).Length;

return output;
}

public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

private List<T> GetSingleOrArray<T>(JToken token)
{
if (token.HasValues)
{
return token.ToObject<List<T>>();
}
else
{
return new List<T> { token.ToObject<T>() };
}
}
}
}
35 changes: 35 additions & 0 deletions test/tools/WebListener/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,41 @@ Location: /Get/
<p>You should be redirected automatically to target URL: <a href="/Get/">/Get/</a>. If not click the link.
```

## /Response/

Will return a response crafted from the query string. The following four fields are supported:

* `body` - a string containing the response body
* `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.

```powershell
$Query = @{
statsucode = 200
contenttype = 'application/json'
body = '{"key1": "value1"}'
headers = @{
"X-Header" = "Response header value"
} | ConvertTo-Json
}
$Uri = Get-WebListenerUrl -Test 'Response' -Query $Query
Invoke-RestMethod -Uri $uri
```

Response headers:

```none
Content-Type: application/json
X-Header: Response header value
```

Response Body:

```json
{"key1": "value1"}
```

## /ResponseHeaders/

Will return the response headers passed in query string. The response body will be the supplied headers as a JSON object.
Expand Down
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 @@ -12,5 +12,6 @@
<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><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>
</ul>