Hello world with mruby on H2O

このブログのウェブサーバーにH2Oを使っています。

H2Oはデフォルトでmrubyに対応しており、これが最近気になっています。

楽しそう。

H2O x mrubyで人はどれだけ幸せになれるのか from Ichito Nagata

そこで、まずはHello Worldするところまでをやってみます。

その前に色々わからないので調べてみます。

mrubyとは

mrubyとは以下の特徴を持つ言語。

  • 組み込み機器やアプリケーションへの組み込みに最適化された軽量なruby
  • ほぼrubyと互換性がある(軽量化のため最低限の機能のみに絞っているのでrubyと全く同じ機能が使えるわけではない)

H2Oのドキュメントを読んで見る

次にH2Oのmrubyについてのドキュメントを読んでみます。

ドキュメントによると、mrubyによってユーザーが独自のロジックを実装できるようになるみたいです。独自のロジックの実装とは、ドキュメントの例に挙げられているように好きなアクセス制御を書いたりレスポンスの内容(ヘッダやレスポンスコードなど)をいじったりすることを指しているようです。

つまりApacheのmod_phpのような「Webサーバーでアプリを動かす」ことが目的ではなく、あくまで「Webサーバーの機能を柔軟に拡張する」のが目的なようです。

H2Oとmrubyの間はRackインターフェースを介してやりとりされるようです。

Rackインターフェースとは

callするとstatus、headers、bodyの3つの配列を返すRubyのオブジェクト(クラスではない)。environmentという1つの引数をとる。environmentとはHTTPリクエストヘッダなどを含むハッシュ。

つまり、mrubyを使ってH2Oの機能を拡張するには、Rackインターフェースの仕様に則って「mrubyでゴニョゴニョ処理した結果をstatus、headers、bodyに入れてH2Oに返す」ことをすれば良い?

やってみる

まだあんまりよくわかっていないけどとりあえずHello worldしてみまする。ドキュメントを見るとmrubyディレクティブはpathsレベル内に書くことができるとのこと。

以下のような設定を用意します。

  • ステータスコードは200
  • ヘッダにcontent-type: text/plainを入れる
  • ボディはHello h2o x mruby!
"blog.lorentzca.me:80":
  listen:
    port: 80
  paths:
    "/":
      mruby.handler: |
        Proc.new do |env|
          [200, {'content-type' => 'text/plain'}, ["Hello h2o x mruby!\n"]]
        end

設定したらH2Oをreloadします。

sudo systemctl reload h2o  

ブラウザでアクセスしてみると...。

できた!

今回はmruby.handlerディレクティブを使ってH2Oの設定ファイル内に直接mrubyのコードを書きましたが、mruby.handler-fileを使って外部ファイルとして参照することもできるようです。

感想

思ったより気軽に始められる。 ✨

まだあんまり理解できてないというか、どこまでmrubyやRackについて理解する必要があるのかもピンときていませんが、少しづつ勉強して複雑な操作をしていきながら慣れていきたい(๑•̀ㅂ•́)و✧

参考リンク

H2Oのドキュメント。

Rackについて。

実例。