Private/Validation.ps1
|
# Kept separate from discovery so URL validation can evolve without touching the page parsers. function Test-SurfaceUri { [CmdletBinding()] param( [Parameter(Mandatory)][string]$Uri, [int]$TimeoutSec = 30 ) $handler = $null $client = $null $request = $null $response = $null try { $handler = [System.Net.Http.HttpClientHandler]::new() $handler.AllowAutoRedirect = $true $client = [System.Net.Http.HttpClient]::new($handler) $client.Timeout = [timespan]::FromSeconds($TimeoutSec) $client.DefaultRequestHeaders.UserAgent.ParseAdd('SurfaceWinPEDrivers/1.0') $request = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Head, $Uri) $response = $client.SendAsync($request, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).GetAwaiter().GetResult() if (-not $response.IsSuccessStatusCode -and [int]$response.StatusCode -in 403,405) { $response.Dispose() $response = $null $request.Dispose() $request = $null $request = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Get, $Uri) $request.Headers.Range = [System.Net.Http.Headers.RangeHeaderValue]::new(0, 0) $response = $client.SendAsync($request, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead).GetAwaiter().GetResult() } [pscustomobject]@{ Uri = $Uri Success = [bool]$response.IsSuccessStatusCode StatusCode = [int]$response.StatusCode ContentLength = if ($response.Content.Headers.ContentLength) { [int64]$response.Content.Headers.ContentLength } else { $null } ContentType = if ($response.Content.Headers.ContentType) { [string]$response.Content.Headers.ContentType.MediaType } else { $null } Error = $null } } catch { [pscustomobject]@{ Uri = $Uri Success = $false StatusCode = $null ContentLength = $null ContentType = $null Error = $_.Exception.Message } } finally { if ($response) { $response.Dispose() } if ($request) { $request.Dispose() } if ($client) { $client.Dispose() } if ($handler) { $handler.Dispose() } } } |