Command Window 0
Nav
# Setup: Define the listener and stop-credentials $listener = [System.Net.HttpListener] ::new ()$listener .Prefixes .Add ("http://localhost:8080/" )$StopCreds = @{ Username = "admin" Password = "password" } $listener .Start ()Write-Host "Server listening on http://localhost:8080/" # Utility: Get a daily log file name function Get-LogFilePath { "server-log-$(Get-Date -Format 'yyyy-MM-dd').txt" } # Logging: Record the request details to the daily log file function Log-Request { param ($context ) try { $req = $context .Request $payload = if ($req .HasEntityBody) { [System.IO.StreamReader] ::new ($req .InputStream).ReadToEnd () } else { "" } $log = "[{0}] {1} request from {2} to {3}`nPayload: {4}`n" -f (Get-Date), $req .HttpMethod, $req .RemoteEndPoint .Address, $req .Url, $payload Add-Content -Path (Get-LogFilePath) -Value $log Write-Host "Logged: $log" } catch { Write-Error "Error logging request: $_" } } # Request Processing: Generate a proper response based on the endpoint. function Process-Request { param ($context ) Log-Request -context $context $req = $context .Request $resp = $context .Response $respBody = "Endpoint not found." $resp .StatusCode = 404 switch ($req .Url .AbsolutePath) { "/hello" { $respBody = "Hello, World!" $resp .StatusCode = 200 } "/stop" { $auth = $req .Headers["Authorization" ] if ($auth -and $auth .StartsWith ("Basic " )) { $decoded = [System.Text.Encoding] ::UTF8 .GetString ([System.Convert] ::FromBase64String ($auth .Substring (6))) -split ":" if ($decoded [0] -eq $StopCreds .Username -and $decoded [1] -eq $StopCreds .Password) { $respBody = "Server stopping..." $resp .StatusCode = 200 # Stop the listener asynchronously $listener .Stop () Write-Host "Server stopped." Exit } } $respBody = "Unauthorized." $resp .StatusCode = 401 } } $bytes = [System.Text.Encoding] ::UTF8 .GetBytes ($respBody ) $resp .ContentLength64 = $bytes .Length try { $resp .OutputStream .Write ($bytes , 0, $bytes .Length) } catch { Write-Error "Error writing response: $_" } finally { $resp .OutputStream .Close () } } # Asynchronous callback: Process each request as it comes $callback = { param ($asyncResult ) try { $listenerInstance = $asyncResult .AsyncState $context = $listenerInstance .EndGetContext ($asyncResult ) Process-Request $context } catch { Write-Error "Exception in callback: $_" } finally { # Restart the asynchronous listener if still active if ($listener .IsListening) { $listener .BeginGetContext ($callback , $listener ) | Out-Null } } } # Start the asynchronous listening loop $listener .BeginGetContext ($callback , $listener ) | Out-Null # Prevent the script from exiting indefinitely Write-Host "Press Enter to exit (the server will stop listening)." [Console] ::ReadLine () | Out-Null