diff --git a/module/Samy.Http.ps1 b/module/Samy.Http.ps1 deleted file mode 100644 index b7da726..0000000 --- a/module/Samy.Http.ps1 +++ /dev/null @@ -1,220 +0,0 @@ -# Samy.Http.ps1 -# HTTP helpers, listener, and dispatcher - -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' - $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 - } - $bytes = [Text.Encoding]::UTF8.GetBytes($Html) - $Context.Response.ContentType = 'text/html' - $Context.Response.ContentLength64 = $bytes.Length - $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length) - $Context.Response.OutputStream.Close() -} - -function Send-JSON { - [CmdletBinding()] - param( - $Context, - $Object - ) - - if (-not $Context -or -not $Context.Response) { - return - } - - 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 5 -ErrorAction Stop - } - catch { - Write-LogHybrid "Send-JSON serialization failed: $($_.Exception.Message); returning empty JSON array." Error Printers -LogToEvent - $json = '[]' - } - } - - $json = [string]$json - $bytes = [Text.Encoding]::UTF8.GetBytes($json) - $Context.Response.ContentType = 'application/json' - $Context.Response.ContentLength64 = $bytes.Length - $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length) - $Context.Response.OutputStream.Close() - } - 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' - $Context.Response.ContentLength64 = $bytes.Length - $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length) - $Context.Response.OutputStream.Close() - } - catch { - } - } -} - -function Invoke-TasksCompleted { - param($Context) - - Write-LogHybrid "All UI-selected tasks processed" Info UI -LogToEvent - Send-Text $Context "Tasks completion acknowledged." -} - -function Get-NextFreePort { - param([int]$Start) - - for ($p = [Math]::Max(1024,$Start); $p -lt 65535; $p++) { - $l = [System.Net.Sockets.TcpListener]::new([Net.IPAddress]::Loopback, $p) - try { - $l.Start() - $l.Stop() - return $p - } - catch { - } - } - throw "No free TCP port available." -} - -function Dispatch-Request { - param($Context) - - $path = $Context.Request.Url.AbsolutePath.TrimStart('/') - - if ($path -eq 'quit') { - Write-LogHybrid "Shutdown requested" Info Server -LogToEvent - Send-Text $Context "Server shutting down." - $Global:Listener.Stop() - return - } - - if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'tasksCompleted') { - Invoke-TasksCompleted $Context - return - } - - if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'getpw') { - Invoke-FetchSites $Context - return - } - - if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'renameComputer') { - Invoke-RenameComputer $Context - return - } - - if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'getprinters') { - Invoke-GetPrinters $Context - return - } - - if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'installprinters') { - Invoke-InstallPrinters $Context - return - } - - if ($path -in @('', 'onboard', 'offboard', 'tweaks', 'SVSApps')) { - $page = if ($path -eq '') { 'onboard' } else { $path } - $html = Get-UIHtml -Page $page - Send-HTML $Context $html - return - } - - $task = $Global:SamyTasks | Where-Object Name -EQ $path - if ($task) { - & $task.HandlerFn $Context - return - } - - $Context.Response.StatusCode = 404 - Send-Text $Context '404 - Not Found' -} - -function Start-SamyHttpServer { - param( - [Parameter(Mandatory)][int]$Port - ) - - $Global:Listener = [System.Net.HttpListener]::new() - $primaryPrefix = "http://localhost:$Port/" - $wildcardPrefix = "http://+:$Port/" - - try { - $Global:Listener.Prefixes.Add($primaryPrefix) - $Global:Listener.Start() - Write-LogHybrid "Listening on $primaryPrefix" Info Server -LogToEvent - } - catch [System.Net.HttpListenerException] { - if ($_.Exception.ErrorCode -eq 5) { - Write-LogHybrid "Access denied on $primaryPrefix. Attempting URL ACL..." Warning Server -LogToEvent - try { - $user = "$env:USERDOMAIN\$env:USERNAME" - if (-not $user.Trim()) { - $user = $env:USERNAME - } - Start-Process -FilePath "netsh" -ArgumentList "http add urlacl url=$wildcardPrefix user=`"$user`" listen=yes" -Verb RunAs -WindowStyle Hidden -Wait - $Global:Listener = [System.Net.HttpListener]::new() - $Global:Listener.Prefixes.Add($wildcardPrefix) - $Global:Listener.Start() - Write-LogHybrid "Listening on $wildcardPrefix (URL ACL added for $user)" Success Server -LogToEvent - } - catch { - Write-LogHybrid "URL ACL registration failed: $($_.Exception.Message)" Error Server -LogToEvent - return - } - } - elseif ($_.Exception.NativeErrorCode -in 32,183) { - $old = $Port - $Port = Get-NextFreePort -Start ($Port + 1) - $Global:Listener = [System.Net.HttpListener]::new() - $primaryPrefix = "http://localhost:$Port/" - $Global:Listener.Prefixes.Add($primaryPrefix) - $Global:Listener.Start() - Write-LogHybrid "Port $old busy. Listening on $primaryPrefix" Warning Server -LogToEvent - } - else { - Write-LogHybrid "HttpListener start failed: $($_.Exception.Message)" Error Server -LogToEvent - return - } - } - - try { - while ($Global:Listener.IsListening) { - $ctx = $Global:Listener.GetContext() - try { - Dispatch-Request $ctx - } - catch { - Write-LogHybrid "Dispatch error: $($_.Exception.Message)" Error Server -LogToEvent - } - } - } - finally { - $Global:Listener.Close() - Write-LogHybrid "Listener closed." Info Server -LogToEvent - } -}