ワンライナーWebサーバを集めてみた

# ワンライナーWebサーバを集めてみた

クライアントサイドのJavaScriptをいじっていて，不意にローカルファイルでは実行できない領域に踏み込んでしまうことがあると思います．最近では，HTTPSが必須であったり，HTTP2を使ってみたくなることもあります．とりあえず私が踏み込んでしまったのはWebWorkersですが，他にもWebRTCや・・・（思い出し中）・・・（見つからなかった）・・・などが該当します．

そんな時にいちいちApacheやnginxを立ち上げるのも面倒なので，ちょっと検索した結果を残しておきます．

[2018/4/18追記] 最近ではHTTPSを使用する必要が高まっています．これを受け，HTTPSに対応する方法が増えてきたので，全て網羅できませんが，可能な限り追記・変更を行いました．

## Python（SimpleHTTPServer）編

Pythonでは（バージョン2.4以降限定らしいですが）モジュールをスクリプトとして実行する"-m"オプションが追加されました．このオプションを使って，標準ライブラリの一つであるSimpleHTTPServerをワンライナーで実行します．起動例とアクセスログを示します．標準ポート番号は8000です．

```bash:8000番ポートで待ち受けする例
$  python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
127.0.0.1 - - [09/Jan/2014 11:21:09] "GET / HTTP/1.1" 200 -
```

きちんとアクセスログが残るのが良いですね．ポート番号を変更したい場合は，末尾にポート番号を指定してください．

```bash:3000番ポートで待ち受けする例
$  python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...
```

