Real World HTTP(第2版)を読んだ話


5 月の連休中に Real World HTTP(第 2 版)を通読したので、簡単に感想をメモしておく。

https://www.amazon.co.jp/dp/4873119030

なお、この本の要約版が無料で公開されているので、買う前にまずはこちらを読むのがいいかもしれない。

https://www.oreilly.co.jp/books/9784873118789/

背景

なぜこの本を読むことにしたかというと、自分自身がプログラミング初心者であり、仕事や趣味でプログラムを書いていて HTTP に関する知識が不足している(…というか、あらゆる点が全部不足してるんだけど)と感じることが多かったからだ。

プログラミングしていると、言語の標準ライブラリやそれをラップしたパッケージ等で気軽に HTTP 通信を扱うことがよくある。そうすると自分で書くプログラムは少なくて済むのだが、実際にどういう仕組みで動いているのかが分からないので問題が起きたときにどこを調べればいいか分からなくなってしまう。あと単純にどう動いてるかの概要が自分で分かってないと気持ち悪い。

インターネットを通じて何かを提供するためのプログラムを書いてお金をもらう仕事をしていく以上は HTTP の勉強を避けては通れないと思ったし、連休何もすることがなかったので、時間をかけて読んでみることにした。

書籍の概要

本書を一言で表すと「HTTP の歴史書」と言えると思う。

1 ページ目の「まえがき」にはこうある。

本書では、変化が大きくない領域である、HTTP(Hypertext Transfer Protocol)というウェブの転送用のプロトコルにフォーカスして紹介します。CGI とウェブアプリケーションサーバー、または最近でてきたサーバーレスアーキテクチャなど、ウェブサービスの裏で実装に使われる言語や仕組みはここ 20 年で大きく移り変わりましたが、実際にブラウザとサーバーの通信に関わる部分のコンセプトは 20 年近く、あまり変わっていません。コンピュータ業界は、日進月歩で新しい技術などが出続けるため、学び続けないといけないとよく言われます。それは半分正しくて半分間違っています。コンピュータサイエンスにあたるような内容、業界標準のプロトコル、テストしやすく見通しの良いコードの書き方、アルゴリズム、データベースなどは、一度学んでも無駄になることはありません。

HTTP は「送信側(クライアント)」と「受信側(サーバー)」の両方がルールに従ってメッセージをやり取りする仕組みであり、この基本は誕生以来変わっていない。しかし一方で、ウェブの発展に伴って主なクライアントであるブラウザに様々な機能が追加されたり、それが仕様として標準化されたりしてきた。

最新の仕様を読むと巨大なプロトコルだが、歴史を辿っていくと最初は特定の課題を解決するためのシンプルなプロトタイプから始まり、それぞれの段階(HTTP/0.9 や 1.0、2 など…)で状況に応じて現実のユースケースに対応するための改善がされていったという経緯があることが分かる。

その経緯を実際に手元で試しながら体系的に学ぶことで、新しい技術であっても何からどのように発展しているのかを知ることができ理解の促進に繋がる。ここに歴史を学ぶ意義がある。

原典といえる RFC への参照もあるので、気になった仕様をいくらでも深堀りできる。とても分厚い(約 450 ページ)本なので内容を全て覚えることは不可能だが、一度通読してどこに何が書いてあるか何となく把握できれば困ったことが起きる度に辞書的に引けて非常に便利になると思う。

そのため、思い立ったらすぐにめくれる紙媒体で買うのをおすすめしたい。

章ごとの大まかな構成と一言感想

第 1 章〜第 2 章

HTTP の先祖といえる電子メールやニュースグループから始まり、メソッドとパス、ヘッダー、ボディ、ステータス等の HTTP の基本概念やコンテントネゴシエーション、クッキー、セッション、キャッシュなどブラウザの裏側を支える仕組みを説明する。

今まで「何となくこういうものかな」と考えていた技術が体系的に整理されており、それぞれの関係性や複数の技術や機能の組み合わせでどのようなユースケースが実現されているかが分かりやすく解説されていて面白かった。

第 3 章

第 1 章〜第 2 章の内容を簡単におさらいしながらそれを実現する HTTP クライアントを Go 言語で実装する。

私はここで初めて Go 言語に触れたのだが、文法がシンプルで読みやすくて驚いた。仕事で使うレベルにするには修行が必要だろうが、読んで何をしているか把握するだけなら C や JavaScript 、または似たような言語を書いたことがあれば困らないと思う。

第 4 章〜第 5 章

主に HTTP/1.1 時代の新機能を紹介する。

Keep-Alive の仕組みや TLS の仕組み(鍵交換や通信手順によって何を守るか)、追加されたメソッド(CONNECT など)、さらには HTTP/1.1 時代に用途として追加されたファイルのダウンロード、XMLHttpRequest、ウェブサイト間の共通認証認可プラットフォーム(SAML や OAuth、OpenID など)がどのように実現されているかを解説する。

個人的に面白かったのが XMLHttpRequest の名前の由来だった。以前から変な名前だなぁとは思っていた(XML 要素はどこに?)。

実はこれは元々 Exchange 2000 のメールサーバーにブラウザからアクセスする機能を実現するために Internet Explorer 5 の β 版に搭載されたのだが、開発中に問題がたくさん起きたことで Microsoft 社内のリリースの期限に間に合いそうになかったので、どうしても出したかった開発者の Alex さんは同僚が作っていた XML 処理ライブラリに無理やり混ぜ込んで出荷することにした(そのため XML とほぼ関係ない機能なのに言い訳として XML という名前をつけた)とのことだった。

