はじめに
- 静的コンテンツ用の簡易的な Web サーバーを起動したいときのための個人的メモ
-
*.jsでファイルを読み込む等、file://では動かないような場合を想定 -
ncやその他で固定のコンテンツのみ返す、みたいなものはとりあえず除外
-
- cgi とか https とかはあまり重視しない
- 基本的に Linux/Unix 系の環境がメイン(動くなら Windows でもよい)
簡易Webサーバー
Python 3.x
python -m http.server 8000
- ディレクトリ指定時に
index.html等がない場合には、ファイル一覧を表示する - IP アドレスは
--bind ADDRで指定(3.4 以降追加でサポート / 3.8 以降で IPv6 もサポート) - port は引数で指定
- ドキュメントルートはカレント (3.7 以降は
--directory DIR形式で指定可能) - CGI を有効にするには
--cgiオプションが必要. フォルダーは/cgi-binと/htbin. 実行時の UID はnobodyを使う
Ruby
ruby -run -e httpd -- --port=8000 .
- ディレクトリ指定時に
index.html等がない場合には、ファイル一覧を表示する - IP アドレスは
--bind-address=ADDRで指定 - port は
--port=PORT - ドキュメントルートは引数で指定
- SSL/TLS 証明書を使って https 化も可能
PHP
php -S localhost:8000
- ディレクトリ指定時に
index.htmlやindex.phpがない場合には再帰的に親ディレクトリを探すが、最終的になければ404 Not Foundになる - IP アドレス、port は
-S ADDR:PORTで指定 - ドキュメントルートは
-t DIRで指定 - あたりまえだけど
*.phpファイルにも対応している
Java 18 以降
jwebserver -b ADDR -p PORT -d DIR
- IP アドレスは
-b ADDRで指定 - port は
-p PORTで指定 - ドキュメントルートは
-d DIRで指定
BusyBox
busybox httpd -f -p 8000
【参考】ヘルプメッセージ
$ busybox httpd --help
BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu6.4) multi-call binary.
Usage: httpd [-ifv[v]] [-c CONFFILE] [-p [IP:]PORT] [-u USER[:GRP]] [-r REALM] [-h HOME]
or httpd -d/-e/-m STRING
Listen for incoming HTTP requests
-i Inetd mode
-f Don't daemonize
-v[v] Verbose
-p [IP:]PORT Bind to IP:PORT (default *:80)
-u USER[:GRP] Set uid/gid after binding to port
-r REALM Authentication Realm for Basic Authentication
-h HOME Home directory (default .)
-c FILE Configuration file (default {/etc,HOME}/httpd.conf)
-m STRING MD5 crypt STRING
-e STRING HTML encode STRING
-d STRING URL decode STRING
-
-fをつけるとフォアグラウンドで動作 (付けないとデーモン化) - ディレクトリ指定時に
index.html等がない場合には404 Not Foundになる - IP アドレスと port は
-p [ADDR:]PORTで指定 - ドキュメントルートは
-h DIRで指定 -
/cgi-bin配下を CGI として扱う
雑多なメモ
動作確認していないものとか、もう古い情報とか
node.js + ライブラリ
http-server
インストール方法(以下はローカルにインストールする例)
npm install http-server
実行方法
npx http-server -p 8000
- IP アドレスは
-a ADDRで指定 - port は
-p PORTで指定 - ドキュメントルートは引数で指定. デフォルトは
./publicがあればそれを使う. なければカレントディレクトリを使う - SSL/TLS 証明書を使って https 化も可能
serve
インストール方法
npm install --global serve
実行方法
serve -p 8000
- IP アドレスは
-l URIで指定(なのかな?) - port は
-p PORTで指定 - ドキュメントルートは引数で指定. デフォルトはカレントディレクトリ
- SSL/TLS 証明書を使って https 化も可能
light-server
インストール方法
npm install light-server
実行方法
npx light-server -s . -p 8000
- IP アドレスは
-b ADDRで指定 - port は
-p PORTで指定 - ドキュメントルートは
-s DIRで指定
Python 2.4 以降
既に使わないと思うけど、念のため。
python -m SimpleHTTPServer 8000
VSCode拡張「Live Server」
PowerShell
Windows の場合 PowerShell で少しスクリプトを書くと、簡易的な Web サーバは作れるみたい。
動作確認はしていないけど、とりあえずメモ。
PowerShell で簡易 Web サーバを作ったよ、というページはほかにもいくつもありそう。
GNU Awk
GNU Awk はソケットも扱えるみたいなので、簡易 Web サーバも作れるようです。
↑この記事の下の方に、ワンライナーでの Web サーバが紹介されています。
ちょっとページが崩れているみたいなので、改めてソースを転載させてもらいます。
ついでにポート番号も 8000 に変更しました(元は 80 だった)。
ソースの転載
awk 'BEGIN{s="/inet/tcp/8000/0/0";"pwd" |& getline;r=$0;while((s |& getline) > 0){gsub(/[\r\n]/,"");if($0 ~ /^\s*$/){c="cat " r path;printf "HTTP/1.0 200 OK\r\n\r\n" |& s;while((c |& getline) > 0){print |& s}close(c);close(s)}else if($0 ~ /HTTP/){print;path=$2}}}'
改行を入れると以下のような感じですね。
BEGIN{
s="/inet/tcp/8000/0/0"
"pwd" |& getline
r=$0
while((s |& getline) > 0){
gsub(/[\r\n]/,"")
if($0 ~ /^\s*$/){
c="cat " r path
printf "HTTP/1.0 200 OK\r\n\r\n" |& s
while((c |& getline) > 0){
print |& s
}
close(c)
close(s)
}else if($0 ~ /HTTP/){
print
path=$2
}
}
}
おそらくは、ワンライナーに収めるためにかなり機能を限定しているようです。
- セキュリティチェックなどは入っていない(
GET /../../etc/passwd HTTP/1.0みたいなことができちゃいそう)常用は厳禁 -
/アクセスでindex.htmlを返す機能はない - Mime-Type なども返さない
最近の Git Bash (Git for Windows) に入っている Awk は GNU Awk 5.0 っぽいので、Git Bash が入っていれば Windows でも動くようですね。
ちょっと手を入れると便利に使えそう? 試しに実装してみました。まだ修正するかも。
BEGIN {
if (port == "") port = "8000"
if (root == "") root = "."
BINMODE = 1
RS="\r\n"
socket = "/inet/tcp/" port "/0/0"
while((socket |& getline) > 0) {
print
path = root "/" $2
gsub(/\?.*$/, "", path)
if (path ~ /\/$/) path = path "index.html"
if ($1 != "GET" || $3 !~ /^HTTP\// || path ~ /\/\.\.\//) {
sendError("400 Bad Request")
close(socket)
continue
}
while((socket |& getline) > 0) if ($0 == "") break
RS = "^$" # never match regex
rc = getline content < path
close(path)
RS = "\r\n"
if (rc < 0) {
sendError("404 Not Found")
} else {
sendContent("200 OK", contextType(path), content)
}
close(socket)
}
close(socket)
exit(1)
}
function contextType(path) {
if (path ~ /\.html$/) return "text/html"
if (path ~ /\.js$/) return "text/javascript"
if (path ~ /\.css$/) return "text/css"
if (path ~ /\.txt$/) return "text/plain"
if (path ~ /\.xml$/) return "text/xml"
if (path ~ /\.png$/) return "image/png"
if (path ~ /\.jpg$/) return "image/jpeg"
if (path ~ /\.gif$/) return "image/gif"
if (path ~ /\.svg$/) return "image/svg+xml"
if (path ~ /\.json$/) return "application/json"
if (path ~ /\.zip$/) return "application/zip"
return "application/octet-stream"
}
function sendError(code) {
sendContent(code, "text/plain", code "\r\n")
}
function sendContent(code,type,content) {
print "HTTP/1.0 " code
printf "HTTP/1.0 %s\r\n",code |& socket
printf "content-type: %s\r\n",type |& socket
printf "\r\n" |& socket
printf "%s",content |& socket
}
実行時には awk -f HttpServer.awk みたいな感じです。
ポート番号を変更するには awk -v port=3000 -f HttpServer.awk みたいに -v port=PORT を指定してください。
気になる点。
-
GETメソッドしかサポートしていない。-
HEADぐらいはサポートしないとまずい? - エラーも
400 Bad Requestになっている。501 Not Implementedが正しい?
-
- ディレクトリを
/無しで指定された場合に404 Not Foundになる。- 本当は
301 Moved Permanentlyで/有りに振り向けるのが正しい気がする
- 本当は
- URLエンコードされたパスに対応していない
C# (Windows 標準のコンパイラ使用)
Windows ではデフォルトで C# のコンパイラが入っているみたいなので、それで簡易 Web サーバーを作ってみました。
参考にした記事
参考になるかもしれない記事