1+ <#
2+ . SYNOPSIS
3+ Switch -RegEx Server
4+ . DESCRIPTION
5+ A simple server implemented in a single switch -regex.
6+
7+ Any match can provide results.
8+ . EXAMPLE
9+ ./SwitchRegexServer.ps1
10+ #>
11+ param (
12+ # The rootUrl of the server. By default, a random loopback address.
13+ [string ]$RootUrl =
14+ " http://127.0.0.1:$ ( Get-Random - Minimum 4200 - Maximum 42000 ) /" ,
15+
16+ [Collections.IDictionary ]
17+ $Dictionary = [Ordered ]@ {
18+ " /" = @ {ContentType = ' text/html' ;Content = ' <h1>Hello World</h1>' }
19+ }
20+ )
21+
22+ $httpListener = [Net.HttpListener ]::new()
23+ $httpListener.Prefixes.Add ($RootUrl )
24+ Write-Warning " Listening on $RootUrl $ ( $httpListener.Start ()) "
25+
26+ $io = [Ordered ]@ { # Pack our job input into an IO dictionary
27+ HttpListener = $httpListener ;
28+ }
29+
30+ # Our server is a thread job
31+ Start-ThreadJob - ScriptBlock {param ([Collections.IDictionary ]$io )
32+ $psvariable = $ExecutionContext.SessionState.PSVariable
33+ foreach ($key in $io.Keys ) { # First, let's unpack.
34+ if ($io [$key ] -is [PSVariable ]) { $psvariable.set ($io [$key ]) }
35+ else { $psvariable.set ($key , $io [$key ]) }
36+ }
37+
38+ # Listen for the next request
39+ :nextRequest while ($httpListener.IsListening ) {
40+ $getContext = $httpListener.GetContextAsync ()
41+ while (-not $getContext.Wait (17 )) { }
42+ $time = [DateTime ]::Now
43+ $request , $reply =
44+ $getContext.Result.Request , $getContext.Result.Response
45+ $result = $null
46+ $result =
47+ switch - regex ($request.Url.LocalPath ) {
48+ ' /' {
49+ " <h1>Home Sweet Home</h1>"
50+ }
51+ ' /Hello/?' {
52+ " <h1>Hello World</h1>"
53+ }
54+ ' /(?<d1>[\d\.]+)x(?<d2>[\d\.]+)/?' {
55+ ($matches.d1 -as [double ]) * ($matches.d2 -as [double ])
56+ }
57+ default {
58+ $timeToRespond = [DateTime ]::Now - $time
59+ " $ ( $request.HttpMethod ) $ ( $request.Url ) $ ( $timeToRespond ) "
60+ }
61+ }
62+ if ($result ) {
63+ $reply.Close ($OutputEncoding.GetBytes (" $result " ), $false )
64+ } else {
65+ $reply.StatusCode = 404
66+ $reply.Close ()
67+ }
68+ }
69+ } - ThrottleLimit 100 - ArgumentList $IO - Name " $RootUrl " | # Output our job,
70+ Add-Member - NotePropertyMembers @ { # but attach a few properties first:
71+ HttpListener = $httpListener # * The listener (so we can stop it)
72+ IO = $IO # * The IO (so we can change it)
73+ Url = " $RootUrl " # The URL (so we can easily access it).
74+ } - Force - PassThru # Pass all of that thru and return it to you.
0 commit comments