概要
PowerShellを使って、ローカルWebサーバーを動かすスクリプトを作成した。
背景と目的
ある事情で、PowerShellを使って、ローカルWebサーバーを動かす必要が出たので、やり方を調べスクリプトを作成してみる。
詳細
0.調査
Web上の参考になったサイトをいくつか見つけた。
1.仕様
最低限動けばよい内容は、
だけとする。
2.実装
参考サイトほぼそのままであるが、ちょっと追加で実装。
# ポートとルートディレクトリ $port = 8080 $root = "ルートディレクトリのパス" # Ctrl+C用 [console]::TreatControlCAsInput = $true Write-Host "Simple Http Server start." # HTTP Serverのオブジェクトを建てる $listener = New-Object system.net.HttpListener $listener.Prefixes.Add('http://127.0.0.1:'+$port+'/') $listener.Start() while($true) { # Ctrl+C用 if ([console]::KeyAvailable) { $key = [system.console]::readkey($true) if (($key.modifiers -band [consolemodifiers]"control") -and($key.key -eq "C")) { "Terminating..." break } } # アクセス待ち $context = $listener.GetContext() # block $request = $context.Request #$request # debug # リクエスト先 $path = $root + $request.RawUrl.Replace("/", "\"); $path # レスポンス処理 $response = $context.Response if( Test-Path $path ) { # 要求されたURLに対応するコンテンツを返す "200 " + $request.RawUrl $page = (Get-Content -Path $path -Encoding UTF8) -join "`n" $buffer = [System.Text.Encoding]::UTF8.GetBytes($page) $ext = (Get-Item $path).Extension # 拡張子ごとにResponseのContent-Typeをつける if ($ext -eq ".html") { $response.ContentType = "text/html" } elseif ($ext -eq ".json") { $response.ContentType = "application/json" } else { $response.ContentType = "text/plain" } } else { # パスが存在しないとき "404 " + $request.RawUrl $path2 = $root + "\error.html" $page = (Get-Content -Path $path -Encoding UTF8) -join "`n" $buffer = [System.Text.Encoding]::UTF8.GetBytes($page) $response.ContentType = "text/html" } $response.ContentLength64 = $buffer.Length $output = $response.OutputStream $output.Write($buffer, 0, $buffer.Length) $output.Close() } $listener.Stop()
ちょっと工夫が必要だったのが、以下の部分。
- 改行コードをつける
$page = (Get-Content -Path $path -Encoding UTF8) -join "`n" $buffer = [System.Text.Encoding]::UTF8.GetBytes($page)
最後の-join "`n"は、ブラウザからアクセスする場合には重要。Get-Contentコマンドは、行で分割した配列としてファイル内容を取得するようなので、次の行のUTF8.GetBytesを実行する前に、改行コードで連結しておく。これをやらないと、手元のChromeでは正しく表示されなかった。
- Content-Typeをつける
htmlではなくても問題なかったが、クライアントアプリ上のjQueryなどでリクエストしてjsonを貰う場合は、つけてあるとブラウザ上で自動的にJSONオブジェクトに変換してくれた。ただし、拡張子ごとにつけないといけないので面倒。もっといい方法がありそうだ。。。
3.動作確認
以下のディレクトリにテスト用ファイルを配置。
C:\work\ test.html test.json
ブラウザで、以下URLにアクセスし、正しく表示された。
http://localhost:8080/test.html
jsonのほうは、Pythonで以下を実行し、正しく取得できた。
import requests resp = requests.get("http://localhost:8080/test.json") print(resp.text)
まとめと今後の課題
PowerShellを使って、ローカルWebサーバーを動かすスクリプトを作成できた。