h2o + mruby セットアップメモ
最近、h2o で mruby がサポートされたので、まずはコンパイルしてみた。
h2o は、@kazuho さんが作成されている HTTP/2 & HTTP/1.x 対応の高速な WEBサーバです。
環境
いつものごとく vagrant で。
- CentOS 7.1 (3.10.0-229.el7.x86_64)
- h2o 1.4.2
- mruby 1.1.0
手順
現状 h2o で mruby を利用する場合は、h2o と mruby のコンパイルを、別々に行わなければいけない(mod_mruby とかだとそのなかで mruby をビルドしてくれる)。
流れとしてはまず、libmruby.a を作成し、h2o コンパイル時にそれをリンクする感じ。
-
作業ディレクトリの作成
mkdir work cd $_
vagrant の共有フォルダ上は NG。vboxfs はハードリンクの作成ができないので h2o のビルドに失敗する。
-
mruby と h2o のコンパイルに必要なパッケージのインストール
sudo yum install -y git gcc bison ruby cmake openssl-devel
-
libmruby.a の作成(mruby のコンパイル)
git clone https://github.com/mruby/mruby.git cd mruby ./minirake
追加で利用したい mrbgems がある場合は、ここで設定しておく。
-
libmruby.pc の作成
h2o コンパイル時に、作成した libmruby.a 等を参照できるよう
libmruby.pc
(pkg-config 用の設定ファイル)を作成し、環境変数PKG_CONFIG_PATH
に登録しておく。cat <<EOD>build/host/lib/libmruby.pc prefix=$PWD libdir=\${prefix}/build/host/lib/ includedir=\${prefix}/include Name: libmruby Description: mruby libraries Version: 1.1.0 Libs: -L\${libdir} -lmruby Cflags: -I\${includedir} EOD
export PKG_CONFIG_PATH="$PWD/build/host/lib/"
-
h2o のコンパイル
cd .. # work 直下に移動 git clone https://github.com/h2o/h2o.git cd h2o git submodule update --init --recursive
$ cmake -DWITH_MRUBY=ON . -- The C compiler identification is GNU 4.8.3 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Found PkgConfig: /usr/bin/pkg-config (found version "0.27.1") -- Looking for include file pthread.h -- Looking for include file pthread.h - found -- Looking for pthread_create -- Looking for pthread_create - not found -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for pthread_create in pthread - found -- Found Threads: TRUE -- Found OpenSSL: /usr/lib64/libssl.so;/usr/lib64/libcrypto.so (found version "1.0.1e") -- checking for module 'libuv>=1.0.0' -- package 'libuv>=1.0.0' not found -- Could NOT find LIBUV (missing: LIBUV_LIBRARIES LIBUV_INCLUDE_DIR) -- checking for module 'libwslay' -- package 'libwslay' not found -- Could NOT find WSLAY (missing: WSLAY_LIBRARIES WSLAY_INCLUDE_DIR) -- checking for module 'libmruby' -- found libmruby, version 1.1.0 -- Configuring done -- Generating done -- Build files have been written to: /home/vagrant/work/h2o
$ make h2o : Linking C executable h2o [100%] Built target h2o $ ls -l h2o -rwxrwxr-x 1 vagrant vagrant 11680735 8月 4 22:39 h2o
動作確認
サンプルの conf で起動。
$ ./h2o -c ./examples/h2o_mruby/h2o.conf
[OCSP Stapling] failed to execute share/h2o/fetch-ocsp-response:No such file or directory
[OCSP Stapling] disabled for certificate file:examples/h2o/server.crt
[OCSP Stapling] failed to execute share/h2o/fetch-ocsp-response:No such file or directory
[OCSP Stapling] disabled for certificate file:examples/h2o/server.crt
[OCSP Stapling] failed to execute share/h2o/fetch-ocsp-response:No such file or directory
[OCSP Stapling] disabled for certificate file:examples/h2o/alternate.crt
[INFO] raised RLIMIT_NOFILE to 4096
[OCSP Stapling] failed to execute share/h2o/fetch-ocsp-response:No such file or directory
[OCSP Stapling] disabled for certificate file:examples/h2o/alternate.crt
h2o server (pid:27481) is ready to serve requests
curl でアクセス
# curl http://localhost:8080/
hello from h2o_mruby. User-Agent:curl/7.29.0 New User-Agent:new-curl/7.29.0-h2o_mruby path:/ host:localhost method:GET query: remote_ip:::1
hello 。
examples/h2o_mruby
ちなみに examples の conf 等はこんな感じだった。
# to find out the configuration commands, run: h2o --help
listen: 8080
listen:
port: 8081
ssl:
certificate-file: examples/h2o/server.crt
key-file: examples/h2o/server.key
hosts:
"127.0.0.1.xip.io:8080":
paths:
/:
file.dir: examples/doc_root
mruby.handler_path: examples/h2o_mruby/hello.rb
access-log: /dev/stdout
"alternate.127.0.0.1.xip.io:8081":
listen:
port: 8081
ssl:
certificate-file: examples/h2o/alternate.crt
key-file: examples/h2o/alternate.key
paths:
/:
file.dir: examples/doc_root.alternate
access-log: /dev/stdout
# paths:
# /:
# file.dir: examples/doc_root
# mruby.handler_path: /path/to/hello.rb
r = H2O::Request.new
h = "hello"
m = "from h2o_mruby"
ua = r.headers_in["User-Agent"].to_s
new_ua = r.headers_in["User-Agent"] = "new-#{ua}-h2o_mruby"
uri = r.uri
host = r.hostname
method = r.method
query = r.query
msg = "#{h} #{m}. User-Agent:#{ua} New User-Agent:#{new_ua} path:#{uri} host:#{host} method:#{method} query:#{query} remote_ip:#{H2O::Connection.new.remote_ip}"
r.log_error msg
H2O.return 200, "OK", msg + "\n"