WEBRickでWebサーバを立ち上げて同一LAN内のパソコンからアクセスする

## 動機
フレームワーク無しでもWEBRickで簡単にWebサーバが作れるというのを読んで、面白そうだったので手元で試してみます。以下、忘れないようにするための記録です。

## WEBRickでWebサーバーを立ち上げる(まずはローカル専用)
WEBRickについて詳しいことはこちらを見つつ。

https://docs.ruby-lang.org/ja/latest/library/webrick.html

↑これを見ると、
> WEBrick は Ruby 3.0 で標準ライブラリから削除されました。Ruby 3.0 以降で WEBrick を使いたい場合は rubygems から利用してください。

とのことなので、gem installしておきます。

```zsh
$ gem install webrick
```

次に、適当なディレクトリを作ってファイルを作成します。

```server.rb
require 'webrick'
options = { BindAddress: '127.0.0.1', Port: '10080', DocumentRoot: '.' }
server = WEBRick::HTTPServer.new(options)
trap(:INT) { server.shutdown } # Signal.trap(:INT) { server.shutdown } でも同じ
server.start
```

Webサーバオブジェクト(つまり[WEBRick::HTTPServer](https://docs.ruby-lang.org/ja/latest/class/WEBrick=3a=3aHTTPServer.html)のインスタンス)は[startメソッド](https://docs.ruby-lang.org/ja/latest/method/WEBrick=3a=3aGenericServer/i/start.html)を持ち、これが最終的にWebサーバを起動させます。
Webサーバオブジェクトは、[WEBRick::HTTPServer.new(options)](https://docs.ruby-lang.org/ja/latest/class/WEBrick=3a=3aHTTPServer.html#S_NEW)で作成しています。
optionsとしてはとりあえず`BindAddress`, `Port`, `DocumentRoot`の3項目を渡せば動くそうです。他の項目については[るりま](https://docs.ruby-lang.org/ja/latest/class/WEBrick=3a=3aHTTPServer.html#S_NEW)にまとまっていました。
`BindAddress`に`127.0.0.1`を渡せばローカル専用のWebサーバになり、`0.0.0.0`を渡せばLAN内に公開されたWebサーバになります。
`trap(:INT)`の行で、`ctrl+c`が入力された時の動作を指定しています。ここでは`server.shutdown`でサーバーを止めています。(この行を書いていないと`ctrl+c`で止められません。`ps aux | grep webrick`でプロセスidを調べてkillするとか)

あとはこのファイルを実行すればWebサーバが立ち上がります。

```zsh
$ ruby server.rb
#[2021-10-31 18:09:13] INFO  WEBrick 1.7.0
#[2021-10-31 18:09:13] INFO  ruby 3.0.2 (2021-07-07) [x86_64-darwin20]
#[2021-10-31 18:09:13] INFO  WEBrick::HTTPServer#start: pid=23294 port=10080
```

curlでアクセスしてみます。

```
$ curl http://127.0.0.1:10080
# (以下結果)                                                   
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
  <HEAD>
    <TITLE>Index of /</TITLE>
    <style type="text/css">
    <!--
    .name, .mtime { text-align: left; }
    .size { text-align: right; }
    td { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
    table { border-collapse: collapse; }
    tr th { border-bottom: 2px groove; }
    //-->
    </style>
  </HEAD>
  <BODY>
    <H1>Index of /</H1>
<TABLE width="100%"><THEAD><TR>
<TH class="name"><A HREF="?N=D">Name</A></TH><TH class="mtime"><A HREF="?M=D">Last modified</A></TH><TH class="size"><A HREF="?S=D">Size</A></TH>
</TR></THEAD>
<TBODY>
<TR><TD class="name"><A HREF="..">Parent Directory</A></TD><TD class="mtime">2021/10/31 18:19</TD><TD class="size">-</TD></TR>
<TR><TD class="name"><A HREF="webrick227.rb">webrick227.rb</A></TD><TD class="mtime">2021/10/31 18:19</TD><TD class="size">375</TD></TR>
</TBODY></TABLE><HR>    <ADDRESS>
     WEBrick/1.7.0 (Ruby/3.0.2/2021-07-07)<BR>
     at 127.0.0.1:10080
    </ADDRESS>
  </BODY>
</HTML>
```
Indexページのhtmlが返ってきました！
curlで指定したのと同じurlをブラウザで開くと...あれ？
![スクリーンショット 2021-10-31 18.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252684/12ef38aa-bee1-53ac-d69f-46650caa02b6.png)
### 10080番ポートはブラウザで見られない
`ERR_UNSAFE_PORT`と書いてあります。調べるとどうやら、ブラウザが最近10080番ポートのサイトを見られないようにしているようです。

https://zenn.dev/ota42y/articles/127fee3353bafe

素直に10080番を避けて、`options`の`Port`に指定するのを`20080`とかにしてみます。

```server.rb
# 省略
options = { BindAddress: '127.0.0.1', Port: '20080', DocumentRoot: '.' }
# 省略
```
urlは http://127.0.0.1:20080 になります。
するとこんな画面になりました。
↓
![スクリーンショット 2021-10-31 22.09.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252684/d1a5e572-9df3-029b-10af-0cf3fbdb269b.png)
`options`の`DocumentRoot`で指定したディレクトリに`index.html`というファイルがなければ、この画面になります。([ホームページにアクセスすると「index of/」と表示され、ファイルが一覧で表示されてしまう](https://support.yahoo-net.jp/PccHostingupper/s/article/H000004839))
今回は`DocumentRoot`にはカレントディレクトリ(`'.'`)を指定しているので、`server.rb`と同じ階層に`index.html`を作成して中身を適当に用意してみます。

```index.html
<h1>Hello World!</h1>
```
ブラウザでさっきと同じurl( http://127.0.0.1:20080 )にアクセスすると...
![スクリーンショット 2021-10-31 22.32.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252684/f2e8851a-5c5b-437a-c1a9-15492c182477.png)
先ほどの`Index of /`という画面ではなく、`index.html`の中身が表示されるようになりました！


## WebサーバをLAN内に公開する
上で書いたように、`options`の`BindAddress`に`127.0.0.1`を渡せばローカル専用のWebサーバになり、`0.0.0.0`を渡せばLAN内に公開されたWebサーバになります。
(カフェなどの公共のLANに繋いでる時は危険なので試さないほうがいいと思います)

```server.rb
# 省略
options = { BindAddress: '0.0.0.0', Port: '20080', DocumentRoot: '.' }
server = WEBRick::HTTPServer.new(options)
# 省略
```

もう一度サーバを立ち上げ直します。

```
$ ruby server.rb
```

これで、同一LAN内の他のパソコンやスマホからでもアクセスできるようになっているはずです。
アクセスするには`127.0.0.1`の代わりに、プライベートIPアドレスを使います。もちろんポート番号(ここでは`20080`)も引き続き付ける必要があります。
urlは例えば`http://192.168.1.21:20080`のようになるはずです。

https://www.cman.jp/network/term/ip/p2/

これで、同じWi-Fiに繋いだ他の端末のブラウザにこのurlを打ち込むと、`index.html`の内容が見られました。
遊びでいろいろ使えそうな感じです。

繰り返しになりますが、公共のLANに繋いでる時は試さないほうがいいと思います。