picohttpparser の addon を書いてみた

はじめに

このエントリーは Node.js Advent Calendar 2014 - Qiitah2o Advent Calendar 2014 - Qiita の 21 日目の記事です。

現時点の node.js の安定版は v0.10.34、開発版は v0.11.14 で、v8 のバージョンはそれぞれ 3.14.5、3.26.33 です。 nan (Native Abstractions for Node.js) のバージョンは 1.4.1 です。

Motivation

以前も Node.js の http_parser の実装を追ってみたことがあって興味があったし、HTTP/2 を追うことでやはり parser に触れてきました。自分は普段は Rails のアプリケーションエンジニアをやっているので Ruby にも興味があります。そして以前は Perl も書いていました。なので @kazuho さんの作られた picohttpparser については耳にしていましたし、h2o で使われているのも知っていました。そんな中 Perl コミュニティで有名な @kazeburo さんが Ruby の C 拡張として pico_http_parser をリリースされました。前々から Node.js の addon は書いてみたかったので、この機会に Ruby の C 拡張の仕組みに触れつつ、picohttpparser の理解を深めるチャンスだと思いやってみました。

What's hard?

ほとんど @kazeburo さんの実装をそのまま使っていて、一部 Node.js の作法に合わせる形で実装しました。普段 C/C++ は書かないのでちょっとしたところでつまづきやすかったです。また nan が v8 のバージョン間の差異を埋めてくれるんですが、きちんと理解して使っていないのでトライアンドエラーで探り探りでした。結果としてまだ開発版での build が成功していないという体たらくです、すいません。

v8 のドキュメントは聞いた話だとソースコードから doxygen で生成するしかないとのことでした。doxygen をあまり使ったことがないのでドキュメントの生成の仕方がよくわからず、Eclipse でやってみたりしたんですがどうも狙ったバージョンのリファレンスが生成出来ず、現時点でバージョン間の差異をきちんと把握することが出来ていません。この辺詳しい方がいらっしゃったらぜひ教えていただきたいです。

またデバッグMac 上で行っていて、この Mac は半年くらい前に乗り換えたばかりで gdb の cert の設定 OS XでGDBを使う(ためにコード署名をする) - Qiita 等をするのが面倒だったで lldb を使っていました。gdb でどうかはわかりませんが、lldb の p、po では v8::String をうまく見ることが出来ずはかどりませんでした。この辺も詳しい方教えてください!

おわりに

というわけで一応 github に公開していますが、勉強がてら書いてみたものなので npm にリリースする予定はありません。また出来れば C++ で書きなおしたり、引数に callback を渡すスタイルを検討したりしてみたいと思ったので時間がある時にやれたら良いなーと思っています。まだ multi line のリクエストもうまく動かせていないのでそのへんのデバッグもしないとなー。

kysnm/node-pico-http-parser · GitHub

謝辞

picohttpparser の作者の @kazuho さん、実装を参考にさせていただいた @kazeburo さんに感謝いたします。ありがとうございました!