Skip to content

Instantly share code, notes, and snippets.

@joshooaj
Last active January 9, 2024 00:43
Show Gist options
  • Save joshooaj/4c2a805f979718fbc423a454270e5d47 to your computer and use it in GitHub Desktop.
Save joshooaj/4c2a805f979718fbc423a454270e5d47 to your computer and use it in GitHub Desktop.
Start a simple local HTTP listener to receive test HTTP requests
function Start-HttpListener {
<#
.SYNOPSIS
Starts a local HTTP server and returns information about HTTP requests.
.DESCRIPTION
This function starts a local HTTP server, by default on http://localhost:10123/,
and returns information about the first HTTP request received.
To test this simple HTTP listener, try opening a second PowerShell session and
sending a request using Invoke-RestMethod like this:
$body = [pscustomobject]@{ Message = 'Hello world' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri 'http://localhost:10123/' -Body $body
.PARAMETER Prefix
Specifies the URI and path prefix for the HTTP server to listen on.
.EXAMPLE
Start-HttpListener | Select-Object -ExpandProperty Body
Starts listening on http://localhost:10123/ and when a request is received,
the body of the request is returned as a string.
.EXAMPLE
Start-HttpListener | ConvertTo-Json
Starts listening on http://localhost:10123/ and when a request is received,
a JSON object is returned with the remote client address, HTTP method, the
full requested URL, the headers, and the body.
.EXAMPLE
(Start-HttpListener).Body | ConvertFrom-Json | ConvertTo-Json -Depth 100
Starts listening on http://localhost:10123/ and when a request is received,
the JSON body is reformatted and "pretty printed" as a string with consistent
indentation.
#>
[CmdletBinding()]
param (
[Parameter()]
[uri[]]
$Prefix = 'http://localhost:10123/'
)
begin {
Add-Type -AssemblyName System.Net
}
process {
try {
$listener = [Net.HttpListener]::new()
$Prefix | ForEach-Object {
$listener.Prefixes.Add($_)
}
$listener.Start()
$context = $listener.GetContext()
$request = $context.Request
$headers = [ordered]@{}
$request.Headers.Keys | Foreach-Object {
$headers[$_] = $request.Headers[$_]
}
$reader = [io.streamreader]::new($request.InputStream)
[pscustomobject]@{
Client = $request.RemoteEndPoint.ToString()
Method = $request.HttpMethod
Url = $request.Url
Headers = $headers
Body = $reader.ReadToEnd()
}
$response = $context.Response
$response.StatusCode = [int][net.httpstatuscode]::OK
$response.StatusDescription = 'Status OK'
$response.Close()
} finally {
if ($listener) {
$listener.Dispose()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment