31
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ErlangAdvent Calendar 2014

Day 7

Erlang で HTTP/2 サーバー Lucid を書きました

Posted at

Erlang で HTTP/2 サーバー Lucid を書きました.
https://github.com/tatsuhiro-t/lucid

この記事では特に HTTP/2 の仕様に関して説明はしませんので, HTTP/2 に興味ある方は HTTP/2 Advent Calendar を読む, あるいは HTTP/2 ID を読む等をおすすめします.

Lucid は私が初めて Erlang で書いたアプリケーションです. 私は Programming Erlang を 7 年程前に買いました. そのころは日本語訳がまだでていませんでした. 半分ほど読んでからほったらかしにして 7 年程たちました. その間一切 Erlang のコードは書いていません.
さて私の twitter TL において "すごい E 本" の日本語版出版の話題が連日盛り上がっていました. そんなに盛り上がるなら何かあるのだろうということで, 原文を Web で読み始めました. The Count of Applications の章まで読んで飽きがきました. しかしそれなりに分かった気になったので一つサーバーを書いてみようと思い立ちました. どのプロトコルを実装するかは大きな選択でしたが, まだだれもやっていなさそうである HTTP/2 を実装することにしました. HTTP/2 については C で nghttp2 を実装しているので, ワタシ HTTP/2 チョットデキル. そこで Buckets of Sockets の章を斜め読みし, supervisor や acceptor 辺りを参考に実装をはじめました.

いくつか HTTP/2 に関連した実装の話題を書きたいと思います.

TLS で HTTP/2 を使う場合, TLS 拡張の ALPN で HTTP/2 をネゴシエートしなければなりません. Erlang の ssl モジュールは ALPN をサポートしていません. NPN はサポートしているので今回は NPN を使います. NPN を使うのは簡単で ssl_options{next_protocols_advertised,[<<"h2-14">>]} を追加するだけです. NPN ではクライアントがプロトコルを選択するので実際にネゴシエートしたプロトコルを得るには ssl:negotiated_next_protocol(Socket) を使います.

サーバーの基本的なアーキテクチャは Buckets of Sockets の sockserv を踏襲しています. HTTP/2 では 1 接続上に複数のリクエスト (ストリーム) が多重化されています. HTTP/2 ではフレームという単位で接続上のデータを処理をしますが Erlang のすばらしいバイナリデータサポートによりパーサーは簡単です. リクエストを受け取ったらプロセスを作成して処理を任せます. それらプロセスからレスポンスデータが来たら, フレームにシリアライズしてクライアントへ送信します.

HTTP/2 のヘッダー圧縮 HPACK も実装しています. huffmandata.erl は巨大なファイルですが, ハフマン符号化のためのテーブルをパターンマッチングのために自動生成したものです. ハフマン符号化はビットレベルの操作なので C などではシフトなど面倒ですが, Erlang は強力な binary comprehension と bitstring のお陰でミスの少ないコードが書けます.

テスト用にこの HTTP/2 サーバーは https://nghttp2.org:3456 で動いています. Chrome M39 では spdy/4 を有効にしても ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY というエラーでアクセスできません. これは Chrome が AEAD 暗号化スイートを要求するのに対し, Erlang の ssl モジュールがそれに非対応だからです (この制限は, HTTP/2 仕様からは取り除かれる可能性があります). Firefox も同様ですが, about:config で network.http.spdy.enforce-tls-profilefalse にするとこの制限を外すことができてアクセス可能になります. nghttp2 に含まれる nghttp クライアントはチェックをしていないのでアクセス可能です.

31
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?