Skip to content

Commit 15a6c57

Browse files
markekrausTravisEz13
authored andcommitted
Replace httpbin.org/gzip Tests with WebListener and Re-Enable Deflate Tests (PowerShell#4948)
* Add Gzip and Deflate Support to WebListener * [Feature] Run Feature tests * [Feature] Address PR Feedback * [Feature] Re-Run CI * [feature] Update WebListener Index page * [Feature] Run Feature tests * [Feature] Re-run CI
1 parent 74df9c2 commit 15a6c57

File tree

7 files changed

+170
-41
lines changed

7 files changed

+170
-41
lines changed

test/powershell/Modules/Microsoft.PowerShell.Utility/WebCmdlets.Tests.ps1

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -592,29 +592,22 @@ Describe "Invoke-WebRequest tests" -Tags "Feature" {
592592
# gzip Returns gzip-encoded data.
593593
# deflate Returns deflate-encoded data.
594594
# $dataEncodings = @("Chunked", "Compress", "Deflate", "GZip", "Identity")
595-
# Note: These are the supported options, but we do not have a web service to test them all.
596-
# $dataEncodings = @("gzip", "deflate") --> Currently there is a bug for deflate encoding. Please see '7976639:Invoke-WebRequest does not support -TransferEncoding deflate' for more info.
597-
$dataEncodings = @("gzip")
598-
foreach ($data in $dataEncodings)
599-
{
600-
It "Invoke-WebRequest supports request that returns $data-encoded data." {
601-
602-
$command = "Invoke-WebRequest -Uri http://httpbin.org/$data -TimeoutSec 5"
595+
# Note: These are the supported options, but we do not have a web service to test them all.
596+
It "Invoke-WebRequest supports request that returns <DataEncoding>-encoded data." -TestCases @(
597+
@{ DataEncoding = "gzip"}
598+
@{ DataEncoding = "deflate"}
599+
) {
600+
param($dataEncoding)
601+
$uri = Get-WebListenerUrl -Test 'Compression' -TestValue $dataEncoding
602+
$command = "Invoke-WebRequest -Uri '$uri'"
603603

604-
$result = ExecuteWebCommand -command $command
605-
ValidateResponse -response $result
604+
$result = ExecuteWebCommand -command $command
605+
ValidateResponse -response $result
606606

607-
# Validate response content
608-
$jsonContent = $result.Output.Content | ConvertFrom-Json
609-
if ($data -eq "gzip")
610-
{
611-
$jsonContent.gzipped | Should Match $true
612-
}
613-
else
614-
{
615-
$jsonContent.deflated | Should Match $true
616-
}
617-
}
607+
# Validate response content
608+
$result.Output.Headers.'Content-Encoding'[0] | Should BeExactly $dataEncoding
609+
$jsonContent = $result.Output.Content | ConvertFrom-Json
610+
$jsonContent.Headers.Host | Should BeExactly $uri.Authority
618611
}
619612

620613
# Perform the following operation for Invoke-WebRequest using the following content types: "text/plain", "application/xml", "application/xml"
@@ -1433,27 +1426,18 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
14331426
# gzip Returns gzip-encoded data.
14341427
# deflate Returns deflate-encoded data.
14351428
# $dataEncodings = @("Chunked", "Compress", "Deflate", "GZip", "Identity")
1436-
# Note: These are the supported options, but we do not have a web service to test them all.
1437-
# $dataEncodings = @("gzip", "deflate") --> Currently there is a bug for deflate encoding. Please see '7976639:Invoke-RestMethod does not support -TransferEncoding deflate' for more info.
1438-
$dataEncodings = @("gzip")
1439-
foreach ($data in $dataEncodings)
1440-
{
1441-
It "Invoke-RestMethod supports request that returns $data-encoded data." {
1442-
1443-
$command = "Invoke-RestMethod -Uri http://httpbin.org/$data -TimeoutSec 5"
1444-
1445-
$result = ExecuteWebCommand -command $command
1429+
# Note: These are the supported options, but we do not have a web service to test them all.
1430+
It "Invoke-RestMethod supports request that returns <DataEncoding>-encoded data." -TestCases @(
1431+
@{ DataEncoding = "gzip"}
1432+
@{ DataEncoding = "deflate"}
1433+
) {
1434+
param($dataEncoding)
1435+
$uri = Get-WebListenerUrl -Test 'Compression' -TestValue $dataEncoding
1436+
$result = Invoke-RestMethod -Uri $uri -ResponseHeadersVariable 'headers'
14461437

1447-
# Validate response
1448-
if ($data -eq "gzip")
1449-
{
1450-
$result.Output.gzipped | Should Match $true
1451-
}
1452-
else
1453-
{
1454-
$result.Output.deflated | Should Match $true
1455-
}
1456-
}
1438+
# Validate response content
1439+
$headers.'Content-Encoding'[0] | Should BeExactly $dataEncoding
1440+
$result.Headers.Host | Should BeExactly $uri.Authority
14571441
}
14581442

14591443
# Perform the following operation for Invoke-RestMethod using the following content types: "text/plain", "application/xml", "application/xml"

test/tools/Modules/WebListener/WebListener.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ function Get-WebListenerUrl {
114114
[switch]$Https,
115115
[ValidateSet(
116116
'Cert',
117+
'Compression',
117118
'Delay',
118119
'Encoding',
119120
'Get',
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Mvc;
7+
using mvc.Models;
8+
9+
namespace mvc.Controllers
10+
{
11+
public class CompressionController : Controller
12+
{
13+
public ActionResult Index()
14+
{
15+
string url = "/Compression/Gzip";
16+
ViewData["Url"] = url;
17+
Response.Redirect(url, false);
18+
return View("~/Views/Redirect/Index.cshtml");
19+
}
20+
21+
[GzipFilter]
22+
public JsonResult Gzip()
23+
{
24+
var getController = new GetController();
25+
getController.ControllerContext = this.ControllerContext;
26+
return getController.Index();
27+
}
28+
29+
[DeflateFilter]
30+
public JsonResult Deflate()
31+
{
32+
var getController = new GetController();
33+
getController.ControllerContext = this.ControllerContext;
34+
return getController.Index();
35+
}
36+
37+
public IActionResult Error()
38+
{
39+
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
40+
}
41+
}
42+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.IO;
3+
using System.IO.Compression;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc.Filters;
6+
7+
namespace mvc.Controllers
8+
{
9+
internal sealed class DeflateFilter : ResultFilterAttribute
10+
{
11+
public override async Task OnResultExecutionAsync( ResultExecutingContext context, ResultExecutionDelegate next)
12+
{
13+
var httpContext = context.HttpContext;
14+
using (var memoryStream = new MemoryStream())
15+
{
16+
var responseStream = httpContext.Response.Body;
17+
httpContext.Response.Body = memoryStream;
18+
19+
await next();
20+
21+
using (var compressedStream = new DeflateStream(responseStream, CompressionLevel.Fastest))
22+
{
23+
httpContext.Response.Headers.Add("Content-Encoding", new [] { "deflate" });
24+
memoryStream.Seek(0, SeekOrigin.Begin);
25+
await memoryStream.CopyToAsync(compressedStream);
26+
}
27+
}
28+
}
29+
}
30+
}

test/tools/WebListener/GzipFilter.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.IO;
3+
using System.IO.Compression;
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc.Filters;
6+
7+
namespace mvc.Controllers
8+
{
9+
internal sealed class GzipFilter : ResultFilterAttribute
10+
{
11+
public override async Task OnResultExecutionAsync( ResultExecutingContext context, ResultExecutionDelegate next)
12+
{
13+
var httpContext = context.HttpContext;
14+
using (var memoryStream = new MemoryStream())
15+
{
16+
var responseStream = httpContext.Response.Body;
17+
httpContext.Response.Body = memoryStream;
18+
19+
await next();
20+
21+
using (var compressedStream = new GZipStream(responseStream, CompressionLevel.Fastest))
22+
{
23+
httpContext.Response.Headers.Add("Content-Encoding", new [] { "gzip" });
24+
memoryStream.Seek(0, SeekOrigin.Begin);
25+
await memoryStream.CopyToAsync(compressedStream);
26+
}
27+
}
28+
}
29+
}
30+
}

test/tools/WebListener/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,46 @@ Response when certificate is not provided in request:
5959
}
6060
```
6161

62+
## /Compression/Deflate/
63+
Returns the same results as the Get test with deflate compression.
64+
65+
```powershell
66+
$uri = Get-WebListenerUrl -Test 'Compression' -TestValue 'Deflate'
67+
Invoke-RestMethod -Uri $uri -Headers $headers
68+
```
69+
70+
```json
71+
{
72+
"args": {},
73+
"origin": "127.0.0.1",
74+
"headers": {
75+
"User-Agent": "Mozilla/5.0 (Windows NT; Microsoft Windows 10.0.15063 ; en-US) PowerShell/6.0.0",
76+
"Host": "localhost:8083"
77+
},
78+
"url": "http://localhost:8083/Compression/Deflate"
79+
}
80+
```
81+
82+
## /Compression/Gzip/
83+
Returns the same results as the Get test with gzip compression.
84+
85+
```powershell
86+
$uri = Get-WebListenerUrl -Test 'Compression' -TestValue 'Gzip'
87+
Invoke-RestMethod -Uri $uri -Headers $headers
88+
```
89+
90+
```json
91+
{
92+
"args": {},
93+
"origin": "127.0.0.1",
94+
"headers": {
95+
"User-Agent": "Mozilla/5.0 (Windows NT; Microsoft Windows 10.0.15063 ; en-US) PowerShell/6.0.0",
96+
"Host": "localhost:8083"
97+
},
98+
"url": "http://localhost:8083/Compression/Gzip"
99+
}
100+
```
101+
62102
## /Delay/
63103

64104
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.

test/tools/WebListener/Views/Home/Index.cshtml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<ul>
33
<li><a href="/">/</a> - This page</li>
44
<li><a href="/Cert/">/Cert/</a> - Client Certificate Details</li>
5+
<li><a href="/Compression/Deflate/">/Compression/Deflate/</a> - Returns deflate compressed response</li>
6+
<li><a href="/Compression/GZip/">/Compression/Gzip/</a> - Returns gzip compressed response</li>
57
<li><a href="/Delay/">/Delay/{seconds}</a> - Delays response for <i>seconds</i> seconds.</li>
68
<li><a href="/Encoding/Utf8/">/Encoding/Utf8/</a> - Returns page containing UTF-8 data.</li>
79
<li><a href="/Get/">/Get/</a> - Emulates functionality of https://httpbin.org/get by returning GET headers, Arguments, and Request URL</li>

0 commit comments

Comments
 (0)