Private/Invoke-Http.ps1
function Invoke-Http { [CmdletBinding()] Param( [Parameter(Mandatory=$true)] [string]$Path, [Parameter(Mandatory=$true)] [Microsoft.PowerShell.Commands.WebRequestMethod]$method, [Parameter(Mandatory=$false)] $params = [System.Web.HttpUtility]::ParseQueryString([String]::Empty), [Parameter(Mandatory=$false)] $contentType='application/json', [Parameter(Mandatory=$false)] $body, [Parameter(Mandatory=$false)] $fileName, [Parameter(Mandatory=$false)] $acceptHeader='application/json', [Parameter(Mandatory=$false)] [switch]$needHeaders=$false ) if ($null -eq $script:PSNexosisVars.ApiKey) { Set-NexosisConfig -SetApiKeyFromEnvironment } $headers = @{} $headers.Add("accept", $acceptHeader) $headers.Add("api-key", "********************************") $headers.Add("User-Agent", $script:UserAgent) $endpoint = "$($script:PSNexosisVars.ApiBaseUrl)/$path" $Request = [System.UriBuilder]$endpoint $Request.Query = $params.ToString() $uri = [string]$Request.Uri.AbsoluteUri Try { if ($fileName -ne $null) { # submit request with file Write-Verbose "Invoke-WebRequest -Uri $uri -Method $method -Headers $($headers.GetEnumerator() | % { "$($_.Name)=$($_.Value)" }) -ContentType $contentType -InFile $fileName" # replace acceptHeader with actual key so we don't print in in VerboseMode $headers["api-key"] = $script:PSNexosisVars.ApiKey $httpResults = Invoke-WebRequest -Uri $uri -Method $method -Headers $headers -ContentType $contentType -InFile $fileName } elseif ($body -ne $null) { # filename null, body is populated, submit body data Write-Verbose "Invoke-WebRequest -Uri $uri -Method $method -Headers $($headers.GetEnumerator() | % { "$($_.Name)=$($_.Value)" }) -Body $body -ContentType $contentType" # replace acceptHeader with actual key so we don't print it in VerboseMode $headers["api-key"] = $script:PSNexosisVars.ApiKey $httpResults = Invoke-WebRequest -Uri $uri -Method $method -Headers $headers -Body $body -ContentType $contentType } else { # no file, no body Write-Verbose "Invoke-WebRequest -Uri $uri -Method $method -Headers $($headers.GetEnumerator() | % { "$($_.Name)=$($_.Value)" }) -ContentType $contentType" # replace acceptHeader with actual key so we don't print in in VerboseMode $headers["api-key"] = $script:PSNexosisVars.ApiKey $httpResults = Invoke-WebRequest -Uri $uri -Method $method -Headers $headers -ContentType $contentType } # Status code in 200's and not an exception if ($httpResults.StatusCode -ge 200 -and $httpResults.StatusCode -le 299) { if (($method -eq [Microsoft.PowerShell.Commands.WebRequestMethod]::Head) -or ($needHeaders -eq $true)) { # If HTTP Head Request, $httpResults.Content won't exist so # return the results so calls can work with headers, etc. # If need headers (Get-NexosisAccountQuotas, etc), return entire HttpRequest object # Callers need to handle checking statuscode and handling Headers and Content # Write raw response body to verbose output Write-Verbose $httpResults $httpResults } elseif ($acceptHeader -eq 'application/json') { # Write raw response body to verbose output Write-Verbose "Raw Body: $($httpResults.Content)" # Return HTTP Content from JSON $httpResults.Content | ConvertFrom-Json } else { # Write raw response body to verbose output Write-Verbose ($httpResults.Content) # Return raw content if expecting CSV like when accept header is 'text/csv' # or any other case, just return raw HTTP body / content $httpResults.Content } } else { # if it's not 200-299 status code and not an exception (400-599), just return the WebRequest object assert($true, "Unexpected condition - Invoke-WebRequest had a status code between 200-299 but did not throw an exception. Nexosis API should not throw 300's.") } } Catch { Write-Verbose "---EXCEPTION---" # Make sure there's a Response object, so we can read in server-side messages if ($_.Exception.Response -ne $null) { $statusCode = $_.Exception.Response.StatusCode.value__ $statusDescription = $_.Exception.Response.StatusDescription Write-Verbose "Status Code: $statusCode" Write-Verbose "Status Description:$statusDescription" Write-Verbose "Method: $($_.Exception.Response.Method)" # If it's an HTTP HEAD request, there's no body to capture the error details from. if ($_.Exception.Response.Method -eq 'HEAD') { $nexosisException = [NexosisClientException]::new($_.Exception.Response.StatusDescription, [int]$_.Exception.Response.StatusCode) throw $nexosisException } else { try { # Read response stream for any error message. $result = $_.Exception.Response.GetResponseStream() $reader = New-Object System.IO.StreamReader($result) $reader.BaseStream.Position = 0 # reset the response stream $reader.DiscardBufferedData() $responseRawError = $reader.ReadToEnd() # Write raw response body to verbose output Write-Verbose "Raw Body: $responseRawError" # Capture JSON Error message from respose stream $responseJsonError = $responseRawError | ConvertFrom-Json # create Nexosis Client Exception $nexosisException = [NexosisClientException]::new($responseJsonError.message, [PSObject]$responseJsonError) } catch { # Content stream was probably not JSON, wrap status description and code to be thrown $nexosisException = [NexosisClientException]::new($statusDescription, $statusCode) } throw $nexosisException } } else { # Unexpected exception - wrap it in a NexosisClientException. Write-Verbose $_.Exception Write-Verbose $_.Exception.message $nexosisException = [NexosisClientException]::new($_.Exception.message, $_.Exception) throw $nexosisException } } } |