Skip to content

Instantly share code, notes, and snippets.

@ChrisStro
Created March 18, 2023 13:14
Show Gist options
  • Save ChrisStro/1acdae319ca9cb0188682fae603db15b to your computer and use it in GitHub Desktop.
Save ChrisStro/1acdae319ca9cb0188682fae603db15b to your computer and use it in GitHub Desktop.
function Start-psWebRequestServer {
[CmdletBinding()]
param ()
begin {
# default
###########
$ServerPort = 5678
$HostNameOrIP = "*"
$SingleRequest = $False
$ServerDebug = $False
# init
###########
if ($Global:psWebServerServerPort) {
$ServerPort = $Global:psWebServerServerPort
Write-Host "[$(Get-Date -Format g)] `$ServerPort now set to => $ServerPort"
}
if ($Global:psWebServerHostNameOrIP) {
$HostNameOrIP = $Global:psWebServerHostNameOrIP
Write-Host "[$(Get-Date -Format g)] `$HostNameOrIP now set to => $HostNameOrIP"
}
if ($Global:psWebServerSingleRequest) {
$SingleRequest = $Global:psWebServerSingleRequest
Write-Host "[$(Get-Date -Format g)] `$SingleRequest now set to => $SingleRequest"
}
if (!$Global:psWebServerServerDebug) {
$ServerDebug = $Global:psWebServerServerDebug
Write-Host "[$(Get-Date -Format g)] `$ServerDebug now set to => $ServerDebug"
}
$listener = New-Object System.Net.HttpListener;
$listener.Prefixes.Add("http://$HostNameOrIP`:$ServerPort/");
$listener.Start()
# prevent directory traversal attacks
#####################################
New-PSDrive -Name "webroot" -PSProvider FileSystem -Root $PWD.Path | Out-Null
Push-Location -Path "webroot:\"
}
process {
Write-Host "[$(Get-Date -Format g)] Visiting http://$HostNameOrIP`:$ServerPort/"
Write-Host "[$(Get-Date -Format g)] Stop listener via http://$HostNameOrIP`:$ServerPort/stop"
while ($listener.IsListening) {
try {
# request vars
$context = $listener.GetContext()
$response = $context.Response
$request = $context.Request
$headers = $request.Headers
# $response.ContentType = "application/json; charset=utf-8"
# $response.ContentType = "text/plain; charset=utf-8"
# console output vars
$remote_host = $context.Request.RemoteEndPoint.Address
$access_url = $context.Request.Url
if ($context.Request.RawUrl -eq "/") {
if ($ServerDebug) {
$context | Out-Host
}
$return = @{}
$return.Remote_Host = $request.RemoteEndPoint.Address
$return.Url = $request.Url
$return.Method = $request.HttpMethod
$return.KeepAlive = $request.KeepAlive
$return.Headers = @{}
foreach ($key in $headers.AllKeys) {
$return.Headers.$key = $headers.GetValues($key)[0]
}
# read body
if ($request.HasEntityBody) {
$body = $request.InputStream
$enc = $request.ContentEncoding
$reader = [System.IO.StreamReader]::new($Body, $enc)
$return.Body = $reader.ReadToEnd()
$body.Close()
$reader.Close()
}
# $content = $return | Out-String
$content = $return | ConvertTo-Json
} elseif ($context.Request.RawUrl -eq "/stop") { $content = "<h1>shutting down listener</h1>"; $stop_listener = $true }
if ($SingleRequest) { $stop_listener = $true }
# console output
Write-Host "[$(Get-Date -Format g)] $remote_host => $access_url"
Write-Verbose $($context | ConvertTo-Json)
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Host "[$(Get-Date -Format g)] Could not reach. Verify server is accessible over the network" -ForegroundColor Magenta
$response.StatusCode = 404
$content = "<h1>404 - Page Not Found</h1>"
} catch [System.Net.HttpListenerException] {
Write-Host "[$(Get-Date -Format g)] $_" -ForegroundColor Yellow
} finally {
$content = [System.Text.Encoding]::UTF8.GetBytes($content)
$response.ContentLength64 = $content.Length
$response.OutputStream.Write($content, 0, $content.Length)
$response.Close()
Write-Host "[$(Get-Date -Format g)] Return $($response.StatusCode)" -ForegroundColor Cyan
# stop listener
###############
if ($stop_listener) { $listener.Stop() ; Pop-Location ; Remove-PSDrive -Name "webroot" }
}
}
}
}
Start-psWebRequestServer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment