はじめに
- 静的コンテンツ用の簡易的な 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 サーバーを作ってみました。
参考にした記事
参考になるかもしれない記事