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