2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[memo] 簡易的なWebサーバーの起動方法

Last updated at Posted at 2023-02-23

はじめに

  • 静的コンテンツ用の簡易的な 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.htmlindex.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 でも動くようですね。

ちょっと手を入れると便利に使えそう? 試しに実装してみました。まだ修正するかも。

HttpServer.awk
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 サーバーを作ってみました。

参考にした記事

参考になるかもしれない記事

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?