Skip to content

Commit

Permalink
Fixing 'InFile parameter of Invoke-WebRequest doesn't work' and addin…
Browse files Browse the repository at this point in the history
…g aliases (iwr for invoke-webrequest and irm for invoke-restmethod) to the web cmdlets. (PowerShell#2848)

* Fixing Invoke-WebRequest InFile parameter

* Adding aliases for Invoke-RestMethod and Invoke-WebRequest

* Adding test cases for Web cmdlets -InFile parameter

* Adding tests for Invoke-WebRequest (iwr) and Invoke-RestMethod (irm) using the cmdlet aliases.

* Remove the extra leading space
  • Loading branch information
Francisco-Gamino authored and daxian-dbw committed Feb 1, 2017
1 parent 1431105 commit 89a5c17
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request)
try
{
// open the input file
using (FileStream fs = new FileStream(InFile, FileMode.Open))
{
SetRequestContent(request, fs);
}
SetRequestContent(request, new FileStream(InFile, FileMode.Open));
}
catch (UnauthorizedAccessException)
{
Expand Down Expand Up @@ -331,55 +328,57 @@ protected override void ProcessRecord()
// Set cmdlet context for write progress
ValidateParameters();
PrepareSession();
HttpClient client = GetHttpClient();
HttpRequestMessage request = GetRequest(Uri);
FillRequestStream(request);

try
using (HttpClient client = GetHttpClient())
using (HttpRequestMessage request = GetRequest(Uri))
{
long requestContentLength = 0;
if (request.Content != null)
requestContentLength = request.Content.Headers.ContentLength.Value;

string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture,
"{0} {1} with {2}-byte payload",
request.Method,
request.RequestUri,
requestContentLength);
WriteVerbose(reqVerboseMsg);

HttpResponseMessage response = GetResponse(client, request);
response.EnsureSuccessStatusCode();

string contentType = ContentHelper.GetContentType(response);
string respVerboseMsg = string.Format(CultureInfo.CurrentCulture,
"received {0}-byte response of content type {1}",
response.Content.Headers.ContentLength,
contentType);
WriteVerbose(respVerboseMsg);
ProcessResponse(response);
UpdateSession(response);

// If we hit our maximum redirection count, generate an error.
// Errors with redirection counts of greater than 0 are handled automatically by .NET, but are
// impossible to detect programmatically when we hit this limit. By handling this ourselves
// (and still writing out the result), users can debug actual HTTP redirect problems.
if (WebSession.MaximumRedirection == 0) // Indicate "HttpClientHandler.AllowAutoRedirect == false"
FillRequestStream(request);
try
{
if (response.StatusCode == HttpStatusCode.Found ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.MovedPermanently)
long requestContentLength = 0;
if (request.Content != null)
requestContentLength = request.Content.Headers.ContentLength.Value;

string reqVerboseMsg = String.Format(CultureInfo.CurrentCulture,
"{0} {1} with {2}-byte payload",
request.Method,
request.RequestUri,
requestContentLength);
WriteVerbose(reqVerboseMsg);

HttpResponseMessage response = GetResponse(client, request);
response.EnsureSuccessStatusCode();

string contentType = ContentHelper.GetContentType(response);
string respVerboseMsg = string.Format(CultureInfo.CurrentCulture,
"received {0}-byte response of content type {1}",
response.Content.Headers.ContentLength,
contentType);
WriteVerbose(respVerboseMsg);
ProcessResponse(response);
UpdateSession(response);

// If we hit our maximum redirection count, generate an error.
// Errors with redirection counts of greater than 0 are handled automatically by .NET, but are
// impossible to detect programmatically when we hit this limit. By handling this ourselves
// (and still writing out the result), users can debug actual HTTP redirect problems.
if (WebSession.MaximumRedirection == 0) // Indicate "HttpClientHandler.AllowAutoRedirect == false"
{
ErrorRecord er = new ErrorRecord(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request);
er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded);
WriteError(er);
if (response.StatusCode == HttpStatusCode.Found ||
response.StatusCode == HttpStatusCode.Moved ||
response.StatusCode == HttpStatusCode.MovedPermanently)
{
ErrorRecord er = new ErrorRecord(new InvalidOperationException(), "MaximumRedirectExceeded", ErrorCategory.InvalidOperation, request);
er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded);
WriteError(er);
}
}
}
}
catch (HttpRequestException ex)
{
ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request);
ThrowTerminatingError(er);
catch (HttpRequestException ex)
{
ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request);
ThrowTerminatingError(er);
}
}
}
catch (CryptographicException ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5108,6 +5108,11 @@ internal static SessionStateAliasEntry[] BuiltInAliases
"Stop-Service", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("sv",
"Set-Variable", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
// Web cmdlets aliases
new SessionStateAliasEntry("irm",
"Invoke-RestMethod", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("iwr",
"Invoke-WebRequest", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
// Porting note: #if !UNIX is used to disable aliases for cmdlets which conflict with Linux / OS X
#if !UNIX
// ac is a native command on OS X
Expand Down Expand Up @@ -5175,10 +5180,6 @@ internal static SessionStateAliasEntry[] BuiltInAliases
"Get-PSSnapIn", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("gwmi",
"Get-WmiObject", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("irm",
"Invoke-RestMethod", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("iwr",
"Invoke-WebRequest", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("iwmi",
"Invoke-WMIMethod", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
new SessionStateAliasEntry("ogv",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,3 +643,127 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
$result.Error | Should BeNullOrEmpty
}
}

Describe "Validate Invoke-WebRequest and Invoke-RestMethod -InFile" -Tags "Feature" {

Context "InFile parameter negative tests" {

$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 http://httpbin.org/post -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'
}
#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 <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 $TestDrive\content.txt"
ScriptBlock = {Invoke-RestMethod -Uri http://httpbin.org/post -Method Post -InFile $TestDrive\content.txt}
ExpectedFullyQualifiedErrorId = 'PathNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand'
}
#endregion
)

It "<Name>" -TestCases $testCases {
param ($scriptblock, $expectedFullyQualifiedErrorId)

try
{
& $scriptblock
throw "No Exception!"
}
catch
{
$_.FullyQualifiedErrorId | should be $ExpectedFullyQualifiedErrorId
}
}
}

Context "InFile parameter positive tests" {

BeforeAll {
$filePath = Join-Path $TestDrive test.txt
New-Item -Path $filePath -Value "hello" -ItemType File -Force
}

It "Invoke-WebRequest -InFile" {
$result = Invoke-WebRequest -InFile $filePath -Uri http://httpbin.org/post -Method Post
$content = $result.Content | ConvertFrom-Json
$content.form | Should Match "hello"
}

It "Invoke-RestMethod -InFile" {
$result = Invoke-RestMethod -InFile $filePath -Uri http://httpbin.org/post -Method Post
$result.form | Should Match "hello"
}
}
}

Describe "Web cmdlets tests using the cmdlet's aliases" -Tags "CI" {

function SearchEngineIsOnline
{
param (
[ValidateNotNullOrEmpty()]
$webAddress
)
$ping = new-object System.Net.NetworkInformation.Ping
$sendPing = $ping.SendPingAsync($webAddress)
return ($sendPing.Result.Status -eq "Success")
}

# Make sure either www.bing.com or www.google.com are online to send a request.
$endPointToUse = $null
foreach ($uri in @("www.bing.com", "www.google.com"))
{
if (SearchEngineIsOnline $uri)
{
$endPointToUse = $uri
break
}
}

# If neither www.bing.com nor www.google.com are online, then skip the tests.
$skipTests = ($endPointToUse -eq $null)
$finalUri = $endPointToUse + "?q=how+many+feet+in+a+mile"

It "Execute Invoke-WebRequest --> 'iwr -URI $finalUri'" -Skip:$skipTests {
$result = iwr -URI $finalUri -TimeoutSec 5
$result.StatusCode | Should Be "200"
$result.Links | Should Not Be $null
}

It "Execute Invoke-RestMethod --> 'irm -URI $finalUri'" -Skip:$skipTests {
$result = irm -URI $finalUri -TimeoutSec 5
foreach ($word in @("200", "how", "many", "feet", "in", "mile"))
{
$result | Should Match $word
}
}
}

0 comments on commit 89a5c17

Please sign in to comment.