Webを支える技術を読んでのメモ #1

HTTPヘッダの重要性

ヘッダは

  • メッセージのボディに対する付加的な情報を表現する(メタデータ

  • クライアントやサーバーは、ヘッダを見て、メッセージに対する挙動を決定する

  • リソースへのアクセス権を設定する認証はヘッダで実現する

  • クライアントとサーバーの通信回数と量を減らすキャッシュなどのHTTPの機能はヘッダで実現する

主なHTTPヘッダ

認証

あるリソースにアクセス制御がかかっている場合、

  • ステータスコード401 Unauthorized(このリソースのアクセスには適切な認証が必要)
  • www-Authenticate ヘッダを利用

クライアントにリソースへのアクセスに必要な認証情報(認証方式)を知ることができる。

Basic認証

ユーザ名とパスワードによる認証方式。ユーザー名とパスワードはAuthorizationヘッダに入れてリクエストごと送信する

Digest認証

Digest認証は、Basic認証よりもセキュアで、あるメッセージに対して、ハッシュ関数を適用した結果のハッシュ値を使った認証を行う

キャッシュ

キャッシュ用ヘッダ

HTTPの重要な機能の一つにキャッシュというものがある。キャッシュとは、サーバから取得したリソースをローカルに蓄積し再利用する手法のことです。ローカルに蓄積したデータをキャッシュと呼ぶこともある。クライアントがローカルに蓄積したキャッシュは、そのキャッシュが有効な期間、クライアントが再度そのリソースにアクセスしようとした時に再利用する。

  • Pragma:キャッシュを抑制する。no-cacheを指定する。この値は、リソースをキャッシュしてはいけないことを示す

  • Expires:キャッシュの有効期限を示す。指定された期間まで、キャッシュが新鮮さを保つことをサーバが保証する。次回このリソースにアクセスする時に、キャッシュの有効期限内かどうかによって、サーバに再度アクセスするのか、キャッシュを利用するのか決定する

  • Cache-Control:上記二つのヘッダ(PragmaとExpires)は、HTTP 1.0が定義したヘッダ。詳細なキャッシュの方法を指定するには、HTTP 1.1で追加された Cache-Control ヘッダを使う。例えば、Pragma:no-cacheとCache-Control:no-cacheは等しい。まとめると、

    • キャッシュさせない場合は、PragmaとCache-Controlのno-cacheを同時に指定する
    • キャッシュの有効期限が明確に決まっている場合は、Expiresを指定する
    • キャッシュの有効期限を相対的に指定場合は、Cache-Controlのmax-ageで相対時間を指定する
条件付きGET

クライアントが、ExpiresやCache-controlヘッダを検証した結果、ローカルキャッシュを再利用できないと判断した場合でも、条件付きGETリクエストを送信すれば、キャッシュを再利用できる場合がある。条件付きGETは、サーバー側にあるリソースが、クライアントローカルのキャッシュから変更されているかどうかを調べるヒントをリクエストヘッダに含めてくれることで、キャッシュがそのまま使えるかどうか検証してくれる。

  • if-Modified-Since (条件付きGET):リソースの更新日時を条件にする。ローカルのキャッシュの更新日が指定され、サーバ上のリソースがこれ以降更新されていないようであれば、サーバは、304 Not Modified を返し、クライアントは、ローカルのキャッシュを使う。304 Not Moddifiedは条件付きGETへのレスポンスで、サーバー上のリソースが変わっていないことを示すステータスコード

  • if-None-Match(条件付きGET):リソースのETagを条件にする。if-Modified-Sinceヘッダによる条件付きGETは便利だが、時計を持っていないサーバーやミリ秒単位で更新される可能性のあるリソースには利用できない。その場合に使うヘッダが、if-None-Match ヘッダとETagヘッダ。if-None-Matchヘッダとif-Modified-Sinceヘッダは似ているが、指定する値が違う。if-Modified-Sinceヘッダが「日時を指定」するのに対し、if-None-Matchは、「値を指定」する。その値は、キャッシュしているリソースのETagヘッダの情報。ETagヘッダの情報が更新されていなけらば、ローカルのキャッシュを使う。if-Modified-Sinceとif-None-Matchの使い分けとしては、サーバーがETagヘッダを出している場合は、if-None-Matchを使った方が良い。(正確な更新有無を確認できるため)

  • ETagの計算

  • 静的ファイル  Apacheなどのデフォルトでは、静的ファイルのETagの値は、inode番号、ファイルサイズ、更新日時から自動で計算してくれる。

  • 動的ファイル  ApacheなどのWebサーバは、動的ファイルのETagの値は、自動で計算してくれない。HTMLやフィードを生成するWebアプリケーションでETagを生成する必要がある。

接続的接続

HTTP 1.1 での大きな新機能が接続的接続です。HTTP 1.0では、クライアントが、TCPコネクションを確立してリクエストを送信し、サーバがそれにレスポンスを返すたびにTCPコネクションを切断していました。TCPのコネクション確立はコストがかかる処理ですので、画像や外部CSSファイルにたくさんリンクしているWebページを表示しようとすると、どうしてももっさりとした動きにならざる得ませんでした。これを解決するため、クラアインとサーバー間でのリクエストのたびに切断するのではなく、まとめて接続し続ける手法が開発されました。HTTP 1.0では、それをKeep-Aliveヘッダで実現しています。HTTP 1.1では、この接続的接続がデフォルトの動作となりました。接続的接続では、クライアントはレスポンスを待たずに同じサーバーにリクエストを送信できます。これを「パイプライン化」と呼びます。パイプライン化により、効率的にメッセージを処理できる。コネクションを切断したい場合は、リクエストでConnectionヘッダに、closeという値を指定すれば、「このリクエストのレスポンスが返ってきたら切断する」という意図をサーバーに伝えれれる。

まとめ(感想)

  • ヘッダは重要

  • ヘッダを意識しながらサーバー/クライアント間のリクエスト/レスポンスがどういった動きになっているか改めて確認してみようと思った。