count

Meter: ヘッダー (HTTP)

[10] Meter: ヘッダーは、 キャッシュに対してその利用回数をに報告させたり、 利用回数の上限を設定したりする仕組みです。

[97] HTTP のオプション機能として RFC 2227 で規定されていますが、 ほとんど利用されていません。

C
クライアント
P
S
C -> P
要求
P -> S
要求 Connection: Meter
S -> P
応答 Connection: Meter
#P#
応答キャッシュ
P -> C
応答
C -> P
要求
#P#
キャッシュを利用
P -> C
応答
#P#
しばらくして利用数を報告
P -> S
要求 Meter: count=1/0
S -> P
応答

仕様書

意味

[6] Meter は、からに対してキャッシュの利用回数を報告するよう求めたり (hit-metering)、一定回数以上利用したら再検証することを求めたり (usage-limiting) することを指示するものです。また、からに対してそのような機能を提供できることを提示したり、 計測結果を伝達したりするためにも使います。

[3] においてキャッシュを用いて応答を返すと、 起源鯖はそのことを感知できませんから、応答が何回返されたか (すなわちアクセス数が幾許であるか) を数えることができません。 これは広告などの目的で不都合であるため、 Cache-Control: などによってキャッシュを無効化する cache-busting >>2 と呼ばれる hack がしばしば用いられていました。 Meter はそれを置き換えることを狙っていました >>2

ただしすべての cache-busting を置き換えることを目的とするものではない >>2 とされています。

利用と再利用

[75] 計測や利用制限は資源 (URL) ごとではなく、 蓄積された応答ごとに数えます >>2

同じ URL でも Vary: ヘッダーの値が異なれば、別のものとして数えます。

[76]利用 (use) 」とは、蓄積された応答を使って 200 応答203 応答、 第0バイトを含む 206 応答のいずれかを返すことをいいます >>2

[77] 上流から応答を受信し、それを直後に下流転送することは、 「利用」の数には含めません >>2。以前にキャッシュ項目として保存したものを使って応答することのみを数えます。

[78]再利用 (reuse) 」とは、 304 応答を返すことをいいます。ただし第0バイトを含まない範囲要求に対するものを除きます。 >>2

[79] この「利用」、「再利用」は、キャッシュ再利用における「再利用」 とは違う意味です。

構文

