Last active
May 4, 2024 14:02
-
-
Save jakobii/429dcef1bacacfa1da254a5353bbeac7 to your computer and use it in GitHub Desktop.
A Basic Powershell Webserver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# You Should be able to Copy and Paste this into a powershell terminal and it should just work. | |
# To end the loop you have to kill the powershell terminal. ctrl-c wont work :/ | |
# Http Server | |
$http = [System.Net.HttpListener]::new() | |
# Hostname and port to listen on | |
$http.Prefixes.Add("http://localhost:8080/") | |
# Start the Http Server | |
$http.Start() | |
# Log ready message to terminal | |
if ($http.IsListening) { | |
write-host " HTTP Server Ready! " -f 'black' -b 'gre' | |
write-host "try testing the different route examples: " -f 'y' | |
write-host "$($http.Prefixes)" -f 'y' | |
write-host "$($http.Prefixes)some/form" -f 'y' | |
} | |
# INFINTE LOOP | |
# Used to listen for requests | |
while ($http.IsListening) { | |
# Get Request Url | |
# When a request is made in a web browser the GetContext() method will return a request object | |
# Our route examples below will use the request object properties to decide how to respond | |
$context = $http.GetContext() | |
# ROUTE EXAMPLE 1 | |
# http://127.0.0.1/ | |
if ($context.Request.HttpMethod -eq 'GET' -and $context.Request.RawUrl -eq '/') { | |
# We can log the request to the terminal | |
write-host "$($context.Request.UserHostAddress) => $($context.Request.Url)" -f 'mag' | |
# the html/data you want to send to the browser | |
# you could replace this with: [string]$html = Get-Content "C:\some\path\index.html" -Raw | |
[string]$html = "<h1>A Powershell Webserver</h1><p>home page</p>" | |
#resposed to the request | |
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html) # convert htmtl to bytes | |
$context.Response.ContentLength64 = $buffer.Length | |
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length) #stream to broswer | |
$context.Response.OutputStream.Close() # close the response | |
} | |
# ROUTE EXAMPLE 2 | |
# http://localhost:8080/some/form' | |
if ($context.Request.HttpMethod -eq 'GET' -and $context.Request.RawUrl -eq '/some/form') { | |
# We can log the request to the terminal | |
write-host "$($context.Request.UserHostAddress) => $($context.Request.Url)" -f 'mag' | |
[string]$html = " | |
<h1>A Powershell Webserver</h1> | |
<form action='/some/post' method='post'> | |
<p>A Basic Form</p> | |
<p>fullname</p> | |
<input type='text' name='fullname'> | |
<p>message</p> | |
<textarea rows='4' cols='50' name='message'></textarea> | |
<br> | |
<input type='submit' value='Submit'> | |
</form> | |
" | |
#resposed to the request | |
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html) | |
$context.Response.ContentLength64 = $buffer.Length | |
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length) | |
$context.Response.OutputStream.Close() | |
} | |
# ROUTE EXAMPLE 3 | |
# http://localhost:8080/some/post' | |
if ($context.Request.HttpMethod -eq 'POST' -and $context.Request.RawUrl -eq '/some/post') { | |
# decode the form post | |
# html form members need 'name' attributes as in the example! | |
$FormContent = [System.IO.StreamReader]::new($context.Request.InputStream).ReadToEnd() | |
# We can log the request to the terminal | |
write-host "$($context.Request.UserHostAddress) => $($context.Request.Url)" -f 'mag' | |
Write-Host $FormContent -f 'Green' | |
# the html/data | |
[string]$html = "<h1>A Powershell Webserver</h1><p>Post Successful!</p>" | |
#resposed to the request | |
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html) | |
$context.Response.ContentLength64 = $buffer.Length | |
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length) | |
$context.Response.OutputStream.Close() | |
} | |
# powershell will continue looping and listen for new requests... | |
} |
Neat! very clear examples!
You can add a clean exit route by adding the following in the while ($http.IsListening)
loop:
# ROUTE EXAMPLE 4
# http://localhost:8080/quit'
if ($context.Request.HttpMethod -eq 'GET' -and $context.Request.RawUrl -eq '/quit')
{
$http.Close()
}
Great example!
I would recommend replacing line 7
$http = [System.Net.HttpListener]::new()
with the next syntax:
$http = New-Object System.Net.HttpListener
Some frameworks are looking at ::new() as a non-existing method and failing
Great example!
How do I transfer images ? E. g. in line 74
<img src="1.png" alt="btn1">
I have to add buttons with images
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added a post example.