/
467.txt
515 lines (402 loc) · 29.2 KB
/
467.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
[10] [DFN[[CODE(HTTP)@en[[[Meter:]]]]]] [[ヘッダー]]は、
[[キャッシュ]]に対してその利用回数を[[鯖]]に報告させたり、
利用回数の上限を設定したりする仕組みです。
[97] [[HTTP]] のオプション機能として [[RFC 2227]] で規定されていますが、
ほとんど利用されていません。
[FIG(sequence)[
:C:[[クライアント]]
:P:[[串]]
:S:[[鯖]]
:C -> P:[[要求]]
:P -> S:[[要求]] [CODE(HTTP)@en[[[Connection:]] [[Meter]]]]
:S -> P:[[応答]] [CODE(HTTP)@en[[[Connection:]] [[Meter]]]]
: #P# :[[応答]]を[[キャッシュ]]
:P -> C:[[応答]]
:C -> P:[[要求]]
: #P# :[[キャッシュ]]を利用
:P -> C:[[応答]]
: #P# :しばらくして利用数を報告
:P -> S:[[要求]] [CODE(HTTP)@en[[[Meter:]] [[count]]=1/0]]
:S -> P:[[応答]]
]FIG]
* 仕様書
[REFS[
- [2] [CITE@en[RFC 2227 - Simple Hit-Metering and Usage-Limiting for HTTP]]
( ([TIME[2011-12-18 04:36:26 +09:00]] 版))
<http://tools.ietf.org/html/rfc2227>
]REFS]
* 意味
[6] [CODE(HTTP)@en[[[Meter]]]] は、[[鯖]]から[[串]]に対して[[キャッシュ]]の利用回数を報告するよう求めたり
(hit-metering)、一定回数以上利用したら[[再検証]]することを求めたり (usage-limiting)
することを指示するものです。また、[[串]]から[[鯖]]に対してそのような機能を提供できることを提示したり、
計測結果を伝達したりするためにも使います。
[3] [[串]]において[[キャッシュ]]を用いて[[応答]]を返すと、
[[起源鯖]]はそのことを感知できませんから、[[応答]]が何回返されたか
(すなわち[[アクセス数]]が幾許であるか) を数えることができません。
これは[[広告]]などの目的で不都合であるため、 [CODE(HTTP)@en[[[Cache-Control:]]]]
などによって[[キャッシュ]]を無効化する [[cache-busting]] [SRC[>>2]] と呼ばれる [[hack]]
がしばしば用いられていました。 [CODE(HTTP)@en[[[Meter]]]]
はそれを置き換えることを狙っていました [SRC[>>2]]。
;; ただしすべての [[cache-busting]] を置き換えることを目的とするものではない [SRC[>>2]]
とされています。
** 利用と再利用
[75] 計測や利用制限は[[資源]] ([[URL]]) ごとではなく、
[[蓄積された応答]]ごとに数えます [SRC[>>2]]。
;; 同じ [[URL]] でも [CODE(HTTP)@en[[[Vary:]]]] [[ヘッダー]]の値が異なれば、別のものとして数えます。
[76] 「[RUBYB[利用]@en[use]]」とは、[[蓄積された応答]]を使って
[CODE(HTTP)[[[200]]]] [[応答]]、 [CODE(HTTP)[[[203]]]] [[応答]]、
第0[[バイト]]を含む [CODE(HTTP)[[[206]]]] [[応答]]のいずれかを返すことをいいます [SRC[>>2]]。
;; [77] [[上流]]から[[応答]]を受信し、それを直後に[[下流]]に[[転送]]することは、
「利用」の数には含めません [SRC[>>2]]。以前に[[キャッシュ項目]]として保存したものを使って[[応答]]することのみを数えます。
[78] 「[RUBYB[再利用]@en[reuse]]」とは、 [CODE(HTTP)[[[304]]]]
[[応答]]を返すことをいいます。ただし第0[[バイト]]を含まない[[範囲要求]]に対するものを除きます。
[SRC[>>2]]
;; [79] この「利用」、「再利用」は、[[キャッシュ再利用]]における「再利用」
とは違う意味です。
* 構文
[18] [CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]の値は、0個以上の[[指令]]の[[リスト]]
([CODE(HTTP)[#]]) です [SRC[>>2]]。
[FIG(railroad)[
= ?
== [[指令]]
== *
=== [[OWS]]
=== [CODE(HTTP)[[[,]]]]
=== [[OWS]]
=== [[指令]]
]FIG]
;; [[リスト]]ですから、 [CODE(HTTP)@en[[[Cache-Control:]]]] [[ヘッダー]]の[[指令]]の区切りと同じく、
区切り文字は [CODE(HTTP)[[[;]]]] ではなく [CODE(HTTP)[[[,]]]] です。
[65] 他の[[引数]]構文を使った[[ヘッダー]]の多くとは違って、この[[ヘッダー]]の構文は一般的な「[[指令]]」の構文は定めず、
個々の[[指令]]の構文のみが規定されています。しかしそれらを総合すると、
[[指令]]は名前のみか、名前、[CODE(HTTP)[[[=]]]]、値のいずれかです。
[98] 名前は[[大文字・小文字不区別]]の[[字句]]です。
[FIG(railroad)[
= [[字句]]
= ?
== [CODE(HTTP)[[[=]]]]
== 値
]FIG]
;; [66] 値は (他の同様な[[ヘッダー]]とは違って)
[[字句]]とは限りません。
[CODE(HTTP)[[[count]]]] [[指令]]で値に使う [CODE(HTTP)[[[/]]]]
は[[字句]]で使えない文字ですが、[[引用文字列]]とせずに値の一部として使われています。
[[引用文字列]]を使った例はありません。
[99] 値の構文や、値を指定しなければならないか指定してはならないかは、
名前によって決まります。
[67] [[RFC 2227]] の当時は[[空白]]を挿入可能かどうか構文上明記していませんでしたが、
現在の仕様でいうところの [[BWS]] が [CODE(HTTP)[[[=]]]] の前後に挿入されると解釈するべきかもしれません。
* 空のヘッダー
[100] [CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]は0個以上の[[指令]]の[[リスト]]ですから、
何も指定しない ([[空文字列]]や[[空白]]のみの文字列とする) こともできます。
[FIG(list)[
- [21] [[要求]]において値が指定されない場合、 [CODE(HTTP)@en[[[will-report-and-limit]]]]
が指定されたのと等価です [SRC[>>2]]。
- [34] [[応答]]において値が指定されない場合、 [CODE(HTTP)@en[[[do-report]]]]
が指定されたのと等価です [SRC[>>2]]。
]FIG]
;; [36] [[空文字列]]の[[ヘッダー]]と非[[空文字列]]の[[ヘッダー]]が同時に別々に指定された時にも >>21 や >>34 が適用されるのかは明記されていませんが、
字面通り解釈すると適用されることになります。複数の同名の[[ヘッダー]]は
[CODE(HTTP)[[[,]]]] 区切りで連結しても同じ意味を表すことになっていますから、
[[空文字列]]の[[ヘッダー]]と[[空文字列]]でない[[ヘッダー]]が連結されることもあります。
とすると[[ヘッダー]]の値である[[リスト]]に[[空文字列]]の要素が含まれている時も
>>21 や >>34 のように解釈するべきなのでしょうか?
[22] 更に、 [CODE(HTTP)@en[[[Connection:]] [[Meter]]]] によって
[CODE(HTTP)@en[[[Meter:]]]] ([[空文字列]])
が暗示され、 [CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]は省略できます [SRC[>>2]]。
* 指令
[48] [[指令]]には、[[要求]]で[[串]]が使うものと[[応答]]で[[鯖]]が使うものがあります。
[71] [[指令]]の名前には非省略形と省略形があり、通常は省略形を使う[['''べきです''']]
[SRC[>>2]]。なお両者を混在させても構いません [SRC[>>2]]。
[108] 次の[[指令]]が規定されています。
[FIG(short list)[
- [CODE(HTTP)@en[[[c]]]]
- [CODE(HTTP)@en[[[d]]]]
- [CODE(HTTP)@en[[[e]]]]
- [CODE(HTTP)@en[[[n]]]]
- [CODE(HTTP)@en[[[r]]]]
- [CODE(HTTP)@en[[[t]]]]
- [CODE(HTTP)@en[[[u]]]]
- [CODE(HTTP)@en[[[w]]]]
- [CODE(HTTP)@en[[[x]]]]
- [CODE(HTTP)@en[[[y]]]]
- [CODE(HTTP)@en[[[count]]]]
- [CODE(HTTP)@en[[[do-report]]]]
- [CODE(HTTP)@en[[[dont-report]]]]
- [CODE(HTTP)@en[[[max-reuses]]]]
- [CODE(HTTP)@en[[[max-uses]]]]
- [CODE(HTTP)@en[[[timeout]]]]
- [CODE(HTTP)@en[[[will-report-and-limit]]]]
- [CODE(HTTP)@en[[[wont-ask]]]]
- [CODE(HTTP)@en[[[wont-limit]]]]
- [CODE(HTTP)@en[[[wont-report]]]]
]FIG]
[73] [[指令]]を指定する順序に意味は無いと思われます。
[72] 同じ[[指令]]が複数回指定された時や、矛盾する[[指令]]が指定された時にどう処理するべきかは不明です。
[109] [[IANA登録簿]]は無いようです。
[107] 他の特定の[[指令]]またはすべての[[指令]]が指定されないことによって暗示的に指定されたとみなされる[[指令]]もいくつかあります。
;; [111] 転送量の削減のために敢えてそのような仕組みにしてあるようです。
* 文脈
[102] [CODE(HTTP)@en[[[Meter]]]] は次の3つの文脈で使うことができます。
[FIG(list)[
- [103] [[串]]から[[鯖]]に対する[[要求]]で、利用回数の計測や制限を[[串]]が提供できることを示す
- [104] [[鯖]]から[[串]]に対する[[応答]]で、利用回数の計測を[[串]]が実施するべきことや制限回数、あるいは計測や制限を指定するつもりがないことを示す
- [105] [[串]]から[[鯖]]に対する[[要求]]で、計測した利用回数を報告する
]FIG]
[12] [CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]は、
[[プロトコルの版]]が [[HTTP/1.1]] [[未満]]の[[メッセージ]]に含めては[['''なりません''']]
[SRC[>>2]]。
[19] この[[ヘッダー]]は複数指定できます [SRC[>>2]]。
[11] [CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]を含む[[メッセージ]]は、
[CODE(HTTP)@en[[[Connection:]] [[meter]]]] を含まなければ[['''なりません''']] [SRC[>>2]]。
[CODE(HTTP)@en[[[Meter:]]]] の値が[[空文字列]]になるときは、
[CODE(HTTP)@en[[[Connection:]] [[meter]]]] のみ指定して
[CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]自体は省略できます (>>22)。
[106] [[利用者エージェント]]は [CODE(HTTP)@en[[[Meter]]]] を指定してはいけないと思われますが、
明示的な要件とはなっていません。
* 計測部分木
[8] [[起源鯖]]を[[根]]とし、[[起源鯖]]からの[[応答]]の[[転送]]経路上にあって
[CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]による計測に対応した[[串]]によって構成される[[木]]のことを[DFN[[RUBYB[計測部分木]@en[metering subtree]]]]
[SRC[>>2]] といいます。
[9] [[起源鯖]]と[[利用者エージェント]]の間には、 [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]に対応しない[[串]]や、対応しているものの[[上流]]に対応しない[[串]]が存在しているため対応できない[[串]]があるかもしれません。
[[計測部分木]]は、そのような[[串]]も含めた配送経路全体で構成される[[木]]の[[部分木]]となります。
* 串から鯖へ
[20] [[串]]は、利用回数の計測や制限に対応していることを示すため、
また利用回数を報告するため、[[要求]]に [CODE(HTTP)@en[[[Meter]]]]
を含めることができます [SRC[>>2]]。
[110] 計測にも制限にも対応しない[[串]]は、 [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]を送信しては[['''なりません''']] [SRC[>>2]]。
[25] [[串]]は[[要求]]に次の[[指令]]を含めて利用回数の計測や制限を求めることができます
[SRC[>>2]]。
[FIG(list)[
- [26] [DFN[[CODE(HTTP)@en[[[will-report-and-limit]]]]]] ([DFN[[CODE(HTTP)@en[[[w]]]]]]) は、
利用報告を送信する意思があり、利用制限にも従うつもりであることを表します [SRC[>>2]]。
- [27] [DFN[[CODE(HTTP)@en[[[wont-report]]]]]] ([DFN[[CODE(HTTP)@en[[[x]]]]]]) は、
利用制限に従う意志はあるが利用報告は送信しないことを表します [SRC[>>2]]。
- [28] [DFN[[CODE(HTTP)@en[[[wont-limit]]]]]] ([DFN[[CODE(HTTP)@en[[[y]]]]]]) は、
利用制限には従わないが利用報告は返すつもりであることを表します [SRC[>>2]]。
]FIG]
[68] [[串]]は[[要求]]に次の[[指令]]を含めて利用回数の計測結果を報告できます [SRC[>>2]]。
[FIG(list)[
- [49] [CODE(HTTP)@en[[DFN[[[count]]]]=[VAR[...]]/[VAR[...]]]] ([DFN[[CODE(HTTP)@en[[[c]]]]]])
は、[[十進整数]]を表す[[ASCII数字]]列2つを値として指定します。
1つ目の数は[[利用]]、2つ目の数は[[再利用]]の回数を表します。 [SRC[>>2]]
[FIG(railroad)[
= +
== [[ASCII数字]]
= [CODE(HTTP)[[[/]]]]
= +
== [[ASCII数字]]
]FIG]
]FIG]
[51] [CODE(HTTP)@en[[[count]]=0/0]] は情報がありませんから、
送信する[['''べきではありません''']] [SRC[>>2]]。
[50] [[要求]]に [CODE(HTTP)@en[[[count]]]] 以外の[[指令]]が含まれない時は、
[CODE(HTTP)@en[[[will-report-and-limit]]]] を暗示します [SRC[>>2]]。
;; [70] これらの[[指令]]は[[要求]]にのみ含められます [SRC[>>2]]。
* 鯖から串へ
[37] [[鯖]]は[[要求]]に [CODE(HTTP)@en[[[Meter]]]] が含まれており、
計測や制限を[[下流]]に委ねたい場合に、 [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]を送信できます。 [CODE(HTTP)@en[[[Meter]]]] の送信を拒みたい時にも使えます。
[29] [[鯖]]は[[串]]に[[応答]]を送信する際に、次の[[指令]]を送信することができます [SRC[>>2]]。
[FIG(list)[
- [30] [DFN[[CODE(HTTP)@en[[[do-report]]]]]] ([DFN[[CODE(HTTP)@en[[[d]]]]]])
は、利用報告の送信を求めるものです [SRC[>>2]]。
- [31] [DFN[[CODE(HTTP)@en[[[dont-report]]]]]] ([DFN[[CODE(HTTP)@en[[[e]]]]]])
は、利用報告を送信しないことを求めるものです [SRC[>>2]]。
- [32] [CODE(HTTP)@en[[DFN[[[timeout]]]]=...]] ([DFN[[CODE(HTTP)@en[[[t]]]]]])
は、利用報告を送信するまでの[[分]]数を指定するものです [SRC[>>2]]。
値は[[ASCII数字]]列です [SRC[>>2]]。
- [38] [CODE(HTTP)@en[[DFN[[[max-uses]]]]=...]] ([DFN[[CODE(HTTP)@en[[[u]]]]]]) は、
[[応答]]を「利用」する回数の[[上限]]を指定します。
値は[[ASCII数字列]]です。
この数には当該[[応答]]の直後の[[転送]]は含めません。
[SRC[>>2]]
- [39] [CODE(HTTP)@en[[DFN[[[max-reuses]]]]=...]] ([DFN[[CODE(HTTP)@en[[[r]]]]]]) は、
[[応答]]を「再利用」する回数の[[上限]]を指定します。
値は[[ASCII数字列]]です。 [SRC[>>2]]
- [47] [DFN[[CODE(HTTP)@en[[[wont-ask]]]]]] ([DFN[[CODE(HTTP)@en[[[n]]]]]])
は、 [CODE(HTTP)@en[[[Meter]]]] を送らないことを求めるものです [SRC[>>2]]。
]FIG]
;; [41] [[キャッシュ]]が「先読み」のために[[要求]]して [CODE(HTTP)@en[[[max-uses]]]]
が返された場合でも、次の最初の実際の[[クライアント]]からの[[要求]]にその[[キャッシュ項目]]を使って返した時は回数に含まれません [SRC[>>1]]。
[35] [CODE(HTTP)@en[[[dont-report]]]] を含まない [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]は、 [CODE(HTTP)@en[[[do-report]]]] が指定されたとみなします [SRC[>>2]]。
;; [46] ここで [CODE(HTTP)@en[[[wont-ask]]]] も [CODE(HTTP)@en[[[dont-report]]]]
と同じとみなされると推測されます。
;; [74] この暗示は[[応答]]のみ適用されると思われます。
[112] [CODE(HTTP)@en[[[wont-ask]]]] は [CODE(HTTP)@en[[[dont-report]]]]
を暗示します。 [SRC[>>2]]
[101] [CODE(HTTP)@en[[[timeout]]]] は [CODE(HTTP)@en[[[do-report]]]]
を暗示しています [SRC[>>2]]。
[42] [[串]]から[[鯖]]に対して表明 (>>20) した機能以外を[[鯖]]から指定されたとしても、
[[串]]はそれを無視する[['''べきです''']] [SRC[>>20]]。
;; [69] これらの[[指令]]は[[応答]]にのみ含められます [SRC[>>2]]。
* 処理モデル
[4] [CODE(HTTP)@en[[[Meter:]]]] は[[串]]または[[起源鯖]]に対するものです [SRC[>>2]]。
[[利用者エージェント]]には適用されません。
[13] [[プロトコルの版]]が [[HTTP/1.1]] [[未満]]の[[クライアント]]から送信された
[CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]を受け入れては[['''なりません''']] [SRC[>>2]]。
;; [14] これは、[CODE(HTTP)@en[[[Connection:]]]] を正しく処理できない [[HTTP/1.0]]
[[串]]があるためです [SRC[>>2]]。
** 起源鯖の処理
[23] [[起源鯖]]は、[[要求]]に [CODE(HTTP)@en[[[Meter]]]] が指定されている時、
[[下流]]に計測や制限を委ねるかどうか決定できます。委ねない場合
(や [CODE(HTTP)@en[[[Meter]]]] を実装しない場合) はただ単に
[CODE(HTTP)@en[[[Meter]]]] を無視して構いません [SRC[>>2]]。
[33] 委ねる場合には、計測や制限を指示する[[指令]]を指定した
[CODE(HTTP)@en[[[Meter:]]]] [[ヘッダー]]を[[応答]]に含めます [SRC[>>2]]。
[[鯖]]は[[串]]が表明した機能以外を要求しては[['''なりません''']] [SRC[>>2]]。
** 串の処理
[5] [[串]]は [CODE(HTTP)@en[[[Meter:]]]] を実装しても構いませんが、
実装しなくても構いません [SRC[>>2]]。
[95] [[ICP]] などで通信しつつ協調して動作する一連の[[串]]は、全体として[[串]]に対する要件を満たさなければ[['''なりません''']] [SRC[>>2]]。
[64] [[鯖]]から [[HTTP/1.1]] 未満の[[応答]]を受信したら、 [[HTTP/1.1]]
以上の[[応答]]を受信するまで、その[[鯖]]には [CODE(HTTP)@en[[[Meter]]]]
を送信する[['''べきではありません''']]。
ただしその[[鯖]]に関して計測や制限を実施中の場合を除きます。 [SRC[>>2]]
[116] [CODE(HTTP)@en[[[wont-ask]]]] が指定された場合、
以後[[串]]は[[鯖]]に対して [CODE(HTTP)@en[[[Meter]]]]
を送信する[['''べきではありません''']]。
[[串]]はこれを最大24時間覚えておく[['''べきです''']]。 [SRC[>>2]]
;; [117] [[鯖]]が [CODE(HTTP)@en[[[Meter]]]] に対応しているものの当該[[資源]]では使わない場合に、転送量の削減のために
[CODE(HTTP)@en[[[Meter]]]] を指定しないことを求めるのが目的のようです。[[串]]が敢えて覚えておいて抑制する効果がどれだけあるのかは謎です。
[118] [[串]]に対して[[要求]]を送信し[[応答]]を受信する[[クライアント]]は、
[[利用者エージェント]]かもしれませんし、他の[[串]]かもしれません。
[[串]]の場合、 [CODE(HTTP)@en[[[Meter]]]] に対応している ([[計測部分木]]の一部である)
かもしれませんし、対応していないかもしれません。
[15] [[クライアント]]が[[計測部分木]]に含まれないなら、[[応答]]を[[転送]]する際に
[CODE(HTTP)@en[[[Meter]]]] を削除し、 [CODE(HTTP)@en[[[Cache-Control:]] [[s-maxage]]=0]]
を含めなければ[['''なりません''']] [SRC[>>2]]。
;; [16] これにより[[計測部分木]]外の[[共有キャッシュ]]が当該[[応答]]を使う前に常に[[計測部分木]]内の[[鯖]]に[[再検証]]しなくてはならなくなりますから、
[[計測部分木]]内の[[串]]が常に利用回数を計測できることとなります。
[24] [[串]]は [CODE(HTTP)@en[[[Meter]]]] を[[転送]]することもできますが、
その場合でも[[串]]に対する要件は満たさなければ[['''なりません''']] [SRC[>>2]]。
;; [7] [[起源鯖]]は [CODE(HTTP)@en[[[Connection:]] [[Meter]]]]
と指定しなければなりませんから、 [CODE(HTTP)@en[[[Meter]]]] に対応していない[[串]]は
[CODE(HTTP)@en[[[Connection:]]]] [[ヘッダー]]の規定に従い [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]を[[転送]]時に削除します。削除せずに[[転送]]するということは、
[CODE(HTTP)@en[[[Meter]]]] を理解できることを表しています。
[43] [[下流]]からの[[要求]]で [CODE(HTTP)@en[[[Meter]]]] を受信した[[串]]は、
自身の[[上流]]に対する義務と整合する範囲でのみこれを無視して構いません。
[CODE(HTTP)@en[[[Meter]]]] がそのような義務に反する場合や、
[[下流]]からの[[要求]]に [CODE(HTTP)@en[[[Meter]]]] が含まれず[[上流]]からの[[応答]]には
[CODE(HTTP)@en[[[Meter]]]] が含まれている場合、
[[転送]]する[[応答]]に [CODE(HTTP)@en[[[Cache-Control:]] [[s-maxage]]=0]]
を追加しなければ[['''なりません''']]。 [CODE(HTTP)@en[[[Expires:]]]]
や [CODE(HTTP)@en[[[Cache-Control:]] [[max-age]]]] は追加したり変更したりする[['''べきではありません''']]。
[SRC[>>2]]
[EG[
[44] [[下流]]の[[串]]が [CODE(HTTP)@en[[[Meter]]]] を送信してきた時、
自身の[[キャッシュ項目]]に [CODE(HTTP)@en[[[Meter]]]] が含まれていなければ、
[CODE(HTTP)@en[[[Meter]]]] を無視します [SRC[>>2]]。
]EG]
[EG[
[45] [[下流]]の[[串]]が [CODE(HTTP)@en[[[Meter:]] [[wont-report]]]] を送信してきた時、
自身の[[キャッシュ項目]]に [CODE(HTTP)@en[[[Meter:]] [[do-report]]]]
が含まれていた場合、[[下流]]からの[[要求]]は自身の義務に則したものではありません。
ですから[[転送]]時には [CODE(HTTP)@en[[[Meter]]]] を削除してかわりに
[CODE(HTTP)@en[[[Cache-Control:]] [[s-maxage]]=0]] を追加しなければなりません。 [SRC[>>2]]
]EG]
[94] [[キャッシュ]]しない[[串]]も[[計測部分木]]に加わることが[RUBYB[強く推奨]@en[strongly recommended]]されています。
そのような[[串]]は[[要求]]でも[[応答]]でも [CODE(HTTP)@en[[[Meter:]]]]
[[ヘッダー]]と適当な [CODE(HTTP)@en[[[Connection:]]]]
[[ヘッダー]]を[[転送]]する[['''べきです''']]。
一旦 [CODE(HTTP)@en[[[Meter:]]]] を[[転送]]しはじめたら、
適当に[[転送]]をやめたりしては[['''なりません''']]。
また [CODE(HTTP)@en[[[Meter:]]]] を含む[[応答]]を元の[[要求]]以外に返しては[['''なりません''']]。
[SRC[>>2]]
*** 利用報告
[113] [CODE(HTTP)@en[[[do-report]]]] が指定された場合、
[[串]]は[[鯖]]に利用報告を送信しなければ[['''なりません''']] [SRC[>>2]]。
[114] [CODE(HTTP)@en[[[dont-report]]]] が指定された場合、
[[串]]は[[鯖]]に利用報告を送信する[['''べきではありません''']] [SRC[>>2]]。
[115] [CODE(HTTP)@en[[[timeout]]]] が指定された場合、
当該[[応答]]が作成されてから指定された[[分]]数が経過した時までに計測数が
0 でなければ、[[串]]は[[鯖]]に利用報告を送信しなければ[['''なりません''']]。
ただし、精度±1分で実装する[RUBYB[べき]@en[should]]です。 [SRC[>>2]]
[40] [[串]]は[[上流]]からの[[応答]]で指定された「利用」や「再利用」
を使い果たした時には[[キャッシュ項目]]を[[応答]]に含めて返す前に[[再検証]]しなければ[['''なりません''']]。
なお利用報告を送ることを求められている場合には、この[[再検証]]を使って利用報告を送る[['''べきです''']]。
[SRC[>>2]]
[53] 利用報告を送信することを表明し、求められた[[串]]は、次の場合に利用報告を送信しなければ[['''なりません''']] [SRC[>>2]]。
[FIG(list)[
- [54] [[クライアント]]からの [CODE(HTTP)@en[[[GET]]]] や
[CODE(HTTP)@en[[[HEAD]]]] の[[条件付き要求]]を[[転送]]する時
(指定されている[[実体タグ]]が高々1つの時)
- [55] [CODE(HTTP)@en[[[max-uses]]]] 超過により[[条件付きGET]]を[[生成]]する時
- [56] [CODE(HTTP)@en[[[Meter:]] [[timeout]]]] 経過の場合で計測数が 0 以外の時
- [57] 何らかの理由で計測数が 0 以外の[[キャッシュ項目]]の計測数を削除する時
([[ストレージ]]制約により削除する時や、より新しい[[応答]]を受信して置き換える時など)
]FIG]
;; [58] [[キャッシュ]]は[[キャッシュ項目]]の[[応答]]の本体を削除しても計測数は削除しないこともできます [SRC[>>2]]。
>>57 は計測数を削除する時点を言っています。
[52] 利用報告の送信には、 (計測対象を明確にするため)
[[条件付き要求]]を使わなければ[['''なりません''']] [SRC[>>2]]。
[CODE(HTTP)@en[[[If-Match:]]]] や [CODE(HTTP)@en[[[If-None-Match:]]]]
を使う場合は、[[実体タグ]]を複数指定しては[['''なりません''']] [SRC[>>2]]。
[[計測部分木]]内の[[串]]は利用報告の[[転送]]時に条件を表す[[ヘッダー]]を書き換えては[['''なりません''']] [SRC[>>2]]。
[59] >>56 や >>57 の場合には[[串]]は[[条件付きHEAD]]によって利用報告を送信しなければ[['''なりません''']] [SRC[>>2]]。
[[串]]は [CODE(HTTP)@en[[[HEAD]]]] が失敗しても再試行する必要はありませんが、
正確性のためできるだけ再試行する[['''べきです''']] [SRC[>>2]]。[[串]]はこの操作の完了まで他の操作を待たせたりする必要はありません [SRC[>>2]]。
;; [60] [[串]]は同じ[[鯖]]への報告を[[持続的接続]]により複数まとめることを強く[RUBYB[推奨]@en[encourage]]されています。
[61] [CODE(HTTP)@en[[[Meter:]] [[count]]]] を含む[[要求]]を[[下流]]から受信したことにより利用報告を行う[[串]]は、自身の計測数を足して[[転送]]しなければ[['''なりません''']] [SRC[>>2]]。
ただし、その[[要求]]に[[キャッシュ項目]]から[[応答]]できる場合にあっては、
[[転送]]する必要はありません [SRC[>>2]]。
;; [62] いずれにせよ自身の計測数にも加算されます (>>83)。
[63] [CODE(HTTP)@en[[[Meter:]] [[count]]]] を[[下流]]から受信し、
それに対する[[キャッシュ項目]]を有しない[[串]]は、
[CODE(HTTP)@en[[[count]]]] を[[上流]]に[[転送]]しなければ[['''なりません''']] [SRC[>>2]]。
[17] [[串]]の[[下流]]に複数の[[計測部分木]]内の[[串]]がある場合、
利用可能回数を分配することができます [SRC[>>2]]。ただしその決定方法は仕様では定められておらず、
実装や設定に任されています。
*** 計測
[80] ある[[蓄積された応答]]の計測を行う[[串]]は、その[[応答]]に関する[[計数子]]
[VAR[CU]] と [VAR[CR]] を持ちます。これらの値は次のように使います。 [SRC[>>2]]
[FIG(list)[
- [81] 0に初期化されます。
- [82] 「利用」される度に [VAR[CU]] を、「再利用」される度に [VAR[CR]]
を[[インクリメント]]します。
- [83] [[クライアント]]からの[[要求]]に [CODE(HTTP)@en[[[Meter:]] [[count]]]]
が含まれていれば、その値を加えます。
- [84] [[鯖]]への[[要求]]の [CODE(HTTP)@en[[[Meter:]] [[count]]]]
に [VAR[CU]] と [VAR[CR]] の値を使います。
- [85] [[鯖]]から[[応答]]を受信したら、[[要求]]の送信から[[応答]]の受信までの間の「利用」と「再利用」の数に設定します。
]FIG]
[86] ある[[蓄積された応答]]の利用制限を行う[[串]]は、その[[応答]]に関する[[計数子]]
[VAR[TU]] と [VAR[TR]] を持ちます。これらの値は次のように使います。 [SRC[>>2]]
[FIG(list)[
- [87] それぞれ [VAR[CU]] や [VAR[CR]] と同様に増加させます。
- [88] [VAR[TU]] は [CODE(HTTP)@en[[[max-uses]]]] を受信した時のみ、
[VAR[TR]] は [CODE(HTTP)@en[[[max-reuses]]]] を受信した時のみ 0 にします。
]FIG]
また [VAR[MU]] と [VAR[MR]] も持ち、次のように使います。 [SRC[>>2]]
[FIG(list)[
- [89] [CODE(HTTP)@en[[[max-uses]]]] と [CODE(HTTP)@en[[[max-reuses]]]] を受信したら、
[VAR[MU]] と [VAR[MR]] を指定された値にします。受信しなかったものがあれば、
[[無限大]]とします。
]FIG]
これらの値から、[[串]]は次のように動作します。 [SRC[>>2]]
[FIG(list)[
- [90] 「利用」しようとして [CODE(math)[[VAR[TU]] ≧ [VAR[MU]]]] なら、
[[要求]]を[[鯖]]に[[転送]]して[[再検証]]しなければ[['''なりません''']]。
- [91] 「再利用」しようとして [CODE(math)[[VAR[TR]] ≧ [VAR[MR]]]] なら、
[[要求]]を[[鯖]]に[[転送]]して[[再検証]]しなければ[['''なりません''']]。
- [92] いずれにせよ、前の[[要求]]を[[転送]]していてその結果を待っているなら、
その[[応答]]が得られる (か時間切れとなる) まで処理を遅延させる[RUBYB[べき]@en[should]]です。
異なる範囲の[[部分要求]]を除き、[[再検証]]のために同時に複数の[[要求]]を送信する[['''べきではありません''']]。
]FIG]
[93] ただし、[CODE(HTTP)@en[[[max-uses]]=0]] の[[応答]]を受信した場合で、
これをただちに[[クライアント]]に[[転送]]しない場合 ([[串]]が「先読み」
している場合) には、 [VAR[PF]] (prefetch) フラグを立てます。
[VAR[PF]] フラグが立っていれば、 [CODE(math)[[VAR[TU]] ≧ [VAR[MU]]]]
であっても (他の理由で要求されない限り) [[再検証]]しなくて構いません。
[VAR[PF]] フラグは[[応答]]を利用したら消去しなければ[['''なりません''']]。 [SRC[>>2]]
;; 先読みを実装しない[[串]]は [VAR[PF]] フラグを実装する必要はありません [SRC[>>2]]。
[96] [[クライアント]]が不正な値を報告してくる可能性はありますから、
[[串]]は [CODE(HTTP)@en[[[Proxy-Authorization:]]]] や[[ホワイトリスト]]などの手段で利用数を中継する[[クライアント]]を制限することもできます [SRC[>>2]]。
* 歴史
[1] [CITE@en[draft-ietf-http-hit-metering-00 - Simple Hit-Metering and Usage-Limiting for HTTP]]
( ([TIME[2012-01-20 20:05:43 +09:00]] 版))
<http://tools.ietf.org/html/draft-ietf-http-hit-metering-00>