参考：[コマンド1つで今すぐWebサーバを起動させるためのワンライナー(Ruby or Python)](http://d.hatena.ne.jp/rx7/20090812/p1)

## Python3.x編

試していませんが，Python3.x系であれば以下のようにしても動作するそうです．

```bash:8000番ポートで待ち受けする例
$ python -m http.server 8000
```

参考：[ワンライナーでWebサーバ](http://tmkoike.hatenadiary.jp/entry/2013/04/19/002532)

## Ruby（WEBRick）編

Rubyにもwebrickというライブラリが標準添付されているので，これを使ってWebサーバを立てることができます．以下の例ではドキュメントルートとポート番号（8000）しか指定していませんが，その他の設定も行えます．標準ポート番号は80です．ポート番号を指定しない場合，管理者権限がないとエラーで止まるので注意してください．

```bash:8000番ポートで待ち受けする例
$ ruby -rwebrick -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000).start'
[2014-01-09 13:49:12] INFO  WEBrick 1.3.1
[2014-01-09 13:49:12] INFO  ruby 1.9.3 (2013-06-27) [x86_64-darwin12.4.0]
[2014-01-09 13:49:12] INFO  WEBrick::HTTPServer#start: pid=9479 port=8000
localhost - - [09/Jan/2014:13:49:15 JST] "GET / HTTP/1.1" 200 2377
- -> /
```

こちらもアクセスログが残るのが良いですね．

~~※停止する場合はkillコマンドに-KILLオプションを使ってください．~~
先ほど試したら，ctrl+Cで停止できました．

```bash:昔の停止方法（今はctrl+Cで止まります）
$ ps aux | grep ruby
webrickのプロセス番号を調べて
$ kill -KILL プロセス番号
```



参考：[コマンド1つで今すぐWebサーバを起動させるためのワンライナー(Ruby or Python)](http://d.hatena.ne.jp/rx7/20090812/p1)

## Ruby（WEBRick）でHTTPS編

久しぶりにWEBRickを調べてみたところ，簡単にHTTPSに対応できることが分かりました．以下の例では証明書を自動生成した上で，8000番ポートで待受をします．※HTTPS専用です．HTTPでは接続できません．

```bash:8000番ポートでHTTPSで待ち受けする例
$ ruby -rwebrick -rwebrick/https -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000, :SSLEnable => true, :SSLCertName => [["CN", WEBrick::Utils::getservername]] ).start'
[2016-06-01 14:10:36] INFO  WEBrick 1.3.1
[2016-06-01 14:10:36] INFO  ruby 2.1.4 (2014-10-27) [x86_64-darwin14.0]
................................................................................................................++++++
....++++++
[2016-06-01 14:10:36] INFO
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=sahara.local
        Validity
            Not Before: Jun  1 05:10:36 2016 GMT
            Not After : Jun  1 05:10:36 2017 GMT
        Subject: CN=sahara.local
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:b7:e4:37:9e:86:40:dd:cb:01:b2:a7:a8:53:db:
                    42:e8:81:0f:a9:23:63:d9:6c:6a:6a:13:0f:bc:66:
                    ed:ac:04:6c:93:1d:82:7b:22:6f:11:fc:cd:b7:ab:
                    a8:6b:fc:fc:60:e8:18:cc:52:95:b4:1a:aa:8c:1e:
                    01:cb:fa:14:0b:03:f0:3e:9e:d2:d4:5d:44:b2:83:
                    e4:de:49:5c:37:7d:1a:2b:97:a7:82:e9:d9:cb:c0:
                    fa:f5:5b:92:54:29:5c:e4:fe:c4:ed:a0:2f:3b:da:
                    83:09:e2:12:d8:01:84:9f:60:80:9c:5a:1b:12:70:
                    be:97:e1:3c:34:b6:fd:80:29
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Key Usage:
                Key Encipherment
            X509v3 Subject Key Identifier:
                00:0C:DD:F6:BD:66:22:72:82:DA:82:20:9C:54:E6:12:64:5E:90:15
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            Netscape Comment:
                Generated by Ruby/OpenSSL
            X509v3 Authority Key Identifier:
                keyid:00:0C:DD:F6:BD:66:22:72:82:DA:82:20:9C:54:E6:12:64:5E:90:15
                DirName:/CN=sahara.local
                serial:01

    Signature Algorithm: sha1WithRSAEncryption
         5b:ae:8f:06:7f:07:a2:ff:25:f1:4e:b6:04:c7:9f:fb:e0:aa:
         54:3d:b8:ab:54:a5:cf:e0:94:52:d1:e5:03:0e:8f:73:13:6f:
         34:f4:e7:88:93:9e:69:df:43:c2:33:5d:cc:48:4b:2a:84:48:
         a4:a2:7d:e8:e1:82:7e:3e:a4:23:34:c9:72:f3:5b:52:c7:41:
         6a:99:29:16:70:ee:bf:bd:d5:38:92:9b:0a:0d:9a:70:6f:a8:
         c3:18:60:df:73:45:41:29:3d:b3:6a:59:23:fe:1f:14:e0:cf:
         a1:db:09:50:06:7c:a3:81:95:c0:78:29:3c:71:ce:ac:aa:20:
         98:06
[2016-06-01 14:10:36] INFO  WEBrick::HTTPServer#start: pid=7246 port=8000
localhost - - [01/Jun/2016:14:10:55 JST] "GET / HTTP/1.1" 200 4257
- -> /
```

Webブラウザで接続しようとすると「この接続ではプライバシーが保護されません」（Chromeの場合）や「安全な接続ではありません」（Firefoxの場合）などの注意書きが表示されます．

Chromeの場合は「詳細設定」をクリックすると出てくる「localhostにアクセスする（安全ではありません）」をクリックすることで，ページを表示できます．

Firefoxの場合はちょっと複雑で，「エラー内容」をクリックすると出てくる「例外を追加」をクリックし，ダイアログ内の「セキュリティ例外を承認」をクリックすることで，このサイトを例外扱いできます．しかしその後，HTTPSサーバを再起動してしまうと，証明書が更新されてしまい接続を拒否されてしまいます（エラーコード: SEC_ERROR_REUSED_ISSUER_AND_SERIAL）．この場合，Firefoxに登録されている証明書を削除する必要があります．詳しくは参考2をご覧ください．

~~上記の方法では証明書を自動的に作成していますが，既存の証明書を利用することもできます．ワンライナーと呼ぶには長くなりすぎるので割愛しますが，詳しくは参考1をごらんください．~~

参考1がドメインごとなくなっており，タイトルで検索しても見つからなかったため，既存の証明書を利用する方法を追記します．

まずは秘密鍵と証明書を準備します．すでに証明書を持っている方は飛ばしてください．以下の例では手抜きをして国名だけJPとして，後の質問には答えていません．

```bash:秘密鍵と証明書の作成
$ openssl req -new -newkey rsa:2048 -sha256 -days 365 -nodes -x509 -keyout localhost.key -out localhost.crt
Generating a 2048 bit RSA private key
.............................................................+++
..............................................................................................................................................................+++
writing new private key to 'localhost.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
$ ls
localhost.crt	localhost.key
```

上記で作成した証明書，または別に作成した既存の証明書を利用してHTTPSに対応したWebサーバを起動します．ワンライナーとしては少し長いので，打ち間違えにお気をつけください．
※以下の例では，Webブラウザから秘密鍵や証明書にアクセスできてしまいます．DocumentRootに別のディレクトリを指定するか，秘密鍵と証明書を別のディレクトリに置くようにしてください．

```bash:8000番ポートでHTTPSで待ち受けする例
$ ruby -rwebrick -rwebrick/https -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000, :SSLEnable => true, :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.open("localhost.key").read), SSLCertificate: OpenSSL::X509::Certificate.new(File.open("localhost.crt").read), :SSLCertName => [["CN", WEBrick::Utils::getservername]] ).start'
[2018-04-18 03:30:53] INFO  WEBrick 1.3.1
[2018-04-18 03:30:53] INFO  ruby 2.3.1 (2016-04-26) [x86_64-darwin14]
[2018-04-18 03:30:53] INFO
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c7:92:94:c6:4b:1f:75:65
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Some-State, O=Internet Widgits Pty Ltd
        Validity
            Not Before: Apr 17 18:23:43 2018 GMT
            Not After : Apr 17 18:23:43 2019 GMT
        Subject: C=JP, ST=Some-State, O=Internet Widgits Pty Ltd
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c3:c7:93:ee:fb:00:4f:b1:b4:6a:8d:b8:13:7e:
                    b0:f9:7e:63:43:21:40:1c:c2:2e:ce:f4:fa:68:37:
                    03:8b:1b:e1:c3:de:3c:4e:23:d3:9b:b8:78:d3:47:
                    3c:78:1f:fb:97:43:d3:ec:6f:8d:56:ee:c1:5a:16:
                    a7:84:91:bf:c3:79:e2:d4:33:cd:f3:b5:7d:5b:55:
                    d2:ef:3f:f8:9d:fe:e1:28:04:24:2d:5a:ef:dd:cc:
                    10:ba:2e:d8:ed:65:61:5b:95:1a:11:5c:1a:c3:1d:
                    76:5f:b2:c8:05:66:88:e0:38:03:4b:fd:0a:51:2c:
                    9f:3e:ff:f0:40:66:02:ba:b5:14:d2:c9:09:3a:c0:
                    c3:40:6a:2f:6c:ed:6b:e1:72:f2:19:c2:41:7a:9c:
                    fb:83:81:ab:df:a1:3b:db:29:b1:4d:a6:89:43:28:
                    17:2a:ee:77:47:60:52:66:fa:08:e4:e5:ec:0e:cd:
                    33:1d:e9:86:81:c3:66:d3:40:63:62:f1:da:83:8a:
                    8a:e9:fd:c5:7b:11:13:d6:9a:74:ef:5b:aa:ac:19:
                    59:8d:a6:ae:22:95:c8:b5:5f:05:bd:09:5d:df:6c:
                    09:b0:9f:22:7f:81:ee:4f:42:5c:e9:4c:7e:0c:75:
                    1b:b3:14:4d:32:cf:86:28:0a:a5:d1:f5:64:b6:5f:
                    26:e1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                A7:A1:32:FD:43:80:05:EC:F0:1B:41:0C:3B:0A:05:DE:46:F1:B5:32
            X509v3 Authority Key Identifier:
                keyid:A7:A1:32:FD:43:80:05:EC:F0:1B:41:0C:3B:0A:05:DE:46:F1:B5:32
                DirName:/C=JP/ST=Some-State/O=Internet Widgits Pty Ltd
                serial:C7:92:94:C6:4B:1F:75:65

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         2b:b0:86:47:9f:29:d0:2d:99:85:7f:52:fd:46:af:5a:ef:97:
         de:98:da:ab:a6:97:4b:3a:16:06:52:ad:ec:9d:37:47:1d:af:
         3d:59:11:43:ca:2e:24:77:88:d3:68:67:cb:53:72:d9:c2:d5:
         a2:26:00:34:26:63:db:1b:86:63:4f:94:ac:20:ee:07:07:67:
         ad:50:67:3a:fa:b8:0a:56:10:9f:e6:c2:80:df:6d:42:2e:cf:
         91:ff:2e:de:02:5a:63:5c:45:0c:e7:8a:0c:a5:42:4d:09:1c:
         1f:c1:28:6b:5e:2e:98:fd:65:d5:83:43:c4:2b:72:f4:61:ca:
         d5:8a:65:4d:10:bd:6b:0a:ce:b5:ea:86:8e:cc:18:61:87:88:
         b0:26:e0:42:22:75:e6:36:12:19:79:52:76:5c:94:f4:3b:7a:
         1e:16:5d:ea:28:1b:a8:b3:f8:aa:49:05:c5:07:f8:5c:7f:99:
         96:cf:f6:d5:71:8d:37:40:94:06:82:d0:d1:67:49:93:1c:29:
         7f:85:18:12:83:4a:0c:95:08:8e:19:e6:07:4a:9e:a1:35:81:
         a6:65:35:d9:ea:a0:cd:b8:6a:c8:f9:fe:0f:b5:1e:bd:df:48:
         64:f1:bb:a4:b6:97:cc:75:fc:40:a5:4c:e9:6b:e4:9a:2f:a0:
         36:d8:39:f8
[2018-04-18 03:30:53] INFO  WEBrick::HTTPServer#start: pid=10166 port=8000
::1 - - [18/Apr/2018:03:30:55 JST] "GET / HTTP/1.1" 200 1996
- -> /
```



~~参考1：[WEBrickでSSLを有効にする](http://labs.appshelf.info/2011/06/01/256/)~~
参考2：[他と同じシリアル番号をもつサーバ証明書](https://support.mozilla.org/ja/kb/%E4%BB%96%E3%81%A8%E5%90%8C%E3%81%98%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E7%95%AA%E5%8F%B7%E3%82%92%E3%82%82%E3%81%A4%E3%82%B5%E3%83%BC%E3%83%90%E8%A8%BC%E6%98%8E%E6%9B%B8)

## Ruby（Sinatra）編

Rubyには，Sinatraフレームワークがあり，こちらを使ってワンライナーでWebサーバを立てることもできます．起動例とアクセスログを示します．標準ポート番号は4567です．Sinatraの書式に則れば複雑なURLも処理してくれますが，以下の例だとindex.htmlを無視して"Hello World"を返してしまいます．

```bash:4567番ポートで待ち受けする例
$ ruby -rsinatra -e 'set :public_folder, "./", get("/"){"Hello world"}'
== Sinatra/1.4.2 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop
127.0.0.1 - - [09/Jan/2014 13:56:05] "GET / HTTP/1.1" 200 11 0.0025
```

ポート番号を指定する場合は，以下のようにしてください．

```bash:8000番ポートで待ち受けする例
$ ruby -rsinatra -e 'set :port, 8000; set :public_folder, "./", get("/"){"Hello world"}'
```

参考：[ワンライナーでウェブサーバを起動する方法](http://mojavy.com/blog/2012/07/18/one-line-webserver/)

※この方法ではlocalhostからしか接続できないようです．外部から接続したい場合は以下のようにproduction環境であることを明示してください．

```bash:他のホストからも受け入れる例
ruby -rsinatra -e 'set :port, 8000; set :public_folder, "./"; set :environment, :producntion; get("/"){"Hello world"}'
```

参考：[Sinatraがデフォルトでは外部から繋がらなくなってたよ](http://qiita.com/u1_fukui/items/b86b21f6ed39f4c10d5d)


## PHP編

PHP 5.4.0からWebサーバの機能が組み込まれるようになりました（tadsan様，情報提供ありがとうございました）．ドキュメントによると，「デモやテストに使ってね」とのことですが，本投稿の用途にはピッタリです．以下の例では8000番ポートを利用するように起動しています．ホスト名やポート番号は省略できません．

```bash:localhostからのみ受け付ける例
$ php -S localhost:8000
PHP 5.4.17 Development Server started at Thu Jan  9 17:35:44 2014
Listening on http://localhost:8000
Document root is /hoge
Press Ctrl-C to quit.
[Thu Jan  9 17:35:48 2014] ::1:59299 [404]: / - No such file or directory
```

Ruby（Sinatra）編と同様，このままではlocalhost以外から接続できません．他のホストから接続したい場合はホスト名として以下のように「0.0.0.0」を指定して起動してください．

```bash:他のホストからも受け入れる例
$ php -S 0.0.0.0:8000
```

参考：[ビルトインウェブサーバー](http://www.php.net/manual/ja/features.commandline.webserver.php)

##Ruby（unライブラリ）編

これまでノーチェックだったのですが，Rubyでも簡単にWebサーバを立てることができます（ 
yoshi-taka様，情報提供ありがとうございました）．ドキュメントによるとUnixの基本コマンドの代替となるユーティリティであるunライブラリの一部で，実際に起動するのはWEBRickのようです．以下の例ではカレントディレクトリをドキュメントルートとし，8000版ポートを利用するように起動しています．アクセスログはベースとなっているWEBRickと同じですね．ポート番号を省略すると80番ポートで起動しようとします．先に紹介したRuby（WEBRick編）と比べて「コマンドが短い」「ctrl+Cで終了できる」ことが利点です．

```bash:8000版で待ち受けする例
$ ruby -run -e httpd . -p 8000
[2014-03-01 11:03:36] INFO  WEBrick 1.3.1
[2014-03-01 11:03:36] INFO  ruby 2.0.0 (2013-06-27) [universal.x86_64-darwin13]
[2014-03-01 11:03:36] INFO  WEBrick::HTTPServer#start: pid=825 port=8000
localhost - - [01/Mar/2014:11:03:49 JST] "GET /test.html HTTP/1.1" 200 94937
- -> /test.html
```

参考：[library un - Ruby](http://docs.ruby-lang.org/ja/2.1.0/library/un.html)
参考：[httpd (Object) - APIdock](http://apidock.com/ruby/Object/httpd)

##Python（CGIHTTPServer）編

Python界隈ではスタティックなWebページだけでは満足できずに，CGIすらワンライナーで動かすことのできるライブラリが存在するようです（mash76様，情報提供ありがとうございました）．ライブラリの名前ですが，その名もズバリCGIHTTPServerとのことです．調べてみるとSimpleHTTPServerを継承して，さらにCGIに対応したとのことです．
それでは事前準備としてCGIスクリプトを用意します．CGIスクリプトはカレントディレクトリのcgi-binに入れておいてください．以下の例ではpythonを使っていますが，他の言語でも実行可能です．

```bash:CGIの準備
$ mkdir cgi-bin
$ cd cgi-bin
$ cat > index.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
文字列(hello world.)を表示する
'''
print "Content-Type: text/plain"
print
print "hello world."
^D  （←コントロール+Dを押してください）
$ chmod 755 index.py
$ cd ..
$ tree
.
└── cgi-bin
    └── index.py
```

それでは起動してみます．以下の例ではカレントディレクトリをドキュメントルートとして起動します．なお，ポート番号を省略すると8000番ポートを利用します．なお，ctrl+Cで修了できますが，終了時にエラーメッセージが出てくるので心の準備をしておいてください．

```bash:標準（8000番）ポートで待ち受けする例
$ python -m CGIHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
127.0.0.1 - - [02/Dec/2015 12:53:38] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [02/Dec/2015 12:53:39] code 404, message File not found
127.0.0.1 - - [02/Dec/2015 12:53:39] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [02/Dec/2015 12:53:47] "GET /cgi-bin/index.py HTTP/1.1" 200 -
```

ポート番号を指定する場合は以下のようにしてください．

```bash:9000番ポートで待ち受けする例
$python -m CGIHTTPServer 9000
```

##Perl編

PerlでもワンライナーWebサーバがあるとの情報を頂きました（xtetuji様，情報提供ありがとうございました）．個人的にPerlをほとんど使っていなかったので，インストール方法から記述したいと思います．

```bash:cpanの設定とPlackのインストール
$ cpan
（結構長いです．インストール先など，いくつか質問されるので適切に入力する．私は全て標準的な設定でよかったのでEnterを押しました．最後に起動スクリプトに環境変数を設定して良いか聞かれます．）
$ sudo cpan Task::Plack
（こちらも結構長いです．必要なモジュールなどをダウンロードします．待たされた後，標準的なインストールで良いか聞かれるので適切に答えてください．私はYを選択しました．また，最初にsudo無しで実行したらPermission Deniedと表示されたのでsudoを付けています．）
```

それでは5000番ポートで待ち受けするように実行してみましょう．ちょっとコマンドラインが長いですが，ドキュメントルートも容易に変更できます．

```bash:PerlによるワンライナーWebサーバの起動
$ plackup -MPlack::App::Directory -e 'Plack::App::Directory->new({root=>$ENV{PWD}})->to_app'
HTTP::Server::PSGI: Accepting connections at http://0:5000/
127.0.0.1 - - [02/Dec/2015:14:01:01 +0900] "GET / HTTP/1.1" 200 31580 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
127.0.0.1 - - [02/Dec/2015:14:01:02 +0900] "GET /favicon.ico HTTP/1.1" 404 9 "http://localhost:5000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
```

参考：[Plack入門:Plackでウェブサーバを起動してhello worldするまで](http://dqn.sakusakutto.jp/2011/08/plackplackhello_world.html)

## node.js（http-server）編

###その1. http-serverをグローバルインストール

node.jsにもワンライナーWebサーバがあるようです．ということでhttp-serverを紹介します．node.jsのインストールが済んでいるものとして説明します．まずはhttp-serverのインストールからです．

```bash:グローバルインストールの例
$ npm install -g http-server
```

ドキュメントルートは，publicディレクトリが有ればそちらに，publicが無ければカレントディレクトリになります．今，下記のようなディレクトリ構成であるものとします．

```text:ディレクトリ構成の例
.
└── public
    └── index.html
```

上記の「.」に相当するディレクトリから，標準ポート（8080番）を利用するように起動します．

```bash:8080番ポートで待ち受けする例
$ http-server
Starting up http-server, serving ./public
Available on:
  http:127.0.0.1:8080
  http:192.168.0.1:8080 （←localhost以外でも待ち受けします）
Hit CTRL-C to stop the server
[Wed, 02 Dec 2015 04:10:35 GMT] "GET /" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
```

ポート番号を変更するには```-p```オプションを利用します．

```bash:8000番ポートで待ち受けする例
$ http-server -p 8000
Starting up http-server, serving ./public
Available on:
  http:127.0.0.1:8000
  http:192/168/0.1:8000
Hit CTRL-C to stop the server
```

また，http-serverには起動と同時にWebブラウザを開くためのオプションが```-o```が有ります．以下のように実行すると，自動的にWebブラウザが開きます．（すでにWebブラウザが起動している場合，新しいタブで該当ページが開きます：chromeの場合）

```bash:ブラウザを同時に開く例
$ http-server -p 8000 -o
Starting up http-server, serving ./public
Available on:
  http:127.0.0.1:8000
  http:172.16.11.3:8000
Hit CTRL-C to stop the server
[Wed, 02 Dec 2015 05:10:59 GMT] "GET /" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
[Wed, 02 Dec 2015 05:11:00 GMT] "GET /favicon.ico" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36"
[Wed, 02 Dec 2015 05:11:00 GMT] "GET /favicon.ico" Error (404): "Not found"
```

http-serverは既存の秘密鍵と証明書を利用する方法でHTTPSに対応したようです．証明書などの作成方法は[Ruby（WEBRick）でHTTPS編](https://qiita.com/sudahiroshi/items/e74d61d939f18779970d#rubywebrick%E3%81%A7https%E7%B7%A8)を御覧ください．以下は，秘密鍵と証明書を指定して，HTTPSで待ち受けを行う例です．
※HTTPではアクセスできません．HTTPSでアクセスしてください．

```bash:8000番ポートでHTTPで待ち受けを行う例
$ http-server -p 8000 -S -C localhost.crt -K localhost.key
Starting up http-server, serving ./public through https
Available on:
  https://127.0.0.1:8000
  https://192.168.1.3:8000
Hit CTRL-C to stop the server
```

参考1：[Node.jsのhttp-serverっていうコマンドラインのウェブサーバーが便利](https://firegoby.jp/archives/5706)
参考2:[http-server](https://github.com/indexzero/http-server)

###その2. http-serverをローカルインストール

上の例ではhttp-serverをグローバルインストールしましたが，場合によってはローカルインストールで済ませたい場合があると思います．そのような人のために，ローカルインストールについても説明したいと思います．ローカルインストールでは，モジュールがカレントディレクトリのnode_modules以下にインストールされるので，環境を汚染しません．それではさっそくインストールしてみましょう．

```bash:http-serverをローカルインストール
$ npm install http-server
http-server@0.8.5 node_modules/http-server
├── opener@1.4.1
├── corser@2.0.0
├── colors@1.0.3
├── http-proxy@1.12.0 (eventemitter3@1.1.1, requires-port@0.0.1)
├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10)
├── ecstatic@0.7.6 (url-join@0.0.1, he@0.5.0, mime@1.3.4, minimist@1.2.0)
├── union@0.4.4 (qs@2.3.3)
└── portfinder@0.4.0 (async@0.9.0, mkdirp@0.5.1)
$
```

続けてWebサーバの起動です．8000番ポートを利用するようにしています．

```bash:http-serverの起動
$ ./node_modules/.bin/http-server -p 8000
Starting up http-server, serving ./
Available on:
  http:127.0.0.1:8000
  http:192.168.0.1:8000
Hit CTRL-C to stop the server
```

コマンドが長いという人は，```npm bin```を併用してください（kaminaly様，ありがとうございました）．なお，```npm bin```の利点として，サブディレクトリに潜っていてもきちんと実行できます．以下の例では，あえてカレントディレクトリをpublicにした上で実行しています．

```bash:npmコマンドを併用したhttp-serverの起動
$ cd public　（←publicにcdしていても・・・）
$ $(npm bin)/http-server -p 8000　（←実行可能．※本来はこの行のみで実行）
Starting up http-server, serving ./
Available on:
  http:127.0.0.1:8000
  http:192.168.0.1:8000
Hit CTRL-C to stop the server
```

###その3. package.jsonを利用してローカルインストール

起動コマンドが長いという人は，以下の様なファイルを作成して，npmを活用してみてください．ポート番号を変更したい場合は6行目の-pの後ろの数値を変更してください．

```json:package.json
{
  "name": "web",
  "version": "1.0.0",
  "description": "シンプルなWebサーバ",
  "scripts": {
    "start": "http-server -p 8000"
  },
  "author": "suda",
  "license": "ISC",
  "dependencies": {
    "http-server": "^0.8.5"
  }
}
```

npmを利用してhttp-serverをインストールします．package.jsonの置いてあるディレクトリ内で以下のコマンドを叩いてください．

```bash:package.jsonに従ってモジュールをインストール
$ npm install
npm WARN package.json web@1.0.0 No repository field.
npm WARN package.json web@1.0.0 No README data
http-server@0.8.5 node_modules/http-server
├── opener@1.4.1
├── corser@2.0.0
├── colors@1.0.3
├── http-proxy@1.12.0 (eventemitter3@1.1.1, requires-port@0.0.1)
├── optimist@0.6.1 (wordwrap@0.0.3, minimist@0.0.10)
├── union@0.4.4 (qs@2.3.3)
├── portfinder@0.4.0 (async@0.9.0, mkdirp@0.5.1)
└── ecstatic@0.7.6 (url-join@0.0.1, he@0.5.0, mime@1.3.4, minimist@1.2.0)
$
```

続けてnpmを利用してWebサーバを起動します．package.jsonの"script"の"start"の項目が実行されます．なお，自動的に~~./node_modules/<パッケージ名>/binにパスが通った状態で~~```./node_modules/.bin```にパスが通った状態で実行されます（kaminaly様，ありがとうございました）．

```
$ npm start
> web@1.0.0 start /home/suda
> http-server -p 8000

Starting up http-server, serving ./public
Available on:
  http:127.0.0.1:8000
  http:192.168.0.1:8000
Hit CTRL-C to stop the server
```

package.jsonを作ってnpmで管理するのはいささか大げさな気がしますが，環境を破壊せずに使える上，初心者にとっては覚えることが少ないので良いという利点もあります．

## node.js（serve）編

http-serverに似たモジュールとしてserveがあることを教えていただきました（kaminaly様，ありがとうございました），ということでさっそく試してみようと思います．ここではグローバルインストールのみ説明していますが，ローカルインストールやpackage.jsonによるローカルインストールも可能です．
追記：serveの最新版（2018/4/18日現在バージョン6.5.5）に合わせて追記，変更しました．

```bash:グローバルインストールの例
$ npm install -g serve
```

続けて，カレントディレクトリをドキュメントルートとして，標準ポート（~~3000番~~5000番）を利用するように起動します．
※標準ポートが変更されました．


```bash:5000番ポートで待ち受けする例
$ serve

   ┌─────────────────────────────────────────────────┐
   │                                                 │
   │   Serving!                                      │
   │                                                 │
   │   - Local:            http://localhost:5000     │
   │   - On Your Network:  http://192.168.1.3:5000   │
   │                                                 │
   │   Copied local address to clipboard!            │
   │                                                 │
   └─────────────────────────────────────────────────┘
```

ポート番号を変更するには```-p```オプションを利用します．

```bash:8000番ポートで待ち受けする例
$ serve -p 8000

   ┌─────────────────────────────────────────────────┐
   │                                                 │
   │   Serving!                                      │
   │                                                 │
   │   - Local:            http://localhost:8000     │
   │   - On Your Network:  http://192.168.1.3:8000   │
   │                                                 │
   │   Copied local address to clipboard!            │
   │                                                 │
   └─────────────────────────────────────────────────┘
```

パスワード認証を掛けることもできるようになっていました．以下の例では，ユーザ名を```suda```，パスワードを```suda1234```として，認証付きサイトとして待ち受けを行います．ユーザ名などは，オプションではなく環境変数で設定します．

```bash:パスワード認証を付ける例
$ SERVE_USER=suda SERVE_PASSWORD=suda1234 serve --ah
th
   ┌─────────────────────────────────────────────────┐
   │                                                 │
   │   Serving!                                      │
   │                                                 │
   │   - Local:            http://localhost:5000     │
   │   - On Your Network:  http://192.168.1.3:5000   │
   │                                                 │
   │   Copied local address to clipboard!            │
   │                                                 │
   └─────────────────────────────────────────────────┘
```


参考：[serve](https://www.npmjs.com/package/serve)

## node.js（light-server）でHTTP2編

node.jsでは，http-serverやserve以外にlight-serverというモジュールががあることを教えていただきました（hatappo様，ありがとうございました）ので，こちらも試してみようと思います．ここではグローバルインストールのみ説明していますが，ローカルインストールやpackage.jsonによるローカルインストールも可能と思われます．（すみません，時間不足で試していません）

```bash:グローバルインストールの例
$ npm install -g light-server
```

続けて，カレントディレクトリをドキュメントルートとして，標準ポート（4000番）を利用するように起動します．

```bash:4000番ポートで待ち受けする例
$ light-server -s .
light-server is listening at http://0.0.0.0:4000
  serving static dir: .

GET /index.html 200 29.438 ms - -
```

ポート番号を変更するには```-p```オプションを利用します．

```bash:8000番ポートで待ち受けする例
$ light-server -s . -p 8000
light-server is listening at http://0.0.0.0:8000
  serving static dir: .
```

light-serverの面白いところに，ファイルの変更をウォッチして，変更があった場合に処理を行うことができることです．以下の例では，カレントディレクトリ以下にあるjsファイルとindex.htmlを監視し，もし変更が有れば```npm run build```を実行し，ファイルをリロードします．（hatappo様のコメントに有った例を使わせていただきました．重ね重ねありがとうございました）

```bash:JSファイルとindex.htmlを監視する例
$ light-server -s -w "**/*.js, index.html # npm run build # reload"
```

なお，-wオプションに続く文字列は，#で区切られており，先頭から```監視対象のファイル```，```変更時に実行する内容```，```リロードの有無```です．詳しくは参考URLをご覧ください．

**お薦め**：公式リポジトリのREADMEを眺めていたところ，HTTP2に対応（自動的にHTTPSにも対応）していることが分かりました．以下の例では，証明書を自動生成した上で4000版ポートで待ち受けを行います．なお，HTTPではアクセスできないので，必ずHTTPSでアクセスしてください．

```bash:4000版ポートでHTTP2で待ち受けする例
$ light-server -s . --http2
light-server is listening at https://0.0.0.0:4000
  serving static dir: .
```


参考：[light-server](https://github.com/txchen/light-server)

## ncコマンド編

ncコマンドはTCPやUDPを利用してコマンドラインからデータを送受信するツールです．このコマンドを使うことで，簡易的なWebサーバを立てることが可能です（と言いつつtukiyo3様のコメントを見て初めて知りました．ご指摘ありがとうございました）．

まずは返信する文字列をワンライナー内で指定する場合の実行方法です．返信する文字列を変更したい場合は\n\nの後ろを変更してください．以下の例では"hello"を返します．

```bash:8000番ポートで待ち受けする例
$ while :; do { echo -e 'HTTP/1.1 200 OK\n\nhello'; } | nc -l 8000; done
```

ファイルの内容を返信したい場合は，以下のように実行してください．以下の例ではindex.htmlの内容を返信します．

```bash:返信するファイルを指定する場合
$ while :; do { echo -e 'HTTP/1.1 200 OK\n\n'; cat index.html; } | nc -l 8000; done
```

参考1によると，Ctrl+Cでは停止できないとのことでしたが，手元のMacOS Xのbash上で実行したところ，停止できました（何故かzsh上で実行した場合は停止できませんでした）．確実に停止するようにしたい場合は同記事をご覧ください．

参考1：[nc コマンドで簡易HTTPサーバ](http://blog.livedoor.jp/sonots/archives/34703829.html)
参考2：[すぐに簡易Webサーバを起動したいとき](http://dev.classmethod.jp/etc/webserver/)