達人が語る,インフラエンジニアの心得

第18回 プロトコルを覚えよう[その2:HTTP編]

この記事を読むのに必要な時間:およそ 4 分

今回は前回に続いて,プロトコルについてです。前回はSMTPでしたが,今回はおそらく最もメジャーなプロトコルであるといっても過言ではないHTTPについてです。

「デカいRFC」の読み方

まずHTTPにはバージョンとして1.0と1.1があります。実質,今はほぼ100%のサイトが1.1だと思って良いでしょう。

HTT1.1はRFC2068で提唱され,RFC2616にObsoleteされています。ですのでRFC2616(と,RFC2616をUpdateしているRFC2817とRFC5785)を読めば,HTTP1.1のことが把握できます。とはいってもでかいRFCなので,読むのはちょっと大変かもしれません。ただ,これくらいポピュラーなRFCになると日本語訳もたくさんあるので,原文と一緒に日本語訳も読むと,理解が速いかもしれません(訳だけ読むのはあまりオススメできません)⁠

また,RFCを読むとき(特にプロトコルに関するRFCを読むとき)は,BNF記法の知識が必要になります。BNFとはバッカスナウアフォーム(Backus-Naur Form)の略で,正規表現のような,任意の文字列を表現するのに定められた記法です。またBNFにはEBNF(Extended BNF)やABNF(Augmented BNF)といった発展形もあります。RFCではABNFがよく使われます。

BNFを知ることはプロトコルを覚えることにも役立つので,ちょっと例を見てみます。

たとえばPage17には,

HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT

とあります。

""で括られているのはリテラル(文字列)です。*は繰り返し,DIGITは数字を意味するシンボルです。ですので上記のBNFは,HTTP-Versionは「HTTP/数字1個以上.数字1個以上」と定義しているということになります。

BNF記法自体,その定義がRFC内に書いてあるので,それを読めば最初はちょっと苦労するかもしれませんが,それほど苦労せず読めるようになると思います。RFC2616だと,2.1節にABNFの定義が記述してあります。

HTTP/1.1の2大特徴

さて,もっとRFC2616を読み進めてみます。19.6節に,HTTP/1.0との違いが簡単にまとめられています。

まずHTTP/1.1の大きな特徴のひとつに,HOSTヘッダのサポートがあります。これはいわゆるname based virtualなWebサーバをサポートするためのものです。

いまではname based virtualなWebサーバは当たり前すぎますが,以前はバーチャルなWebサーバはIP basedか,そもそもバーチャルに対応していないという時代がありました。しかしそれではIPアドレスの枯渇に拍車をかけてしまうので,name based virtualという手法が考えられ,一気に広まりました。

簡単に言うと,name based virtualなWebサーバとは,HOSTヘッダという「何々という名前のWebサーバに接続していますよ」という情報を宣言するためのヘッダによって,返却するコンテンツを制御するものです(簡単に言ってないような…)⁠

つまり,あるWebサーバがあったとして,そこにwww.foobar.comとwww.barbaz.comという2つのサイトの設定をname basedでもたせているとします。接続したクライアントがHOSTヘッダで,どちらのサイトのホスト名を伝えるかによって,サーバはそれに適したコンテンツを返却します。

たとえば

HOST: www.foobar.com

であればwww.foobar.comのコンテンツを,また

HOST: www.barbaz.com

であればwww.barbaz.comのコンテンツを返すということです。

ちなみにIP basedというのは,あるサーバに複数のIPをもたせてWebサーバをbindingしておき,どのIPに接続してくるかによって返却するコンテンツを制御するというものです。

そして,RFC2616の19.6.1.1には以下のように書いてあります。

  Both clients and servers MUST support the Host request-header.
  A client that sends an HTTP/1.1 request MUST send a Host header.
  Servers MUST report a 400 (Bad Request) error if an HTTP/1.1
  request does not include a Host request-header.
  Servers MUST accept absolute URIs.

すなわち,HTTP/1.1の場合にはHOSTヘッダは必ずサポートしなければいけない,していないとHTTP/1.1非準拠である,ということになります。

もうひとつ,HTTP/1.1の大きな特徴に,Keep-Aliveの挙動があげられます。こちらは19.6.2に下記のように書いてあります。

  Persisitent connections are the deafult for HTTP/1.1 messages; we introduce
  a new keyword (Connection: close) for declaring non-persistence.

つまり,HTTP/1.1ではKeep-Alive接続がデフォルト挙動として定義されており,持続的接続を終了するためにConnection: closeという新しいキーワードが作られました。

HTTP/1.1の大きな特徴は上記の2点(name based virtual対応とKeep-Aliveのデフォルトの挙動)です。そして,name based virtualがあるが故に,HTTPを手で打てるというのが結構重要なのです(インフラエンジニアにとっては,ですが)⁠

なぜかというと,ブラウザでWebの検証をする場合には,ブラウザはDNSで名前解決をして,その解決したIPに接続にいきます。つまり,DNSに登録されている名前は,

接続先IPのAレコード

であると同時に,

HOSTヘッダで伝えられるホスト名

でもあるのです。

ところが,検証などをしている時には,この2つを連動させたくないということがよくあります。もちろんDNS側で,Aレコードの答えをクエリ元によって変化させるという解決もありますが,それよりは手でHTTPを話せるほうが楽でしょう。もちろん,サイトのレンダリングの結果を見たいときには手でHTTPプロトコルを話しても意味がないですが。

著者プロフィール

山崎徳之(やまざきのりゆき)

青山学院大学卒業後,アスキー,So-netなどでネットワーク,サーバエンジニアを経験。オン・ザ・エッヂ(現ライブドア)のデータセンターである「データホテル」を構築,運営。2003年にベイエリアにおいてVoIPベンチャーであるRedSIP Inc.を創業。2006年6月に株式会社ゼロスタートコミュニケーションズ(現 ZETA株式会社)を設立,代表取締役就任(現任)。ECソリューションの「ZETA CX」シリーズとして検索エンジンやレコメンドエンジンを開発,販売している。

blog:http://blog.zaki.jp/
社長コラム:https://zetacx.com/column

コメント

コメントの記入