- HTTPヘッダの重要性
- HTTPヘッダの生い立ち
- 日時
- MIMEメディアタイプ
- 言語タグ
- コンテントネゴシエーション
- Content-Lengthとチャンク転送
- 認証
- キャッシュ
- 持続的接続
- その他のHTTPヘッダ
- まとめ
HTTPヘッダの重要性
- メッセージボディに対する付加的な情報(メタデータ)を表現
- クライアントとサーバはヘッダを見てメッセージに対する挙動を決定する
- メディアタイプなや言語タグなど、アプリケーションのフレームワークでなく、実装者が設定するヘッダも多い
HTTPヘッダの生い立ち
- HTTP1.0から登場
- 電子メールのメッセージ仕様のヘッダ形式をもとに追加
→ インターネットの成長とともに規定された歴史 HTTP1.0から登場ヘッダと電子メールのメッセージヘッダと共通部分が多い
例)Content-Type、Dateなど歴史からくる制約、バッドノウハウも多い
- メール:7bit ASCIIコード以外の文字が入れられない
- HTTP:文字エンコーディングの制限でラテンアルファベット以外い入れられない
電子メールとの違い
- メール
- 1方向にしかメッセージのやり取りができない
- HTTP
- 一度の通信でリクエスト/レスポンスの2つのメッセージをやりとり
- メール
日時
MIMEメディアタイプ
- メッセージでやり取りするリソースの表現の種類を指定
電子メールからきた仕様(Muktipurpose Internet Mail Extensions)
Content-Type
- メディアタイプを指定する
- タイプとサブタイプで構成
charsetパラメータ
言語タグ
コンテントネゴシエーション
- メディアタイプ、文字エンコーディング、言語タグはサーバーで指定
クライアントと交渉して決めることができるパラメータ
Accept
- 処理できるメディアタイプを伝える
- メディアタイプに優先順位をつける
- サーバーがクライアントからの要求にこたえられない場合、「406:Not Acceptable」
Accept-Charset
Accept-Language
- 処理できる言語を伝える
- 自然言語に優先順位をつける
Content-Lengthとチャンク転送
Content-Length
- ボディの長さを指定する
- 静的ファイルなどあらかじめサイズがわかっている場合
Transfer-Encoding:chunked
- チャンク転送
- ボディを分割して転送する。
- 動的に画像生成する場合など、ファイルサイズが決まるまでレスポンスが返せない場合に応答性能が低下するのを防ぐ
- チャンクサイズは16進数を仕様
- HTTP1.1で受信が必須仕様
認証
HTTP認証方式
Digest認証
- セキュアな認証方式
- 認証なしでリクエストして、レスポンス情報から認証情報を生成し、再送信する
チャレンジ
再送信
利点
- パスワードに関するセキュリティリスクを低減
- パスワードを盗まれる危険性がない
- パスワードそのものを預けなくてもよい、パスワードのハッシュ値を保管すだけ
- パスワードに関するセキュリティリスクを低減
欠点
- パスワード以外のセキュリティリスクは回避できない
- パスワードのみを暗号化
- メッセージ自体は平文でネットワーク上に流れる
- クライアント側の負担が大きい
- 同じURI空間でも毎回チャレンジして、ダイジェストを生成する必要がある
(nonceを取得するため)
- 同じURI空間でも毎回チャレンジして、ダイジェストを生成する必要がある
- パスワード以外のセキュリティリスクは回避できない
普及していない理由
WSSE
キャッシュ
- サーバから取得したリソースをローカルストレージに蓄積し、再利用する手法
ローカルストレージにキャッシュしたデータそのものをキャッシュと呼ぶこともある
ヘッダ(サーバーへのアクセスをしない)
Pragma
- キャッシュを抑制
- 「no-cache」のみ指定可能
- 指定された場合は必ずサーバーにアクセスする
- キャッシュを抑制させない場合に指定(Cache-Controlにも指定)
Expires
- キャッシュの有効期限を示す
- クライアントが有効期限内からサーバーへのアクセスを行うか判断する
- 最長1年を推奨
- 有効期限が明確に決まっている場合に指定
Chache-Control
- 詳細なキャッシュ方法を指定する
- HTTP1.1で追加、Pragma、Expiresを代用可能
- 相対的な有効期限設定が可能
- 有効期限が相対的に指定したい場合に指定
条件付きGET
- サーバーに判断してもらう
クライアントではキャッシュ利用不可と判断された場合でもリクエストヘッダに情報を詰めて、キャッシュ利用可否をサーバーに判断してもらう
if-Modified-Since
- リソースの更新日時を条件にする
if-Non-Match
- リソースのEtagを条件にする
- サーバーがEtagを出している場合に利用、正確な更新有無が判断可能
静的ファイルの場合
- Webサーバーで判断可能
- inode番号、ファイルサイズ、更新日時から自動計算可能
動的リソースの場合
- アプリケーションで判断する
- 生成したHTMLなどからEtagを算出
- サイズが大きなリソースや複雑なクエリが発生する場合はメタデータで生成、リソースの更新カウンタから算出
持続的接続
- HTTP1.1からの追加機能
問題
解決
- 都度接続、切断を繰り返すのではなく、接続し続ける手法が開発
- HTTP1.0ではオプション(keep-alive)
- HTTP1.1ではデフォルト
- パイプライン化
- クライアントはサーバからのレスポンスを待たずに同じサーバーにリクエストを送信可能
- コネクションを切断したい場合、(Connection:close)を指定
その他のHTTPヘッダ
- Content-Disposition
- サーバがクライアントにファイル名を提示
- 電子メール仕様から伝承
- 文字エンコーディングが必要
まとめ
- HTTPヘッダはメソッドやステータスコードと組み合わせて認証やキャッシュなどのHTTPの重要な機能を実装
- 電子メールや文字エンコーディングは深い歴史があり、バッドノウハウを引き継いでいる。
- HTTPヘッダをうまく利用するためにサーバやブラウザだけでなく、電子メールや文字エンコーディングの歴史も調査する必要がある
【WEBを支える技術】URI設計編~良いURI設計とは~ - WEB道楽
【WEBを支える技術】HTTP基礎編~シンプルさが標準化~ - WEB道楽