[3] [DFN[[CODE(HTTP)@en[[[Max-Forwards:]]]] [[ヘッダー]]]]は、
[[要求メッセージ]]が[[串]]によって[[転送]]されても良い最大回数を表します。

* 仕様書

[REFS[
- [9] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-5.1.2>'''
- [6] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.7>
- [7] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.8>
- [8] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-08-07 05:54:02 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#page-92>
]REFS]

* 意味

[10] [CODE(HTTP)@en[[[Max-Forwards:]]]] [[ヘッダー]]は、
[[要求]]が[[串]]によって[[転送]]される回数を制限するものです [SRC[>>9]]。

;; [21] [[応答]]には適用されないようです。

* 文脈

[4] [[クライアント]]は、[CODE(HTTP)@en[[[OPTIONS]]]] [SRC[>>6]] や
[CODE(HTTP)@en[[[TRACE]]]] の[[要求]]に
[CODE(HTTP)@en[[[Max-Forwards:]]]] [[ヘッダー]]を含めることができます。

[5] [[串]]は、[CODE(HTTP)@en[[[OPTIONS]]]] [[要求]]に関して、
[CODE(HTTP)@en[[[Max-Forwards:]]]] を含む[[要求]]を[[転送]]する場合を除き、
これを[[生成]]しては[['''なりません''']] [SRC[>>6]]。

;; [19] 以前は拡張メソッドでも使えるとされていましたが、
[[RFC 7231]] で >>4 の2つの[[メソッド]]に限定されました [SRC[>>8]]。

* 構文

[11] 値は、[[非負整数]]です [SRC[>>9]]。

[12] この値は当該[[要求メッセージ]]が[[転送]]されることができる残り回数を示す[[十進整数]]です
[SRC[>>9]]。

* 処理モデル

[13] [[中間器]]は、 [CODE(HTTP)@en[[[OPTIONS]]]] や [CODE(HTTP)@en[[[TRACE]]]]
の[[要求]]を受信した時 [CODE(HTTP)@en[[[Max-Forwards:]]]] [[ヘッダー]]が含まれている場合、
- [14] 値が0なら、これを[[転送]]しては[['''ならず''']]、
最終[[受信者]]として[[応答]]しなければ[['''なりません''']] [SRC[>>9, >>7]]。
- [15] 値が[[正]]なら、元の値より1少ない値、または対応している最大値のどちらか小さい方にした
[CODE(HTTP)@en[[[Max-Forwards:]]]] を[[生成]]して[[転送]]しなければ[['''なりません''']]
[SRC[>>9]]。

[16] [[受信者]]は、他の[[要求メソッド]]の場合 [CODE(HTTP)@en[[[Max-Forwards:]]]]
を無視して構いません [SRC[>>9]]。

;; [17] ということは適用しても良いということになりますが、
例えば[[串]]が自身宛でない [CODE(HTTP)@en[[[GET]]]] を処理するとどうなるのでしょうか。。。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[18] RFC 2068・2616 (HTTP/1.1) 14.31 Max-Forwards
]FIGCAPTION]

> The Max-Forwards request-header field [DEL[may be used]] [INS[provides a mechanism]] with the
TRACE [DEL[method (section 14.31)]] [INS[(section 9.8) and OPTIONS (section 9.2) methods]] to limit the
number of proxies or gateways that can forward the request to the
next inbound server. This can be useful when the client is attempting
to trace a request chain which appears to be failing or looping in mid-chain.

[CODE(HTTP)[Max-Forwards]] [[要求頭欄]]は、 [CODE(HTTP)[[[TRACE]]]] 方式および
[CODE(HTTP)[[[OPTIONS]]]] と共に使って、次の[[上り]]サーバーに[[要求]]を転送することができる[[串]]または[[関門]]の数を制限する機構を提供します。
これは、クライアントが鎖途中で失敗したり循環したりしているっぽい[[要求鎖]]を追跡しようとする時に便利です。

>
- Max-Forwards   = "Max-Forwards" ":" 1*DIGIT

> The Max-Forwards value is a decimal integer indicating the remaining
number of times this request message may be forwarded.

[CODE(HTTP)[Max-Forwards]] 値は、この要求メッセージが転送されても良い残り回数を示す十進整数です。

> Each proxy or gateway recipient of a TRACE [INS[or OPTIONS]] request
containing a Max-Forwards header field [DEL[SHOULD]] [INS[MUST]] check and update
its value prior to forwarding the request. If the received value is zero
(0), the recipient [DEL[SHOULD NOT]] [INS[MUST NOT]] forward the request; instead, it [DEL[SHOULD]] [INS[MUST]]
respond as the final recipient [DEL[with a 200 (OK) response containing the received request message as the response entity-body (as described in section 9.8)]].
If the received Max-Forwards value is greater than zero, then the forwarded message [DEL[SHOULD]] [INS[MUST]]
contain an updated Max-Forwards field with a value decremented by one (1).

[CODE(HTTP)[Max-Forwards]] 頭欄を含んだ
[CODE(HTTP)@en[[[TRACE]]]] 要求または [CODE(HTTP)@en[[[OPTIONS]]]] 要求のそれぞれの串または関門である受信者は、]]
要求を転送する前に [CODE(HTTP)[Max-Forwards]] 頭欄の値を確認し、更新しなければ'''なりません'''。受信した値が零 ([CODE(HTTP)[0]]) なら、受信者はその要求を転送しては'''なりません'''。
代わりに、最終受信者として応答します。受信した [CODE(HTTP)[Max-Forwards]]
値が零より大きければ、転送されるメッセージは一 ([CODE(HTTP)[1]]) 
減らした値の [CODE(HTTP)[Max-Forwards]] 欄を含まなければ'''なりません'''。

> The Max-Forwards header field [DEL[SHOULD]] [INS[MAY]] be ignored for all other methods
defined by this specification and for any extension methods for which
it is not explicitly referred to as part of that method definition.

[CODE(HTTP)[Max-Forwards]] 頭欄は、この仕様書で定義されたほかのすべてのメソッドおよびメソッド定義の中で陽に言及していない拡張メソッドでは無視しても'''構いません'''。
]FIG]

[1] RFC 2068 では、 [CODE(HTTP)[Max-Forwards:]] 頭欄に串・関門が対応することは推奨
([CODE[[[SHOULD]]]]) でしたが、 RFC 2616 では必須
([CODE[[[MUST]]]]) になりました。

ですから、 RFC 2068 に従う中継者が要求鎖中に要ると正しく機能しないかもしれません。
(RFC 2068 に従う中継者ばかりであったら正しく機能する保証がありませんでしたが、 RFC 2616 に従う中継者ばかりなら必ず正しく機能します。[WEAK[もっとも、どちらの RFC に従うか判定する方法はありませんけどね。]])

[2] RFC 2068 では、 [CODE(HTTP)[Max-Forwards]] に対応していない[[メソッド]]では無視するべきだと言っていましたが、
RFC 2616 は無視しても良いと言っています。

ですから、どちらに従っていても、 [CODE(HTTP)[Max-Forwards:]] に影響されないはずの[[メソッド]]を使っているときに中継者が数を減らしてしまう可能性があります。 [CODE(HTTP)[0]] に反応して要求鎖の途中で応答が戻ってくる可能性もあります。

* 実装

[20] [[Apache]] 2.2 は(おそらくどの[[メソッド]]でも) [CODE(HTTP)@en[[[Max-Forwards:]]]]
に対応しているようです。 [CODE(HTTP)@en[[[OPTIONS]]]] や [CODE(HTTP)@en[[[TRACE]]]]
では仕様通り[[串]]が返答するようです。 [CODE(HTTP)@en[[[GET]]]] では
[CODE(HTTP)[[[502]] Proxy Error]] が返されており、[[本体]]に含まれるエラーメッセージによると
[CODE(HTTP)@en[[[Max-Forwards:]] 0]] を受信したらループと判断するようです。