Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Function Invoke-WebServer {
- [cmdletbinding()]
- param(
- $URL = 'http://localhost:9092/',
- $AuthenticationSchemes = "Negotiate",
- $RunspacesCount = 4,
- [scriptblock]$ProcessRequest={},
- [System.Management.Automation.Runspaces.InitialSessionState]$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
- )
- $script:InitialSessionState = $InitialSessionState
- $listener = New-Object System.Net.HttpListener
- $listener.Prefixes.Add($url)
- $listener.AuthenticationSchemes = $authenticationSchemes
- $listener.Start()
- Write-Verbose "Starting up a runspace pool of $RunspacesCount runspaces"
- $pool = [runspacefactory]::CreateRunspacePool(2, $RunspacesCount)
- $pool.Open()
- Function Add-SessionStateVariable {
- param($Name)
- $var = Get-Item "variable:\$name"
- $variable = New-Object System.Management.Automation.Runspaces.SessionStateVariableEntry $var.Name,$var.Value,$null
- $script:InitialSessionState.Variables.Add($variable)
- }
- $VerboseMessageQueue = [System.Collections.Queue]::Synchronized((new-object Collections.Queue))
- $RequestHandler = {
- param(
- $Context,
- $VerboseMessageQueue,
- $ProcessRequest
- )
- # Add types so that we get some intellisense help while coding
- [System.Net.HttpListenerRequest]$Request = $context.Request
- [System.Net.HttpListenerResponse]$Response = $context.Response
- [System.Security.Principal.IPrincipal]$User = $context.User
- $VerboseMessageQueue.Enqueue("User $($Context.User.Identity.Name) sent a request")
- $length = $Request.ContentLength64
- $buffer = New-Object "byte[]" $length
- [void]$Request.InputStream.Read($buffer,0,$length)
- $requestBody = [System.Text.Encoding]::UTF8.GetString($buffer)
- $requestObject = $requestBody | ConvertFrom-Json
- $context.Response | Add-Member -Name ResponseFile -MemberType NoteProperty -Value $null -Force
- $context.Request | Add-Member -Name RequestBody -MemberType NoteProperty -Value $requestBody -Force
- $context.Request | Add-Member -Name RequestObject -MemberType NoteProperty -Value $requestObject -Force
- try {
- $result = .$ProcessRequest $context $VerboseMessageQueue
- if($context.Response.ResponseFile) {
- $buffer = [System.IO.File]::ReadAllBytes($context.Response.ResponseFile)
- $response.ContentLength64 = $buffer.Length
- $response.OutputStream.Write($buffer, 0, $buffer.Length)
- } elseif($context.Response.ContentLength64 -eq 0){
- if($result) {
- $jsonResponse = $result | ConvertTo-Json
- $buffer = [System.Text.Encoding]::UTF8.GetBytes($jsonResponse)
- $response.ContentLength64 = $buffer.Length
- $response.OutputStream.Write($buffer, 0, $buffer.Length)
- }
- }
- $response.close()
- } catch {
- $Context.Response.StatusRequestHandler = "500"
- $response.close()
- }
- }
- $RequestListener = {
- param(
- $listener,
- $pool,
- $VerboseMessageQueue,
- $RequestHandler,
- $ProcessRequest,
- $InitialSessionState
- )
- $VerboseMessageQueue.Enqueue("Waiting for request")
- $psWorker = [powershell]::Create($InitialSessionState)
- $context = $listener.GetContext()
- $psWorker.RunspacePool = $pool
- [void]$psWorker.AddScript($RequestHandler.ToString())
- [void]$psWorker.AddArgument($context)
- [void]$psWorker.AddArgument($VerboseMessageQueue)
- [void]$psWorker.AddArgument($ProcessRequest)
- [void]$psWorker.BeginInvoke()
- }
- try {
- Write-Verbose "Server listening on $url"
- while ($listener.IsListening)
- {
- if($iasync -eq $null -or $iasync.IsCompleted) {
- $obj = New-Object object
- $ps = [powershell]::Create($InitialSessionState)
- $ps.RunspacePool = $pool
- [void]$ps.AddScript($RequestListener.ToString())
- [void]$ps.AddArgument($listener)
- [void]$ps.AddArgument($pool)
- [void]$ps.AddArgument($VerboseMessageQueue)
- [void]$ps.AddArgument($Requesthandler)
- [void]$ps.AddArgument($ProcessRequest)
- [void]$ps.AddArgument($InitialSessionState)
- $iasync = $ps.BeginInvoke()
- }
- while($VerboseMessageQueue.count -gt 0){
- Write-Verbose $VerboseMessageQueue.Dequeue()
- }
- Start-Sleep -Milliseconds 30
- }
- } finally {
- Write-Verbose "Closing down server"
- $listener.Stop()
- $listener.Close()
- }
- }
- # Create a simple html file
- "<html><body>Hej</body></html>" | Out-File c:\ps\out.html -Encoding utf8
- # Sample server, serving up a single file in /file and
- Invoke-WebServer -URL "http://*:8080/" -AuthenticationSchemes negotiate -ProcessRequest {
- param(
- $context,
- $VerboseMessageQueue
- )
- $VerboseMessageQueue.Enqueue("::Request::")
- $VerboseMessageQueue.Enqueue($($context.Request | out-string))
- if($context.request.url.localpath -eq "/json" -and $context.request.httpmethod -eq "get") {
- $VerboseMessageQueue.Enqueue($($context.request.requestobject | out-string))
- [pscustomobject]@{
- Sequence = @(3,2,1)
- Strings = @("red","blue","green")
- }
- }
- if($context.request.url.localpath -eq "/json" -and $context.request.httpmethod -eq "post") {
- $VerboseMessageQueue.Enqueue($($context.request.requestobject | out-string))
- [pscustomobject]@{
- Sequence = @(3,3,3)
- Strings = @("PUT","GET","POST")
- }
- }
- if($context.request.url.localpath -eq "/file") {
- $context.response.ResponseFile = "c:\ps\out.html"
- $context.response.contenttype = "text/html"
- }
- } -Verbose
- # Sample client calls
- # Simple Get JSON
- Invoke-RestMethod -Method get -Uri 'http://localhost:8080/json' -UseDefaultCredentials
- # Post JSON to the webserver
- $data = [pscustomobject]@{
- Sequence = @(1,2,3,4)
- Strings = @("Orange","yellow","black")
- }
- $postData = $data | ConvertTo-Json
- Invoke-RestMethod -Method post -Uri 'http://localhost:8080/json' -UseDefaultCredentials -Body $postData
- # Request a file
- Invoke-RestMethod -Method get -Uri 'http://localhost:8080/file' -UseDefaultCredentials
Advertisement
Add Comment
Please, Sign In to add comment