mirror of
https://github.com/PowerShell/PowerShell.git
synced 2024-11-27 03:46:23 +08:00
Fixing 'InFile parameter of Invoke-WebRequest doesn't work' and adding aliases (iwr for invoke-webrequest and irm for invoke-restmethod) to the web cmdlets. (#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
This commit is contained in:
parent
1431105251
commit
89a5c17d6b
@ -280,10 +280,7 @@ namespace Microsoft.PowerShell.Commands
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// open the input file
|
// open the input file
|
||||||
using (FileStream fs = new FileStream(InFile, FileMode.Open))
|
SetRequestContent(request, new FileStream(InFile, FileMode.Open));
|
||||||
{
|
|
||||||
SetRequestContent(request, fs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
@ -331,55 +328,57 @@ namespace Microsoft.PowerShell.Commands
|
|||||||
// Set cmdlet context for write progress
|
// Set cmdlet context for write progress
|
||||||
ValidateParameters();
|
ValidateParameters();
|
||||||
PrepareSession();
|
PrepareSession();
|
||||||
HttpClient client = GetHttpClient();
|
|
||||||
HttpRequestMessage request = GetRequest(Uri);
|
|
||||||
FillRequestStream(request);
|
|
||||||
|
|
||||||
try
|
using (HttpClient client = GetHttpClient())
|
||||||
|
using (HttpRequestMessage request = GetRequest(Uri))
|
||||||
{
|
{
|
||||||
long requestContentLength = 0;
|
FillRequestStream(request);
|
||||||
if (request.Content != null)
|
try
|
||||||
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"
|
|
||||||
{
|
{
|
||||||
if (response.StatusCode == HttpStatusCode.Found ||
|
long requestContentLength = 0;
|
||||||
response.StatusCode == HttpStatusCode.Moved ||
|
if (request.Content != null)
|
||||||
response.StatusCode == HttpStatusCode.MovedPermanently)
|
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);
|
if (response.StatusCode == HttpStatusCode.Found ||
|
||||||
er.ErrorDetails = new ErrorDetails(WebCmdletStrings.MaximumRedirectionCountExceeded);
|
response.StatusCode == HttpStatusCode.Moved ||
|
||||||
WriteError(er);
|
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)
|
||||||
catch (HttpRequestException ex)
|
{
|
||||||
{
|
ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request);
|
||||||
ErrorRecord er = new ErrorRecord(ex, "WebCmdletWebResponseException", ErrorCategory.InvalidOperation, request);
|
ThrowTerminatingError(er);
|
||||||
ThrowTerminatingError(er);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (CryptographicException ex)
|
catch (CryptographicException ex)
|
||||||
|
@ -5108,6 +5108,11 @@ end
|
|||||||
"Stop-Service", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
"Stop-Service", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||||
new SessionStateAliasEntry("sv",
|
new SessionStateAliasEntry("sv",
|
||||||
"Set-Variable", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
"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
|
// Porting note: #if !UNIX is used to disable aliases for cmdlets which conflict with Linux / OS X
|
||||||
#if !UNIX
|
#if !UNIX
|
||||||
// ac is a native command on OS X
|
// ac is a native command on OS X
|
||||||
@ -5175,10 +5180,6 @@ end
|
|||||||
"Get-PSSnapIn", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
"Get-PSSnapIn", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||||
new SessionStateAliasEntry("gwmi",
|
new SessionStateAliasEntry("gwmi",
|
||||||
"Get-WmiObject", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
"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",
|
new SessionStateAliasEntry("iwmi",
|
||||||
"Invoke-WMIMethod", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
"Invoke-WMIMethod", "", ScopedItemOptions.ReadOnly | ScopedItemOptions.AllScope),
|
||||||
new SessionStateAliasEntry("ogv",
|
new SessionStateAliasEntry("ogv",
|
||||||
|
@ -643,3 +643,127 @@ Describe "Invoke-RestMethod tests" -Tags "Feature" {
|
|||||||
$result.Error | Should BeNullOrEmpty
|
$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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user