Files
SAMY/src/http.ps1
2026-01-24 23:11:47 -05:00

151 lines
5.2 KiB
PowerShell

function Send-Text {
param($Context, $Text)
if (-not $Context -or -not $Context.Response) { return }
$bytes = [Text.Encoding]::UTF8.GetBytes([string]$Text)
$Context.Response.ContentType = 'text/plain; charset=utf-8'
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes,0,$bytes.Length)
$Context.Response.OutputStream.Close()
}
function Send-HTML {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)][object] $Context,
[Parameter(Mandatory = $true)][string] $Html
)
if (-not $Context -or -not $Context.Response) { return }
try {
$Context.Response.Headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
$Context.Response.Headers["Pragma"] = "no-cache"
$Context.Response.Headers["Expires"] = "0"
} catch { }
$bytes = [Text.Encoding]::UTF8.GetBytes($Html)
$Context.Response.ContentType = "text/html; charset=utf-8"
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
$Context.Response.OutputStream.Close()
}
function Send-RemoteAsset {
[CmdletBinding()]
param(
[Parameter(Mandatory)][object] $Context,
[Parameter(Mandatory)][string] $Url,
[Parameter(Mandatory)][string] $ContentType
)
if (-not $Context -or -not $Context.Response) { return }
if ([string]::IsNullOrWhiteSpace($Url)) {
try {
$Context.Response.StatusCode = 500
} catch { }
Send-Text $Context "Asset URL is empty (ContentType=$ContentType)"
return
}
try {
$resp = Invoke-WebRequest -UseBasicParsing -Uri $Url -ErrorAction Stop
try {
$Context.Response.Headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
$Context.Response.Headers["Pragma"] = "no-cache"
$Context.Response.Headers["Expires"] = "0"
} catch { }
$Context.Response.ContentType = $ContentType
# Prefer binary stream for images/icons. For js/css/html, treat as UTF-8 text.
$bytes = $null
if ($ContentType -like 'image/*' -or $ContentType -like '*x-icon*' -or $ContentType -like '*octet-stream*') {
try {
$ms = New-Object System.IO.MemoryStream
$resp.RawContentStream.CopyTo($ms)
$bytes = $ms.ToArray()
}
catch {
# Fallback: treat as text if RawContentStream isn't usable
$bytes = [Text.Encoding]::UTF8.GetBytes([string]$resp.Content)
}
}
else {
$bytes = [Text.Encoding]::UTF8.GetBytes([string]$resp.Content)
}
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
}
catch {
Write-LogHybrid "Send-RemoteAsset failed for $Url : $($_.Exception.Message)" Error Server -LogToEvent
try {
$Context.Response.StatusCode = 502
$msg = "Failed to fetch asset: $Url"
$bytes = [Text.Encoding]::UTF8.GetBytes($msg)
$Context.Response.ContentType = "text/plain; charset=utf-8"
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
} catch { }
}
finally {
try { $Context.Response.OutputStream.Close() } catch { }
}
}
function Send-JSON {
[CmdletBinding()]
param(
$Context,
$Object
)
if (-not $Context -or -not $Context.Response) { return }
$json = $null
try {
if ($null -eq $Object) {
Write-LogHybrid "Send-JSON called with `$null object; returning empty JSON array." Warning Printers -LogToEvent
$json = '[]'
}
else {
try { $json = $Object | ConvertTo-Json -Depth 8 -ErrorAction Stop }
catch {
Write-LogHybrid "Send-JSON serialization failed: $($_.Exception.Message); returning empty JSON array." Error Printers -LogToEvent
$json = '[]'
}
}
$json = [string]$json
try {
$Context.Response.Headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
$Context.Response.Headers["Pragma"] = "no-cache"
$Context.Response.Headers["Expires"] = "0"
} catch { }
$bytes = [Text.Encoding]::UTF8.GetBytes($json)
$Context.Response.ContentType = "application/json; charset=utf-8"
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
}
catch {
Write-LogHybrid "Send-JSON fatal error: $($_.Exception.Message)" Error Printers -LogToEvent
try {
$fallback = '[]'
$bytes = [Text.Encoding]::UTF8.GetBytes($fallback)
$Context.Response.ContentType = "application/json; charset=utf-8"
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
} catch { }
}
finally {
try { $Context.Response.OutputStream.Close() } catch { }
}
}