Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public int MaximumFollowRelLink
[Alias("RHV")]
public string ResponseHeadersVariable { get; set; }

/// <summary>
/// Gets or sets the variable name to use for storing the status code from the response.
/// </summary>
[Parameter]
public string StatusCodeVariable { get; set; }

#endregion Parameters

#region Helper Methods
Expand Down Expand Up @@ -454,6 +460,12 @@ internal override void ProcessResponse(HttpResponseMessage response)
StreamHelper.SaveStreamToFile(responseStream, QualifiedOutFile, this);
}

if (!string.IsNullOrEmpty(StatusCodeVariable))
{
PSVariableIntrinsics vi = SessionState.PSVariable;
vi.Set(StatusCodeVariable, (int)response.StatusCode);
}

if (!string.IsNullOrEmpty(ResponseHeadersVariable))
{
PSVariableIntrinsics vi = SessionState.PSVariable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,12 @@ public virtual string CustomMethod
[Parameter]
public virtual SwitchParameter Resume { get; set; }

/// <summary>
/// Gets or sets whether to skip checking HTTP status for error codes.
/// </summary>
[Parameter]
public virtual SwitchParameter SkipHttpErrorCheck { get; set; }

#endregion

#endregion Virtual Properties
Expand Down Expand Up @@ -690,6 +696,11 @@ internal bool ShouldWriteToPipeline
get { return (!ShouldSaveToOutFile || PassThru); }
}

internal bool ShouldCheckHttpStatus
{
get { return !SkipHttpErrorCheck; }
}

/// <summary>
/// Determines whether writing to a file should Resume and append rather than overwrite.
/// </summary>
Expand Down Expand Up @@ -1242,7 +1253,7 @@ internal virtual void FillRequestStream(HttpRequestMessage request)

// Add the content headers
if (request.Content == null)
{
{
request.Content = new StringContent(string.Empty);
request.Content.Headers.Clear();
}
Expand Down Expand Up @@ -1513,7 +1524,7 @@ protected override void ProcessRecord()
OutFile = null;
}

if (!_isSuccess)
if (ShouldCheckHttpStatus && !_isSuccess)
{
string message = string.Format(CultureInfo.CurrentCulture, WebCmdletStrings.ResponseStatusCodeFailure,
(int)response.StatusCode, response.ReasonPhrase);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ $redirectTests = @(
Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" {
BeforeAll {
$WebListener = Start-WebListener
$NotFoundQuery = @{
statuscode = 404
responsephrase = 'Not Found'
contenttype = 'text/plain'
body = 'oops'
headers = "{}"
}
}

# Validate the output of Invoke-WebRequest
Expand Down Expand Up @@ -780,6 +787,23 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" {
$result.Output.RelationLink["next"] | Should -BeExactly "${baseUri}?maxlinks=3&linknumber=2&type=${type}"
}

It "Verify Invoke-WebRequest supresses terminating errors with -SkipHttpErrorCheck" {
$uri = Get-WebListenerUrl -Test 'Response' -Query $NotFoundQuery
$command = "Invoke-WebRequest -SkipHttpErrorCheck -Uri '$uri'"
$result = ExecuteWebCommand -Command $command
$result.output.StatusCode | Should -Be 404
$result.output.Content | Should -BeExactly "oops"
$result.error | Should -BeNullOrEmpty
}

It "Verify Invoke-WebRequest terminates without -SkipHttpErrorCheck" {
$uri = Get-WebListenerUrl -Test 'Response' -Query $NotFoundQuery
$command = "Invoke-WebRequest -Uri '$uri'"
$result = ExecuteWebCommand -Command $command
$result.output | Should -BeNullOrEmpty
$result.error | Should -Not -BeNullOrEmpty
}

Context "Redirect" {
It "Validates Invoke-WebRequest with -PreserveAuthorizationOnRedirect preserves the authorization header on redirect: <redirectType> <redirectedMethod>" -TestCases $redirectTests {
param($redirectType, $redirectedMethod)
Expand Down Expand Up @@ -1930,6 +1954,14 @@ Describe "Invoke-WebRequest tests" -Tags "Feature", "RequireAdminOnWindows" {
Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" {
BeforeAll {
$WebListener = Start-WebListener

$NotFoundQuery = @{
statuscode = 404
responsephrase = 'Not Found'
contenttype = 'application/json'
body = '{"message": "oops"}'
headers = "{}"
}
}

#User-Agent changes on different platforms, so tests should only be run if on the correct platform
Expand Down Expand Up @@ -2259,6 +2291,64 @@ Describe "Invoke-RestMethod tests" -Tags "Feature", "RequireAdminOnWindows" {
1..3 | ForEach-Object { $result.Output[$_ - 1].linknumber | Should -BeExactly $_ }
}

It "Verify Invoke-RestMethod supresses terminating errors with -SkipHttpErrorCheck" {
$uri = Get-WebListenerUrl -Test 'Response' -Query $NotFoundQuery
$command = "Invoke-RestMethod -SkipHttpErrorCheck -Uri '$uri'"
$result = ExecuteWebCommand -Command $command
$result.output.message | Should -BeExactly "oops"
$result.output.error | Should -BeNullOrEmpty
}

It "Verify Invoke-RestMethod terminates without -SkipHttpErrorCheck" {
$uri = Get-WebListenerUrl -Test 'Response' -Query $NotFoundQuery
$command = "Invoke-RestMethod -Uri '$uri'"
$result = ExecuteWebCommand -Command $command
$result.output | Should -BeNullOrEmpty
$result.error | Should -Not -BeNullOrEmpty
}

It "Verify Invoke-RestMethod assigns 200 status code with -StatusCodeVariable" {
$query = @{
statuscode = 200
responsephrase = 'OK'
contenttype = 'application/json'
body = '{"message": "works"}'
headers = "{}"
}

$uri = Get-WebListenerUrl -Test 'Response' -Query $query
Invoke-RestMethod -StatusCodeVariable code -Uri "$uri"
$code | Should -Be 200
}

It "Verify Invoke-RestMethod assigns 404 status code with -StatusCodeVariable" {
$query = @{
statuscode = 404
responsephrase = 'Not Found'
contenttype = 'application/json'
body = '{"message": "oops"}'
headers = "{}"
}

$uri = Get-WebListenerUrl -Test 'Response' -Query $query
Invoke-RestMethod -SkipHttpErrorCheck -StatusCodeVariable code -Uri "$uri"
$code | Should -Be 404
}

It "Verify Invoke-RestMethod assigns 500 status code with -StatusCodeVariable" {
$query = @{
statuscode = 500
responsephrase = 'Internal Server Error'
contenttype = 'application/json'
body = '{"message": "oops"}'
headers = "{}"
}

$uri = Get-WebListenerUrl -Test 'Response' -Query $query
Invoke-RestMethod -SkipHttpErrorCheck -StatusCodeVariable code -Uri "$uri"
$code | Should -Be 500
}

#region Redirect tests

It "Validates Invoke-RestMethod with -PreserveAuthorizationOnRedirect preserves the authorization header on redirect: <redirectType> <redirectedMethod>" -TestCases $redirectTests {
Expand Down Expand Up @@ -3387,4 +3477,3 @@ Describe "Web cmdlets tests using the cmdlet's aliases" -Tags "CI", "RequireAdmi
$result.Hello | Should -Be "world"
}
}