HTTPヘッダのメタ情報

ユーザエージェント(ブラウザ)がウェブサーバーからHTTPでリソースを取得するとき、HTTPメッセージのヘッダにいくつかのデータを付加することで、リソースに関する情報やユーザエージェントの機能、利用者の好みなどを伝えることができます。HTTPヘッダは、ウェブのリソースに関するメタ情報を提供する、最も確実で効率的な手段の一つです。

HTTPとヘッダ

WWWでリソースを取得するとき、ほとんどの場合はHTTP (Hypertext Transfer Protocol) [RFC2616]に基づくメッセージの交換によってユーザエージェント(UA)とウェブサーバーがやり取りを行います。このときに伝達されるデータについて概略を理解しておくと、メタデータの確実で効率的な提供に生かすことができます。

たとえば、このページを取り出すためにUAがサーバーに送るHTTPのリクエストメッセージは、次のようなのものです。

[例1]

GET /docs/sw/http-header.html HTTP/1.1
Host: www.kanzaki.com
Accept: text/html, text/plain, text/sgml, */*;q=0.01
Accept-Encoding: gzip, compress
Accept-Language: ja,en
If-Modified-Since: Sun, 2 Sep 2001 11:31:06 GMT
User-Agent: Lynx/2.8.2

1行目がリソースを取得(GET)するための指示とHTTPバージョンで、それ以降が補足情報を伝えるヘッダです。プロパティ名: 形式のフィールドで、メタデータなどをサーバーに送ります。この場合は、主としてUAがどんなタイプの情報を処理できるのかを示しています。

UAからのリクエストを受けてサーバーがリソースを送り出すときも、同様の形の応答ヘッダが先頭に付加されます。

[例2]

HTTP/1.1 200 OK
Date: Wed, 05 Sep 2001 06:06:19 GMT
Server: Apache/1.3.12
Content-Location: http-header.html.ja
Vary: negotiate,accept-language,accept-charset
TCN: choice
P3P: policyref="/w3c/p3p.xml",CP="NOI DSP COR ADM DEV OUR STP"
Last-Modified: Wed, 05 Sep 2001 06:02:09 GMT
Connection: close
Content-Type: text/html; charset=shift_jis
Content-Language: ja

1行目は処理の結果を示す応答コード、2行目以降がヘッダ部分です。ヘッダの後に、1行の空行を挟んで、リソースの中身が送信されます。このヘッダでは、日付などの送信処理に関するデータと、MIMEタイプや更新日時などのリソースに関するメタデータほかが示されています。

UAは、実際にリソースの取得を要求(GET)するまえに、このヘッダ情報だけをリクエスト(HEAD)して、効率的にメタ情報を調べることもできます。また、UAがローカルディスクのキャッシュの日時をIf-Modified-Sinceヘッダで送れば、サーバーはリソースの更新日付がキャッシュより新しいときだけ内容を送り返せばよく、無駄なデータの送信を避けられます(更新されていなければ、応答コードを304 Not modifiedとしてヘッダのみ送り返す)。

応答ヘッダによるメタデータ

サーバーからの応答ヘッダには、送り出すリソースについてのメタデータが含まれます。これらの多くはサーバーが自動的に付加しますが、いくつかは作者(サーバー管理者)が設定することで、より適切なメタデータをリソースに加えられるようになります。

MIMEタイプと文字コード情報

ウェブ上には世界各国・各言語のリソースが存在しますから、文字化けを起こさずに適切に内容を処理するためには、使われている文字コードを知ることが重要です。文字コード情報は、Content-Typeヘッダのオプションパラメータであるcharset=で示します。UAはこのヘッダを見て、リソースの本体を処理する前に、その内容がどんな文字コードで書かれているかを理解できるわけです。

リソースの中身の文字コードは、サーバーは自動的には分かりません(送信するたびに中身をチェックして文字コードを判別していては効率が悪すぎます)。そこで、サーバー管理者が設定ファイルで(必要ならグループごとに)文字コードを示す情報を設定しておきます。この手段は、サーバーによって異なりますが、広く使われているApacheならば、AddType指示子を使い、httpd.conf.htaccessファイルに次の1行を加えます[APACHE-MIME]

[例3] AddType "text/html; charset=Shift_JIS" .html

この設定により、.htmlという拡張子を持つファイルのContent-Typeヘッダには、text/htmlというMIMEタイプに加え、Shift_JISという文字コード情報が付加されることになります。

ファイルによって使用する文字コードが違っている場合、ディレクトリ単位で文字コードを管理し、AddType指示子をhttpd.conf<Directory>別に、もしくはディレクトリごとの.htaccessファイルに記述します。あるいは、文字コードごとに拡張子を使い分けるのも一つの手段です。

SSIと更新日付情報

サイトの共通バナーなどを効率よく管理するためにSSI (Server Side Include)を利用している人も少なくないと思います。SSIを使う場合の問題は、ファイルの内容がリクエストされるたびに異なる可能性があるので、サーバーがLast-Modifiedフィールドを応答ヘッダに加えなくなるという点です。本当にダイナミックな内容なら、これは正しい対応なのですが、共通バナーのような固定的なものをインクルードするだけで更新日付情報が提供できなくなると、重要なメタデータが失われてしまうことになります。

この問題を回避するために使われるのが、ApacheのXBitHack指示子です[APACHE-INCL]。この指示子は、本来は実行権限を持つHTMLファイルをSSIの対象として処理させるための機能ですが、これを利用して、SSI処理したファイルにもLast-Modifiedヘッダを加えさせることができます。

[例4] XBitHack full

という1行を設定ファイルに記述し、更新日付を返したいファイルに実行許可を与えてください。実行許可のないSSIファイルにはLast-Modifiedは加えられないので、本当にダイナミックなファイルと固定的なインクルードを区別することも可能です。

コンテント・ネゴシエーション

HTTP/1.1では、ヘッダに含まれるメタデータを使って、複数のリソースの中から最も適切なものを選択するためのコンテント・ネゴシエーションの仕組みが定められています。例えば、同じ内容の文書の英語版と日本語版が用意されている場合、UAのAccept-Languageヘッダの値でenが優先されていれば英語版を、jaが優先されていれば日本語版をサーバーが送り返すといった機能です。

MultiViewsと言語ネゴシエーション

Apacheサーバーには、このコンテント・ネゴシエーションを簡単に利用できるようにするMultiViews機能が用意されています[APACHE-NEG]。次の1行を設定ファイルに加えてください。

[例5] Options +MultiViews

Options Allが指定されていても、このMultiViewsの指定は別途行わなければなりません。MultViewsを利用して、言語のネゴシエーションを行わせるには、次のようにして言語コードと拡張子を結びつけます。

[例6]

AddLanguage ja .ja
AddLanguage en .en

これで、.jaという拡張子を持つファイルは日本語に、.enは英語に対応づけられます。サーバー側には、日本語版と英語版のファイルを、それぞれ次のような拡張子を加えたファイル名で用意します。

[例7]

http-header.html.ja
http-header.html.en

Apacheは、UAからhttp-header.htmlというリソース取得のリクエストを受け取ると、Accept-Languageヘッダを調べ、その内容に応じて適切な言語バージョンのファイルを送り返してくれます。MultiViewsは、言語バージョンだけでなく、Acceptヘッダに応じて画像タイプなどMIMEタイプのバリエーションを選んだり、Accept-Charsetヘッダに応じて文字コードのバリエーションを選んだりすることも可能です。

ブラウザの言語設定

UAのリクエストに含まれるAccept-Languageヘッダは、多くのブラウザではオプション設定の「言語の優先順位」といった部分で指定することができます。

ブラウザには、優先順位を付けて日本語[ja]、英語[en]などの言語を設定する機能がある

このオプションで設定した言語コードが、リクエスト時にAccept-Languageヘッダとしてサーバーに送られることになります。設定画面での優先順位を入れ替えてこのページを再読込してみると、同じURIをリクエストしているのに、異なる言語のページが表示されることが分かるでしょう。

独自ヘッダの追加

サイト全体に共通するメタデータを提供する場合、HTTPヘッダに新しいフィールドを追加すると効率的です。たとえば、P3Pのコンパクトポリシーをヘッダに加えるような使い方です。

Apacheではmod_headersモジュールの提供するHeader指示子[APACHE-HEADER]を使って、新しいヘッダを追加することができます。

[例8] Header Set P3P 'policyref="/w3c/p3p.xml",CP="NOI DSP COR ADM DEV OUR STP"'

この応答ヘッダを確認することで、クライアントはP3Pのポリシーファイルを別途ロードすることなく、サーバーのプライバシーポリシーを確認できるようになります(P3Pについては、後日解説ページを提供する予定です)。

参照文献

[RFC2616]
R. Fielding, et al., Hypertext Transfer Protocol -- HTTP/1.1, , The Internet Society
<http://www.ietf.org/rfc/rfc2616.txt>
[APACHE-MIME]
Apache module mod_mime, Apache HTTP Server documentation
<http://httpd.apache.org/docs/mod/mod_mime.html>
[APACHE-INCL]
Apache module mod_include, Apache HTTP Server documentation
<http://httpd.apache.org/docs/mod/mod_include.html>
[APACHE-NEG]
Apache Content Negotiation, Apache HTTP Server documentation
<http://httpd.apache.org/docs/content-negotiation.html>
[APACHE-HEADER]
Apache module mod_headers, Apache HTTP Server documentation
<http://httpd.apache.org/docs/mod/mod_headers.html>