Skip to content

Commit d10bbba

Browse files
feat: DebugServer ( Fixes #5 )
1 parent 3516049 commit d10bbba

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

Servers/DebugServer.ps1

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<#
2+
.SYNOPSIS
3+
A debug server.
4+
.DESCRIPTION
5+
A server that runs on the current thread, so you can debug it.
6+
7+
You can run this with -AsJob, but then you cannot debug in PowerShell.
8+
.NOTES
9+
A few notes:
10+
11+
1. This will effectively lock the current thread (CTRL+C works).
12+
2. Because of the way requests are processed, you may need to refresh to hit the breakpoint.
13+
3. Be aware that browsers will request a `favicon.ico` first.
14+
#>
15+
param(
16+
# The rootUrl of the server. By default, a random loopback address.
17+
[string]$RootUrl=
18+
"http://127.0.0.1:$(Get-Random -Minimum 4200 -Maximum 42000)/",
19+
20+
# If set, will run in a background job.
21+
[switch]
22+
$AsJob
23+
)
24+
25+
$httpListener = [Net.HttpListener]::new()
26+
$httpListener.Prefixes.add($RootUrl)
27+
$httpListener.Start()
28+
Write-Warning "Listening on $rootUrl"
29+
30+
$listenScript = {
31+
param([Net.HttpListener]$httpListener)
32+
# Listen for the next request
33+
:nextRequest while ($httpListener.IsListening) {
34+
$getContext = $httpListener.GetContextAsync()
35+
36+
while (-not $getContext.Wait(17)) { }
37+
38+
$context = $getContext.Result
39+
$requestTime = [DateTime]::Now
40+
$request, $reply = $context.Request, $context.Response
41+
$debugObject = $request |
42+
Select-Object HttpMethod, Url, Is* |
43+
Add-Member NoteProperty Headers ([Ordered]@{}) -Force -passThru |
44+
Add-Member NoteProperty Query ([Ordered]@{}) -Force -passThru
45+
46+
foreach ($headerName in $request.Headers) {
47+
$debugObject.headers[$headerName] = $request.Headers[$headerName]
48+
}
49+
if ($request.Url.Query) {
50+
51+
foreach ($chunk in $request.Url.Query -split '&') {
52+
$parsedQuery =
53+
[Web.HttpUtility]::ParseQueryString($chunk)
54+
$key = @($parsedQuery.Keys)[0]
55+
if ($debugObject.Query[$key]) {
56+
$debugObject.Query[$key] = @(
57+
$debugObject.Query[$key]
58+
) + $parsedQuery[$key]
59+
} else {
60+
$debugObject.Query[$key] = $parsedQuery[$key]
61+
}
62+
}
63+
}
64+
$reply.ContentType = 'application/json'
65+
$reply.Close(
66+
$OutputEncoding.GetBytes(
67+
($debugObject | ConvertTo-Json -Depth 5)
68+
), $false)
69+
"Responded to $($Request.Url) in $([DateTime]::Now - $requestTime)"
70+
}
71+
}
72+
73+
if ($AsJob) {
74+
Start-ThreadJob -ScriptBlock $listenerScript -ArgumentList $httpListener
75+
} else {
76+
. $listenScript $httpListener
77+
}

0 commit comments

Comments
 (0)