108 lines
3.5 KiB
PowerShell
108 lines
3.5 KiB
PowerShell
# Simple static file server for the wedding site (Windows, no Node/Python required)
|
|
$ErrorActionPreference = "Stop"
|
|
$root = $PSScriptRoot
|
|
$port = 8080
|
|
|
|
$mime = @{
|
|
".html" = "text/html; charset=utf-8"
|
|
".htm" = "text/html; charset=utf-8"
|
|
".css" = "text/css; charset=utf-8"
|
|
".js" = "application/javascript; charset=utf-8"
|
|
".json" = "application/json; charset=utf-8"
|
|
".png" = "image/png"
|
|
".jpg" = "image/jpeg"
|
|
".jpeg" = "image/jpeg"
|
|
".gif" = "image/gif"
|
|
".svg" = "image/svg+xml"
|
|
".webp" = "image/webp"
|
|
".woff" = "font/woff"
|
|
".woff2" = "font/woff2"
|
|
".ttf" = "font/ttf"
|
|
".otf" = "font/otf"
|
|
".mp3" = "audio/mpeg"
|
|
".mp4" = "video/mp4"
|
|
".ico" = "image/x-icon"
|
|
}
|
|
|
|
function Get-ContentType([string]$path) {
|
|
$ext = [System.IO.Path]::GetExtension($path).ToLowerInvariant()
|
|
if ($mime.ContainsKey($ext)) { return $mime[$ext] }
|
|
return "application/octet-stream"
|
|
}
|
|
|
|
function Send-File([System.Net.HttpListenerContext]$ctx, [string]$filePath) {
|
|
$bytes = [System.IO.File]::ReadAllBytes($filePath)
|
|
$ctx.Response.ContentType = Get-ContentType $filePath
|
|
$ctx.Response.ContentLength64 = $bytes.Length
|
|
$ctx.Response.OutputStream.Write($bytes, 0, $bytes.Length)
|
|
}
|
|
|
|
$listener = New-Object System.Net.HttpListener
|
|
$listener.Prefixes.Add("http://localhost:$port/")
|
|
$listener.Start()
|
|
|
|
$url = "http://localhost:$port/www.mewedding.vn/index.html"
|
|
Write-Host ""
|
|
Write-Host " Thiep cuoi dang chay tai:" -ForegroundColor Green
|
|
Write-Host " $url" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
Write-Host " Nhan Ctrl+C de dung server." -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
|
|
try {
|
|
Start-Process $url | Out-Null
|
|
} catch {
|
|
Write-Host " Mo trinh duyet thu cong: $url" -ForegroundColor Yellow
|
|
}
|
|
|
|
while ($listener.IsListening) {
|
|
$context = $listener.GetContext()
|
|
$request = $context.Request
|
|
$response = $context.Response
|
|
|
|
try {
|
|
$rawPath = $request.Url.LocalPath
|
|
if ([string]::IsNullOrWhiteSpace($rawPath) -or $rawPath -eq "/") {
|
|
$rawPath = "/www.mewedding.vn/index.html"
|
|
}
|
|
|
|
$relative = [System.Uri]::UnescapeDataString($rawPath).TrimStart("/").Replace("/", [IO.Path]::DirectorySeparatorChar)
|
|
$filePath = Join-Path $root $relative
|
|
$filePath = [IO.Path]::GetFullPath($filePath)
|
|
|
|
if (-not $filePath.StartsWith([IO.Path]::GetFullPath($root), [StringComparison]::OrdinalIgnoreCase)) {
|
|
$response.StatusCode = 403
|
|
$buf = [Text.Encoding]::UTF8.GetBytes("403 Forbidden")
|
|
$response.OutputStream.Write($buf, 0, $buf.Length)
|
|
continue
|
|
}
|
|
|
|
if (Test-Path $filePath -PathType Container) {
|
|
$index = Join-Path $filePath "index.html"
|
|
if (Test-Path $index) { $filePath = $index } else {
|
|
$response.StatusCode = 404
|
|
$buf = [Text.Encoding]::UTF8.GetBytes("404 Not Found")
|
|
$response.OutputStream.Write($buf, 0, $buf.Length)
|
|
continue
|
|
}
|
|
}
|
|
|
|
if (-not (Test-Path $filePath -PathType Leaf)) {
|
|
$response.StatusCode = 404
|
|
$buf = [Text.Encoding]::UTF8.GetBytes("404 Not Found: $rawPath")
|
|
$response.OutputStream.Write($buf, 0, $buf.Length)
|
|
continue
|
|
}
|
|
|
|
Send-File $context $filePath
|
|
}
|
|
catch {
|
|
$response.StatusCode = 500
|
|
$msg = [Text.Encoding]::UTF8.GetBytes($_.Exception.Message)
|
|
$response.OutputStream.Write($msg, 0, $msg.Length)
|
|
}
|
|
finally {
|
|
$response.Close()
|
|
}
|
|
}
|