$base = Split-Path -Parent $MyInvocation.MyCommand.Path $listener = [System.Net.Sockets.TcpListener]::new([System.Net.IPAddress]::Loopback, 5501) $listener.Start() Write-Host "http://127.0.0.1:5501/" while ($true) { $client = $listener.AcceptTcpClient() try { $stream = $client.GetStream() $reader = New-Object System.IO.StreamReader($stream, [System.Text.Encoding]::ASCII, $false, 1024, $true) $writer = New-Object System.IO.StreamWriter($stream) $writer.AutoFlush = $true $requestLine = $reader.ReadLine() if (-not $requestLine) { $client.Close(); continue } while ($true) { $line = $reader.ReadLine(); if ($line -eq $null -or $line -eq "") { break } } $rawPath = "/" if ($requestLine -match "^GET\s+([^\s]+)") { $rawPath = $matches[1] } $pathOnly = $rawPath.Split("?")[0] $pathOnly = [System.Uri]::UnescapeDataString($pathOnly) $reqExt = [System.IO.Path]::GetExtension($pathOnly) if ($pathOnly -like "/search/*" -and [string]::IsNullOrEmpty($reqExt)) { $file = Join-Path $base "search.html" } elseif ($pathOnly -eq "/") { $file = Join-Path $base "index.html" } else { $rel = $pathOnly.TrimStart("/"); $file = Join-Path $base $rel } if (-not (Test-Path $file)) { $status = "404 Not Found" $body = [System.Text.Encoding]::UTF8.GetBytes("Not Found") $contentType = "text/plain; charset=utf-8" } else { $status = "200 OK" $body = [System.IO.File]::ReadAllBytes($file) $ext = [System.IO.Path]::GetExtension($file).ToLower() switch ($ext) { ".html" { $contentType = "text/html; charset=utf-8" } ".css" { $contentType = "text/css" } ".js" { $contentType = "application/javascript" } ".png" { $contentType = "image/png" } ".jpg" { $contentType = "image/jpeg" } ".jpeg" { $contentType = "image/jpeg" } ".svg" { $contentType = "image/svg+xml" } ".json" { $contentType = "application/json" } ".ico" { $contentType = "image/x-icon" } default { $contentType = "application/octet-stream" } } } $writer.WriteLine("HTTP/1.1 $status") $writer.WriteLine("Content-Type: $contentType") $writer.WriteLine("Content-Length: " + $body.Length) $writer.WriteLine("Connection: close") $writer.WriteLine("") $stream.Write($body, 0, $body.Length) } catch { try { $client.Close() } catch {} } finally { try { $client.Close() } catch {} } }