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