Created
September 25, 2016 12:52
Powershell static http server
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
#Requires -RunAsAdministrator | |
# Simple static http server. | |
Param( | |
[int]$port = 8080, | |
[string]$root = (Get-Location) | |
) | |
function Serve { | |
$listener = [System.Net.HttpListener]::new() | |
$listener.Prefixes.Add("http://+:$port/") | |
Write-Host "Root: $root" | |
try { | |
$listener.Start() | |
Write-Host "server started on :$port" | |
while ($listener.IsListening) { | |
$context = $null | |
$ctxTask = $listener.GetContextAsync() | |
do { | |
if ($ctxTask.Wait(100)) { | |
$context = $ctxTask.Result | |
} | |
} | |
while (-not $context) | |
Handle $context | |
} | |
} | |
catch [System.Exception] { | |
Write-Host $_ | |
} | |
finally { | |
$listener.Stop() | |
} | |
} | |
function Handle([System.Net.HttpListenerContext] $context) { | |
try { | |
Write-Host $context.Request.RawUrl | |
$path = $context.Request.RawUrl.TrimStart("/") | |
if ([String]::IsNullOrWhiteSpace($path)) { | |
$path = "index.html" | |
} | |
$path = [System.IO.Path]::Combine($root, $path) | |
if ([System.IO.File]::Exists($path)) { | |
$fstream = [System.IO.FileStream]::new($path, [System.IO.FileMode]::Open) | |
$fstream.CopyTo($context.Response.OutputStream) | |
} else { | |
$context.Response.StatusCode = 404 | |
} | |
} | |
catch [System.Exception] { | |
$context.Response.StatusCode = 500 | |
Write-Error $_ | |
} | |
finally { | |
$context.Response.Close() | |
} | |
} | |
Serve |
I was getting file lock errors. I modified the $fstream line to be read only
$fstream = [System.IO.FileStream]::new($path, [System.IO.FileMode]::open , [System.IO.FileAccess]::Read )
Cheers!
Also if the files presented have spaces or other characters they will need to be escaped for URL and if accessing a SMB share the file path will need to be unescaped.
$path = [System.IO.Path]::Combine($root, $path) ; $path = [uri]::UnescapeDataString($path)
!!Awesome code!! Tim-S
#Change root accordingly. I like sym links.
function GenIndexHtml {
$root='C:\Link\Link\';$Body = ls -r -file |%{ $UT8=$_ ; $_.fullname.replace($root,'') |%{ "<p><a href='http://192.168.0.100/"+[string]([uri]::EscapeUriString(($_.split('\\')|%{$_}) -join "/"))+"'/>$UT8</a></p>" } }
$IndexFileContent=@(); $IndexFileContent += "<html><head><title>Title</title></head><body>" ; $IndexFileContent +=$Body ; $IndexFileContent += "</body><html>"
$IndexFileContent |sc index.html
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thx - a handy little snippet ;)
Had a small issue with static content that required the MIME-type to be set correctly (Content contained scripts that use Webworkers).
Can be adapted to simply (try to) determine the MIMEtype from the filepath with the help of [System.Web.MimeMapping]::GetMimeMapping before writing the file to Outputstream.