This article is helpful if you want to quickly listen for HTTP requests, inspect them, and respond to them in real time. That means you can decide what request data to explore and what response data to send on the fly!
This could be useful when testing webhooks, dependent web services, or anything else HTTP.
As far as I can tell, all PowerShell versions should be supported.
This solution is made possible by the .NET HttpListener
.
$httpListener = New-Object System.Net.HttpListener
$httpListener.Prefixes.Add('http://localhost:5001/')
$httpListener.Start()
Here, I’m listening for requests aimed at http://localhost:5001/
, but you could listen to any other interface or port on your machine.
Listen on all interfaces by using a +
, like so: http://+:5001/
HttpListener
requires that you include a trailing /
in the prefix.
$context = $httpListener.GetContext()
In the above, $context
will contain both the request and response object.
The HttpListener.GetContext()
method synchronously blocks until a request is received.
In a separate PowerShell session:
Invoke-WebRequest 'http://localhost:5001/big-test'
You could kick off a request from anywhere though. It doesn’t have to be from PowerShell or even from your machine.
Barring network or firewall issues, the command in step 2 should complete once the request is received.
Now, you have all the time in the world to read every property of the request!
$context.Request.HttpMethod
$context.Request.Url
$context.Request.Headers.ToString() # pretty printing with .ToString()
# use a StreamReader to read the HTTP body as a string
$requestBodyReader = New-Object System.IO.StreamReader $context.Request.InputStream
$requestBodyReader.ReadToEnd()
If the calling service hasn’t timed out on you yet, you can send back a response!
$context.Response.StatusCode = 200
$context.Response.ContentType = 'application/json'
$responseJson = '{"big": "test"}'
$responseBytes = [System.Text.Encoding]::UTF8.GetBytes($responseJson)
$context.Response.OutputStream.Write($responseBytes, 0, $responseBytes.Length)
$context.Response.Close() # end the response
You can call .Write(...)
multiple times before calling .Close()
.
Release the open TCP port:
$httpListener.Close()
HttpListener
Do?For all this, check out the docs.
If you find this post useful, and wish to support it, you can below!