Private/Invoke-SystemNetRequest.ps1
|
function Invoke-SystemNetRequest { <# .SYNOPSIS Uses System.Net.WebRequest to make a HTTP request and returns the response. .DESCRIPTION Reads the complete response into memory. Uses the declared response charset, or UTF-8 when none is declared, with byte-order mark detection. Only absolute HTTP and HTTPS URIs are supported. Origin authentication with the current user's credentials is opt-in. Proxy authentication remains independent of origin authentication. Verbose and warning messages omit URI credentials, queries and fragments. The original terminating error is preserved and may contain server details. .PARAMETER TimeoutSec Timeout for obtaining a response, in seconds. Defaults to 100 seconds. .PARAMETER ReadWriteTimeoutSec Timeout for individual synchronous stream reads, in seconds. Defaults to 300 seconds. This is not a limit on the total response download time. .PARAMETER UseDefaultCredentials Enables the current user's credentials for origin server authentication. #> [OutputType([System.String])] [CmdletBinding(SupportsShouldProcess = $false)] param ( [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNullOrEmpty()] [System.String] $Uri, [Parameter(Position = 1)] [System.String] $UserAgent = (Get-EvergreenUserAgent), [Parameter()] [ValidateRange(1, [System.Int32]::MaxValue)] [System.Int32] $MaximumRedirection = 3, [Parameter()] [ValidateRange(1, 2147483)] [System.Int32] $TimeoutSec = 100, [Parameter()] [ValidateRange(1, 2147483)] [System.Int32] $ReadWriteTimeoutSec = 300, [Parameter()] [System.Management.Automation.SwitchParameter] $UseDefaultCredentials ) $webResponse = $null $httpWebRequest = $null $responseStream = $null $streamReader = $null $RequestCompleted = $false $SafeUri = "<invalid URI>" try { $RequestUri = $null if (-not [System.Uri]::TryCreate($Uri, [System.UriKind]::Absolute, [ref]$RequestUri) -or $RequestUri.Scheme -notin @("http", "https")) { throw [System.ArgumentException]::new("Uri must be an absolute HTTP or HTTPS URI.") } $UriBuilder = [System.UriBuilder]::new($RequestUri) $UriBuilder.UserName = "" $UriBuilder.Password = "" $UriBuilder.Query = "" $UriBuilder.Fragment = "" $SafeUri = $UriBuilder.Uri.AbsoluteUri $httpWebRequest = [System.Net.WebRequest]::Create($RequestUri) if (-not [System.String]::IsNullOrEmpty($UserAgent)) { $httpWebRequest.UserAgent = $UserAgent } $httpWebRequest.MaximumAutomaticRedirections = $MaximumRedirection $httpWebRequest.AllowAutoRedirect = $true $httpWebRequest.Timeout = $TimeoutSec * 1000 $httpWebRequest.ReadWriteTimeout = $ReadWriteTimeoutSec * 1000 $httpWebRequest.UseDefaultCredentials = $UseDefaultCredentials.IsPresent if (Test-ProxyEnv) { $ProxyObj = New-Object -TypeName "System.Net.WebProxy" $ProxyObj.Address = $script:EvergreenProxy $ProxyObj.UseDefaultCredentials = $true $httpWebRequest.Proxy = $ProxyObj if (Test-ProxyEnv -Creds) { $ProxyObj.UseDefaultCredentials = $false $ProxyObj.Credentials = $script:EvergreenProxyCreds } } Write-Verbose -Message "$($MyInvocation.MyCommand): Requesting: $SafeUri." $webResponse = $httpWebRequest.GetResponse() $responseStream = $webResponse.GetResponseStream() $Encoding = [System.Text.Encoding]::UTF8 if ($webResponse.ContentType -match '(?i)(?:^|;)\s*charset\s*=') { $Encoding = [System.Text.Encoding]::GetEncoding($webResponse.CharacterSet.Trim([char[]]@('"', "'"))) } $streamReader = New-Object -TypeName "System.IO.StreamReader" -ArgumentList $responseStream, $Encoding, $true $result = $streamReader.ReadToEnd() $RequestCompleted = $true Write-Output -InputObject $result } catch { $RequestException = $_.Exception while ($RequestException -isnot [System.Net.WebException] -and $null -ne $RequestException.InnerException) { $RequestException = $RequestException.InnerException } if ($RequestException -is [System.Net.WebException] -and $null -eq $webResponse) { $webResponse = $RequestException.Response } Write-Warning -Message "$($MyInvocation.MyCommand): Request failed ($($RequestException.GetType().Name)), with: $SafeUri." Write-Warning -Message "$($MyInvocation.MyCommand): For troubleshooting steps see: $($script:resourceStrings.Uri.Info)." throw } finally { try { if (-not $RequestCompleted -and $null -ne $httpWebRequest) { $httpWebRequest.Abort() } if ($null -ne $streamReader) { $streamReader.Dispose() } elseif ($null -ne $responseStream) { $responseStream.Dispose() } } finally { if ($null -ne $webResponse) { $webResponse.Dispose() } } } } |