Files
WD-HN/serve.ps1
2026-05-20 17:37:36 +07:00

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()
}
}