技術者ブログ
クラウド型WAF「Scutum(スキュータム)」の開発者/エンジニアによるブログです。
金床“Kanatoko”をはじめとする株式会社ビットフォレストの技術チームが、“WAFを支える技術”をテーマに幅広く、不定期に更新中!
HTTP/2のRFCを読んだ感想
はじめに
私は自ら「串職人」と名乗るほどウェブの(つまりHTTPの)Proxyサーバが好きで、もう10年以上もプロキシサーバを作り続けています。このブログの主題であるクラウド型WAF、Scutumもそのひとつです。そもそもプロトコルとしてのHTTPが好きです。ウェブの裏側に、とてもシンプルな、テキストベースのHTTPプロトコルが活躍しているということが私の串職人としての出発点です。
HTTP/2が出た
先日、ついにHTTP/2が出ました。
数年前から、「SPDY」などのキーワードに代表される次世代のHTTPが模索されていることは何となく知っていましたが、どうもGoogleのような非常に大きいトラフィックを処理している組織が主導しているもので、一般の開発者やウェブの利用者にとってそれほど魅力的なものではなさそうだな、という印象を抱いていました。
サーバ側を作っているのもGoogle、ブラウザ(Chrome)を作っているのもGoogleで、そんなに高速化したいならUDPでも使えばよいのでは...などと、とりあえず様子を見ていました。
SPDYの段階ではまだ次世代HTTPの「アルファ版」のようなものなので、いつ変更されるかもわからないため、私自身が開発しているサーバやプロキシに反映させるつもりはなく、プロトコルの詳細についても特に追っていませんでした。
しかしついに正式にRFC化されたということなので、串職人として久しぶりに大仕事が降ってきたと軽く興奮しつつ、90ページ以上あるRFCをセブンイレブンのプリンターで両面印刷し、1ページ目から順番に読み始めたのです。SPDYを全く勉強していなかったので、先入観なく「HTTP/1.1に続いて登場したHTTP/2はどんなものか?」という視点で読めたのは良かったと思います。
RFCを読んだ最初の印象
RFCを読んでみた最初の印象は、「これはどこの惑星のHTTPだ?」というものでした。てっきり新しいヘッダやらが色々定義されてくるものだと思ったのですが、根本的に違うものでした。むしろ、ストリーム制御の話などがあるので、TCP/2か?のように感じました。
そもそも私はHTTP/2登場の文脈をまったく誤解していたのです。HTTP/2はHTTP/1.0やHTTP/1.1を入れ替えるものだろうと思っていたのですが、まったくそうではなく、従来のHTTP/1.1はそのままに、その外側にさらにかぶせて使うものだったのです。そのためHTTP/1.1とバッティングする箇所は皆無であり、今まで何も定義されていなかった部分、イメージとしては「TCPとHTTP/1.1の間」にプラスアルファするために登場したプロトコルといえます。
並列性のサポート
ご存じの通りTCPはスロースタートであるため、1つのコネクションの中で効率的にデータをやりとりできれば効率的で、HTTP/2の目玉の一つはこれです。この点は非常によいと思いますし、実際に一定の効果が期待できるのではと思います。しかし例えば「HTTP/1.1より3倍速くなった!」ということは難しいでしょうから、普通の開発者やユーザからしたら「ちょっと速くなったね」程度の話で、果たして新しいプロトコルを定義するほどのメリットがあるのか疑問に思います。
ヘッダの圧縮
ヘッダの圧縮も並列性のサポートと同様で、もちろん良いだろうとは思いますが、新規にプロトコルを定義するほどのメリットがあるとは思えません。大きなHTMLやJavaScript等を、従来の枠組みの中で可能であるgzip圧縮すればよいだけだろうという気がします。ヘッダが圧縮されてしまうことで、当然デバッグはやりづらくなります。
ステートフルすぎる
HTTP/2では複数のストリームやプライオリティ、依存ツリーなど、とにかく大量の状態を管理する必要があります。これは「リクエストが来たらレスポンスを返す」だけだったHTTP/1.1と比べると非常に大きな違いで、実装は今までのHTTP/1.1と比べ、とてつもなく複雑化すると思われます。関数型言語が流行っているこの時代にこれほどステートフルな方向にシフトするとは正直おどろきました。
他のレイヤーとクロスオーバーしすぎている
HTTPのRFCであるのにTLSに言及している箇所があったり、データの転送について、まるでTCPのようにフロー制御の機能があったりと、きれいに「そのレイヤー」に収まっていない印象を受けました。そもそもTCPを強く意識して出てきたものなのである意味仕方ないかもしれませんが...
複雑すぎる
全体的に、それほど大きなメリットがなさそうなのにやたら複雑になってしまっている印象を受けます。HTTP/1.1まではインターネットプロトコルとして比較的シンプルであり、それこそがウェブ発展の大きな原動力になっていたと考えていますが、HTTP/2はやたらと複雑で、デバッグは面倒になるでしょう。
単に追加するだけで何も減らせていない
開発者はHTTP/2に本気で取り組もうと考える場合、HTTP/2だけを勉強すればよいのではなく、従来通りHTTP/1.1を勉強した上で、さらにHTTP/2も勉強する必要があることになります。つまり単純に、覚えなくてはいけないことが大幅に増えたことになります。HTTP/1.1から無駄な部分(個人的には思いつきませんが)を極力減らし、シンプルにした上で出てくるのであればまだしも、単に追加だけしてしまっているので、開発者の負担を増やす方向にのみ向かってしまっています。
これは流行らないかも
細かい点まで含めてそれなりに吟味してみましたが、個人的な予想としてHTTP/2は失敗に終わる確率が8割という気がします。失敗というのは、開発者に歓迎されず、また仮に導入された場合にも、大した効果も上げられずにトラブルだけを増やすという意味です。
そもそもHTTP/1.1の出来は十分によいのです。シンプルで扱いやすく、十分に速いです。HTTP/1.1にとても大きな不満がなければ、HTTP/2を積極的に導入しようとするモチベーションは湧きません。
そしてHTTP/2が流行らないだろうと思う最大の理由は、HTTP/1.1が全体として温存されており、今後もHTTP/1.1だけを使い続けることができる可能性が高いという点です。HTTP/2の中でも根本的な部分では「リクエストがきたらレスポンスを返す」という流れは変わっておらず、各ヘッダフィールドの持つ意味もHTTP/1.1のままです。HTTP/2はラッパー的な存在であり、HTTP/2の中の処理は従来通りHTTP/1.1になります。つまりサーバやウェブアプリケーション側では内部の処理は従来と同じになるため、クライアントとの通信において、HTTP/1.1のサポートを捨て、HTTP/2だけにする理由がありません。
WAF開発者としての視点から
WAF(Web Application Firewall)開発者の視点として見ると、プロトコルが複雑になるため、色々とやれることが増えて防御しやすくなる面がありそうです。具体的には、PINGやPUSH_PROMISEなどによってWAF側から積極的にクライアントに対して働きかけ、反応を見ることで実装のフィンガープリンティングがやりやすくなりそうです。例えば、RubyやPythonで作成された攻撃ツールがFirefoxやChromeのフリをしているのを見破ったりすることが容易になるでしょう。
さいごに
個人的にHTTP/2で最も「なんなんだソレ...」と感じたのはヘッダフィールドを必ず小文字にすると言う規定です。従来の「User-Agent」はHTTP/2では「user-agent」になります。実にしまりがなく、だらしない印象です。これだけを持ってしてもHTTP/2からは失敗の香りが漂ってくる気がします。
まとめ
今回はHTTP/2のRFCを読んだ印象をまとめてみました。ScutumはHTTPレイヤーで多くの仕事をするので、当然HTTP/2についても今後の動向を見ながら適切に対応していく予定ですが、個人的にはあまり流行らないだろうと予想しています。IPv4のように「アドレスの枯渇」という問題を抱えているプロトコルでさえリプレースが進まないのに、特に大きな問題を持っていないHTTP/1.1が、これだけ複雑でそれほどメリットのないHTTP/2に隠されていくようになる気がしません。むしろ必要とされているのではTCP/2なのではないかと思います。