Web Archive で読める Alex さんのブログの言葉を借りれば

doesn’t have any specific tie to XML other than that was the easiest excuse for shipping it

Microsoft みたいな大企業でそんなことやっていいのか?とも思うが、結果としてはこの行動によって Exchange 2000 のリリース前にそれにウェブから接続できるクライアント、つまり XMLHttpRequest を使えるブラウザ)が普及しきっている状態を作れた。ビジネス的には成功だったと言えそうだ。

第 6 章

第 4 章〜第 5 章で登場した機能を備えた HTTP/1.1 のクライアントを Go 言語で実装する。

基本的には標準ライブラリを通じて TLS 通信をするための簡単なクライアントとサーバーを作るのだが、証明書の作り方から説明されていて初心者にも優しかった。

第 7 章〜第 8 章

HTTP/2 や HTTP/3 時代におけるプロトコルの再定義や新しく登場したユースケースを紹介する。SPDY や QUIC(これは厳密には HTTP ではないが)の仕組みについても解説されている。

この時代の新たなユースケースとしてはセマンティックウェブ、モバイルの DeepLink、HTTP ライブストリーミングによる動画再生などがある。

個人的には WebRTC (Real-Time Communication)が興味深かった。HTTP は基本的にブラウザとサーバーの間の通信だが、 WebRTC はブラウザ同士の P2P 通信(例えば 1 対 1 もしくは複数人でのシンプルなビデオ通話システムやスクリーンの共有)にも使うことができるし 1 対多のリアルタイム映像配信にも使える。トランスポート層には通常の HTTP 通信と同様に TCP を使うこともできるが、通常は UDP を使う。このプロトコルはヘッダサイズが少なく TCP と比べて信頼性が低い代わりに転送速度が速い。

HTTP の上でリアルタイム配信を行う HLS(HTTP Live Streaming)では(ストリーミングという名前がついているものの)実際にはチャンクごとにダウンロードが完了しないと再生が始められないため、どうしても 30 秒程度の遅延が発生してしまう。また、 HLS はサポートされている環境が少ないというデメリットもある。

第 9 章

第 7 章〜第 8 章で登場した HTTP/2 のいくつかの実装を Go 言語で行う。

WebSocket を使って簡単なリアルタイム通信のチャットルームを作ったりする。

第 10 章〜第 13 章

REST API の考え方や現実世界での実装例、利用方法、JavaScript の XMLHttpRequest や FetchAPI をつかった動的な HTTP アクセス、ウェブアプリケーションの基本的なリクエスト-レスポンスのフローやインフラ構成等をかんたんに紹介している。

個人的に興味を惹かれたのは CDN 関連の記述だった。CDN はユーザーから物理的に近くに位置する高機能なプロキシサーバーで、 Akamai やら CloudFront やら Fastly やら様々な製品が存在する。コンテンツをキャッシュしてレスポンスを高速化することもできるが、キャッシュをしなくてもインターネット上でクライアントからサーバーへのホップ数を削減する効果がある。

どちらの使い方であってもサーバーの負荷軽減やユーザー体験の向上に大きな役割を果たすので非常に有用ではあるものの、ユーザーごとに同じ URL で異なる内容を見せなければならないケース(例えば会員制サイトのマイページとか)では Cache-Control ヘッダで適切なディレクティブが設定されていないと同じ URL を開いた別のユーザーが前のユーザーの画面を見ることになってしまうケースがあるので注意しなければならない。

本書では事例としてメルカリのインシデントが紹介されていた。

https://engineering.mercari.com/blog/entry/2017-06-22-204500/

第 14 章

最後の 1 章はまるまるセキュリティに割かれている。 XSS や中間者攻撃、セッションハイジャック、 CSRF 、リスト型アカウントハッキング等さまざまな攻撃手法を紹介しつつ、ブラウザや HTTP の機能を使ってそれらをどう防ぐかが解説されている。実装例というよりは、このような仕組みが用意されているからこういう考え方でセキュリティ対策をしようという説明が並んでいた。

同じような内容は IPA (ビールじゃない方)の「安全なウェブサイトの作り方」という無料の PDF にも書かれていたので、どちらも読むと理解が深まっていいかもしれない。このようなセキュリティ対策はやらかすと一発アウトなので何回読んでもいい。

https://www.ipa.go.jp/security/vuln/websecurity.html

この章で興味深かった仕組みとして、古のセッション管理とセッション固定化攻撃の話があった。私はその昔携帯電話向けにゲームを作る会社で働いていたことがあって、その頃は素人なりに URL にセッション ID 出てるの大丈夫なのだろうかと思っていたが、どうやらフィーチャーフォンでは Cokkie が使えない機種があったからそうせざるを得なかったらしい。

まとめ

自分の感想を書いたが、なにぶん私自身が初心者なのでこの本の魅力を紹介しきれていない気がする。

この本の最大の長所は HTTP の歴史を体系的に一冊にまとめたことにあると思っている。今は既に使われていない技術がなぜ生まれなぜ消えたか、という記述も豊富で、各技術や仕様の歴史の中での位置づけを確認しながら読めるので理解が進みやすい。

初心者は体系的に整理された HTTP の知識を一冊で得られるので、プログラミングを始めたけどウェブの仕組みがよく分かってない、という人には特におすすめしたい。自分がまさにそうだったように。

幸い冒頭で挙げたようにミニ版(本書の要約)が無料で公開されているので、気になる方はぜひダウンロードしてみてください。

https://www.oreilly.co.jp/books/9784873118789/