[18] Meter: ヘッダーの値は、0個以上の指令リスト (#) です >>2

  1. ?
    1. 指令
    2. *
      1. OWS
      2. ,
      3. OWS
      4. 指令
リストですから、 Cache-Control: ヘッダー指令の区切りと同じく、 区切り文字は ; ではなく , です。

[65] 他の引数構文を使ったヘッダーの多くとは違って、このヘッダーの構文は一般的な「指令」の構文は定めず、 個々の指令の構文のみが規定されています。しかしそれらを総合すると、 指令は名前のみか、名前、=、値のいずれかです。

[98] 名前は大文字・小文字不区別字句です。

  1. 字句
  2. ?
    1. =
[66] 値は (他の同様なヘッダーとは違って) 字句とは限りません。 count 指令で値に使う /字句で使えない文字ですが、引用文字列とせずに値の一部として使われています。 引用文字列を使った例はありません。

[99] 値の構文や、値を指定しなければならないか指定してはならないかは、 名前によって決まります。

[67] RFC 2227 の当時は空白を挿入可能かどうか構文上明記していませんでしたが、 現在の仕様でいうところの BWS= の前後に挿入されると解釈するべきかもしれません。

空のヘッダー

[100] Meter: ヘッダーは0個以上の指令リストですから、 何も指定しない (空文字列空白のみの文字列とする) こともできます。

[36] 空文字列ヘッダーと非空文字列ヘッダーが同時に別々に指定された時にも >>21>>34 が適用されるのかは明記されていませんが、 字面通り解釈すると適用されることになります。複数の同名のヘッダー, 区切りで連結しても同じ意味を表すことになっていますから、 空文字列ヘッダー空文字列でないヘッダーが連結されることもあります。 とするとヘッダーの値であるリスト空文字列の要素が含まれている時も >>21>>34 のように解釈するべきなのでしょうか?

[22] 更に、 Connection: Meter によって Meter: (空文字列) が暗示され、 Meter: ヘッダーは省略できます >>2

指令

[48] 指令には、要求が使うものと応答が使うものがあります。

[71] 指令の名前には非省略形と省略形があり、通常は省略形を使うべきです >>2。なお両者を混在させても構いません >>2

[108] 次の指令が規定されています。

[73] 指令を指定する順序に意味は無いと思われます。

[72] 同じ指令が複数回指定された時や、矛盾する指令が指定された時にどう処理するべきかは不明です。

[109] IANA登録簿は無いようです。

[107] 他の特定の指令またはすべての指令が指定されないことによって暗示的に指定されたとみなされる指令もいくつかあります。

[111] 転送量の削減のために敢えてそのような仕組みにしてあるようです。

文脈

[102] Meter は次の3つの文脈で使うことができます。

  • [103] からに対する要求で、利用回数の計測や制限をが提供できることを示す
  • [104] からに対する応答で、利用回数の計測をが実施するべきことや制限回数、あるいは計測や制限を指定するつもりがないことを示す
  • [105] からに対する要求で、計測した利用回数を報告する

[12] Meter: ヘッダーは、 プロトコルの版HTTP/1.1 未満メッセージに含めてはなりません >>2

[19] このヘッダーは複数指定できます >>2

[11] Meter: ヘッダーを含むメッセージは、 Connection: meter を含まなければなりません >>2Meter: の値が空文字列になるときは、 Connection: meter のみ指定して Meter: ヘッダー自体は省略できます (>>22)。

[106] 利用者エージェントMeter を指定してはいけないと思われますが、 明示的な要件とはなっていません。

計測部分木

[8] 起源鯖とし、起源鯖からの応答転送経路上にあって Meter: ヘッダーによる計測に対応したによって構成されるのことを計測部分木 (metering subtree) >>2 といいます。

[9] 起源鯖利用者エージェントの間には、 Meter: ヘッダーに対応しないや、対応しているものの上流に対応しないが存在しているため対応できないがあるかもしれません。 計測部分木は、そのようなも含めた配送経路全体で構成される部分木となります。

串から鯖へ

[20] は、利用回数の計測や制限に対応していることを示すため、 また利用回数を報告するため、要求Meter を含めることができます >>2

[110] 計測にも制限にも対応しないは、 Meter: ヘッダーを送信してはなりません >>2

[25] 要求に次の指令を含めて利用回数の計測や制限を求めることができます >>2

  • [26] will-report-and-limit (w) は、 利用報告を送信する意思があり、利用制限にも従うつもりであることを表します >>2
  • [27] wont-report (x) は、 利用制限に従う意志はあるが利用報告は送信しないことを表します >>2
  • [28] wont-limit (y) は、 利用制限には従わないが利用報告は返すつもりであることを表します >>2

[68] 要求に次の指令を含めて利用回数の計測結果を報告できます >>2

[51] count=0/0 は情報がありませんから、 送信するべきではありません >>2

[50] 要求count 以外の指令が含まれない時は、 will-report-and-limit を暗示します >>2

[70] これらの指令要求にのみ含められます >>2

鯖から串へ

[37] 要求Meter が含まれており、 計測や制限を下流に委ねたい場合に、 Meter: ヘッダーを送信できます。 Meter の送信を拒みたい時にも使えます。

[29] 応答を送信する際に、次の指令を送信することができます >>2

[41] キャッシュが「先読み」のために要求して max-uses が返された場合でも、次の最初の実際のクライアントからの要求にそのキャッシュ項目を使って返した時は回数に含まれません >>1

[35] dont-report を含まない Meter: ヘッダーは、 do-report が指定されたとみなします >>2

[46] ここで wont-askdont-report と同じとみなされると推測されます。
[74] この暗示は応答のみ適用されると思われます。

[112] wont-askdont-report を暗示します。 >>2

[101] timeoutdo-report を暗示しています >>2

[42] からに対して表明 (>>20) した機能以外をから指定されたとしても、 はそれを無視するべきです >>20

[119] timeout の値は、 当該応答が作成されてから利用報告を送信するべき時刻までの数を表します >>2

[69] これらの指令応答にのみ含められます >>2

利用回数の計測

[122] キャッシュ蓄積された応答は、計測と制限のための次の変数を持ちます >>2

  • CU
  • CR
  • TU
  • TR
  • MU
  • MR
  • PF

[123] 「U」が利用、「R」が再利用を表しています。

[80] これらの値は、次のように変化させます >>2

[87] PF は「prefetch」の意味で、先読み機能を実装している時に使うことが想定されています。 先読みを実装しないPF フラグを実装する必要あ貼りません >>2

利用回数上限の適用

[40] ある蓄積された応答を使って要求を処理する場合には次のように動作します >>2

[92] いずれにせよ、前の要求転送していてその結果を待っているなら、 その応答が得られる (か時間切れとなる) まで処理を遅延させるべき (should) です。 異なる範囲の部分要求である場合を除き、 再検証のために同時に複数の要求を送信するべきではありません>>2

[17] 応答に利用や再利用の回数の制限があり、 その応答を利用回数制限に対応した転送する場合には、 それ(ら)や自身で利用回数を分配することができます >>2。 ただしその決定方法は仕様では定められておらず、実装や設定に任されています。

[63] いずれにせよ、max-usesmax-reuses が含まれる Meter: ヘッダーを受信し、そのヘッダー下流転送する場合には、 元々指定された値以下の何らかの値を指定することになります。 すべてを自身が判断したいなら値を 0 にできますし、 すべてを下流に委ねたいなら元の値のままにできます。 後者の場合は MUMR を 0 にしないといけません。

[128] 再検証に失敗した場合に蓄積された応答を使って良いのかは不明です。 must-revalidate 相当と考えるなら、使わないべきでしょうか。

利用報告の送信

[113] 指令 do-report が指定された場合、 に当該応答に関する利用報告を送信しなければなりません >>2

[114] 指令 dont-report が指定された場合、 に当該応答に関する利用報告を送信するべきではありません >>2

[53] ある応答に関して利用報告を送信することを求められている場合、 は次の場合に利用報告を送信しなければなりません >>2

[58] キャッシュキャッシュ項目応答の本体を削除しても計測数は削除しないこともできます >>2>>57 は計測数を削除する時点を言っています。

[115] timeout の指定により利用報告を送信する場合は、 その送信のタイミングの精度は±1分で実装するべき (should) です。 >>2

[52] 利用報告の送信には、 (計測対象を明確にするため) 条件付き要求を使わなければなりません >>2

[124] 実体タグではなく * を指定した条件付き要求でも良いのかどうかは不明です。

[120] 利用報告を含む条件付き要求If-Match:If-None-Match: を使う場合は、 実体タグを複数指定してはなりません >>2クライアントからの条件付き要求転送する場合 (>>54) であっても、実体タグが複数指定されている場合は利用報告を送信しません >>2

[121] 利用報告を含む条件付き要求転送時に、 条件を表すヘッダーを書き換えてはなりません >>2

[59] クライアントからの要求転送ではなく要求生成する >>56>>57 の場合には、 HEAD 要求を使わなければなりません >>2はこの HEAD 要求が失敗しても再試行する必要はありませんが、 正確性のためできるだけ再試行するべきです >>2はこの操作の完了まで他の操作を待たせたりする必要はありません >>2

[60] は同じへの報告を持続的接続により複数まとめることを強く推奨 (encourage) されています。

[84] 利用報告は、 Meter: count によって行います。その値はそれぞれ CUCR としなければなりません >>2

[61] Meter: count を含む要求クライアントから受信し、 それをに送信する場合、下流から受信した値を自身の CUCR に加算し、その結果を Meter: count に設定して転送することとなります。

処理モデル

[4] Meterまたは起源鯖に対するものです >>2利用者エージェントには適用されません。

[129] 明記されていませんが、趣旨からして私的キャッシュにも適用されないと思われます。

[13] プロトコルの版HTTP/1.1 未満クライアントから送信された Meter: ヘッダーを受け入れてはなりません >>2

[14] これは、Connection: を正しく処理できない HTTP/1.0 があるためです >>2

起源鯖の処理

[23] 起源鯖は、要求Meter が指定されている時、 下流に計測や制限を委ねるかどうか決定できます。委ねない場合 (や Meter を実装しない場合) はただ単に Meter を無視して構いません >>2

[33] 委ねる場合には、計測や制限を指示する指令を指定した Meter: ヘッダー応答に含めます >>2が表明した機能以外を要求してはなりません >>2

串の処理

[5] Meter: を実装しても構いませんが、 実装しなくても構いません >>2

[95] ICP などで通信しつつ協調して動作する一連のは、全体としてに対する要件を満たさなければなりません >>2

[64] から HTTP/1.1 未満の応答を受信したら、 HTTP/1.1 以上の応答を受信するまで、そのには Meter を送信するべきではありません。 ただしそのに関して計測や制限を実施中の場合を除きます。 >>2

[116] wont-ask が指定された場合、 以後に対して Meter を送信するべきではありませんはこれを最大24時間覚えておくべきです>>2

[117] Meter に対応しているものの当該資源では使わない場合に、転送量の削減のために Meter を指定しないことを求めるのが目的のようです。が敢えて覚えておいて抑制する効果がどれだけあるのかは謎です。

[118] に対して要求を送信し応答を受信するクライアントは、 利用者エージェントかもしれませんし、他のかもしれません。 の場合、 Meter に対応している (計測部分木の一部である) かもしれませんし、対応していないかもしれません。

[15] クライアント計測部分木に含まれないなら、応答転送する際に Meter を削除し、 Cache-Control: s-maxage=0 を含めなければなりません >>2

[16] これにより計測部分木外の共有キャッシュが当該応答を使う前に常に計測部分木内の再検証しなくてはならなくなりますから、 計測部分木内のが常に利用回数を計測できることとなります。

[24] Meter転送することもできますが、 その場合でもに対する要件は満たさなければなりません >>2

[7] 起源鯖Connection: Meter と指定しなければなりませんから、 Meter に対応していないConnection: ヘッダーの規定に従い Meter: ヘッダー転送時に削除します。削除せずに転送するということは、 Meter を理解できることを表しています。

[43] 下流からの要求Meter を受信したは、 自身の上流に対する義務と整合する範囲でのみこれを無視して構いません。 Meter がそのような義務に反する場合や、 下流からの要求Meter が含まれず上流からの応答には Meter が含まれている場合、 転送する応答Cache-Control: s-maxage=0 を追加しなければなりませんExpires:Cache-Control: max-age は追加したり変更したりするべきではありません>>2

[44] 外向きMeter を送信してきた時、 自身のキャッシュ項目Meter が含まれていなければ、 Meter を無視します >>2

[45] 外向きMeter: wont-report を送信してきた時、 自身のキャッシュ項目Meter: do-report が含まれていた場合、下流からの要求は自身の義務に則したものではありません。 ですから転送時には Meter を削除してかわりに Cache-Control: s-maxage=0 を追加しなければなりません。 >>2

[94] キャッシュしない計測部分木に加わることが強く推奨 (strongly recommended) されています。 そのような要求でも応答でも Meter: ヘッダーと適当な Connection: ヘッダー転送するべきです。 一旦 Meter:転送しはじめたら、 適当に転送をやめたりしてはなりません。 また Meter: を含む応答を元の要求以外に返してはなりません>>2

[62] Meter: count を含む要求を受信しても、 キャッシュから結果を返せるのであれば、転送せずに応答を返しても構いません >>2count の値はの保持している値に加算され (>>83)、 次にが利用数を報告する時に使われます。キャッシュから結果を返せない時は、 count上流転送しなければなりません >>2

セキュリティー

[96] クライアントcount に指定した値が正確であることは一般には保証されません。 起源鯖計測部分木内のも、不正な値が指定されることを考慮する必要があります。 Proxy-Authorization:ホワイトリストなどの手段で利用数を中継するクライアントを制限することもできます >>2

[125] RFC 2227>>96 の問題を簡単に触れるだけであまり重大に考えていないようですが (まだ大らかな時代だったからかもしれませんが。)、これは Meter の仕組みが起源鯖 (あるいは著者) が信用できる“身内”のの間でしか機能しないことを意味しています。 不正な値を排除するためには第三者が運用するMeter を実装していたとしてもそれは利用できず、 Cache-Control: s-maxage に書き換えられて転送されることとなります。は (あったとしても) ほとんどが第三者の運用するものですから、元々 RFC 2227 が望んでいた cache-busting の解決には全くなりません。

[126] “身内”のの間では Meter を使う必然性はなく、 のログファイルに直接アクセスしたり、が提供する (通常の HTTP鯖としての) アクセス数の計測機能を参照したりすれば十分です。むしろアクセス数以上の任意の情報が得られ、 より有用です。

[127] Meter がほとんど利用されなかったのはこのような問題を解決できなかったからでしょう。 あるいはそもそも RFC 2227著者らの言う cache-busting という「問題」が存在すらしていなかったのかもしれません。 (RFC 2227 の書かれた時代にはまだ明確にはなっていなかったかもしれませんが、) 著者の管理下にない共有キャッシュWeb では機能しませんし、 必要性もほとんどありません (共有キャッシュ参照)。

歴史

[1] draft-ietf-http-hit-metering-00 - Simple Hit-Metering and Usage-Limiting for HTTP ( ( 版)) <http://tools.ietf.org/html/draft-ietf-http-hit-metering-00>

[132] >>305 には RFC 2227 が出版された後にいくつか実装しようという動きがあるものの、 起源鯖ではログにどう記録するかが問題になるだろう、ただし RFC の範囲外である、と状況が説明されています。

[133] RFC 2227Proposed Standard なので、実装経験なしでも出版できています。 それにしても実装可能か十分検討せずに標準として出版するとは流石 IETF ですね。

[135] >>134 は同じ著者が提案する別の拡張で、 Meter との相互作用も検討していましたが、こちらは RFC 化すらされていないようです。

[137] >>136RFC 2227 を引用して cache-busting を踏まえた広告に関する仕組みを提案していましたが、支持を集められなかったようです。

[139] >>138Meter の失敗の原因としてアクセス数以外の IPアドレスクッキーなどを起源鯖が得られないことを挙げています。