基本機能の実装にチャレンジ!
mount_procで機能追加
「第1回:WEBrickを使ってみよう!」で説明しましたが、WEBrickにはFileHandler以外にもCGIHandlerなどがあります。しかも標準で添付されているHandlerだけでなく、自分でHandlerを書くことで、さまざまな処理を実行させることができます。
ただし、Handlerを書くにはクラスを継承するなど、やや面倒です。Handlerを書くほどでもない場合は、mount_procという方法で手軽に機能を追加することができます。
HTTPServer#mountでは、第一引数にマウントするパスを取り、第二引数に処理するHandlerをとります。HTTPServer#mount_procでは、第一引数にマウントするパスを取り、第二引数に処理するメソッドをとります。第二引数の代わりにブロックを渡すこともできます。よってブロックに書いた処理が実行されるため、自分の好きな処理をするHTTPサーバーができます。
まずは、/echo以下にアクセスすると「Path: パス名」を表示するという、簡単な機能を書いてみましょう。コードは、ダウンロードファイルのhttpserver3.rbのようになります。ここで例えば、/echo/a/b/c/1/2にアクセスすると、画面にパスが表示されます。
では、mount_procで何をしているのか見てみましょう。アクセスしてきた情報は、WEBrick::HTTPRequest(http://www.ruby-lang.org/ja/man/html/WEBrick_HTTPRequest.html)のreqに入り、出力される情報はWEBrick::HTTPResponse(http://www.ruby-lang.org/ja/man/html/WEBrick_HTTPResponse.html)のresに蓄えられます。アクセスされたパスは、res.pathに入っています。Webブラウザに表示される内容は、res.bodyに設定します。
このmount_procでは、/echo以下にアクセスされた場合には、PATH:の後にパスを加えた文字列をres.bodyに設定しています。
これで、/echo以下の適当なURLにアクセスすると、そのパスを返す機能ができあがりました。図2は、HTTPRequestとHTTPResponseのメソッドです。
mount_procを使ってWebサーバーを作る
今度は、HTTPServlet::HTTPServlet::FileHandlerを使わないで、同じことをmount_procを使って実装してみましょう。
すべてのURLで、標準のHTTPServlet::HTTPServlet::FileHandlerではなく、mount_procを使うためには、マウント先に「/」を設定します。
このmount_procの中でURLから、それに相当するファイルを読み込み、それをレスポンスボディーに返すようにすることで、HTTPサーバーを実装します。
http://localhost:3000/test/sample1.htmlを開いた場合は、public_html/test/sample1.htmlのファイルを表示します。アクセスされたパスはWEBrick::HTTPRequest#pathに設定されています。このURLを開いた場合、パスに「/test/sample1.html」が設定されています。
これを元に、mount_procでWEBrick::HTTPServlet::FileHandlerと同じようにファイルをマウントするには、サンプルファイルhttpserver4.rbのようなmount_procを書きます。
このコードでは、req.pathを見て$docroot以下のファイルを読み込み、レスポンスボディーであるres.bodyに設定します。
これで、http://localhost:3000/index.htmlにアクセスすると、public_html/index.htmlが表示されます。