1+ <#
2+ . SYNOPSIS
3+ Method Switch Server
4+ . DESCRIPTION
5+ A simple server implemented in a single switch.
6+
7+ Each HTTP Method is processed in a separate case.
8+ . EXAMPLE
9+ ./MethodSwitchServer.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+ switch ($request.httpMethod ) {
46+ get {
47+ $reply.Close (
48+ $OutputEncoding.GetBytes (
49+ " Getting $ ( $request.Url ) "
50+ ), $false )
51+ }
52+ head {
53+ $reply.ContentLength = 0
54+ $reply.Close ()
55+ }
56+ default {
57+ $timeToRespond = [DateTime ]::Now - $time
58+ $myReply = " $ ( $request.HttpMethod ) $ ( $request.Url ) $ ( $timeToRespond ) "
59+ $reply.Close ($OutputEncoding.GetBytes ($myReply ), $false )
60+ }
61+ }
62+ }
63+ } - ThrottleLimit 100 - ArgumentList $IO - Name " $RootUrl " | # Output our job,
64+ Add-Member - NotePropertyMembers @ { # but attach a few properties first:
65+ HttpListener = $httpListener # * The listener (so we can stop it)
66+ IO = $IO # * The IO (so we can change it)
67+ Url = " $RootUrl " # The URL (so we can easily access it).
68+ } - Force - PassThru # Pass all of that thru and return it to you.
0 commit comments