[8] [[CGI]] の[[メタ変数]] [DFN[[CODE(CGI)@en[[[PATH_INFO]]]]]] は、[[Script-URI]] の [[path]]
のうち、[[CGIスクリプト]]によって解釈されるべき部分を[[パーセント復号]]したものです。

* 仕様書

[REFS[
- [22] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]]
-- [6] '''<http://tools.ietf.org/html/rfc3875#section-4.1.5>'''
-- [23] <http://tools.ietf.org/html/rfc3875#section-8.2>
]REFS]

* 意味

[9] [CODE(CGI)@en[[[PATH_INFO]]]] は、[[CGIスクリプト]]によって返されるべき[[資源]]・[[部分資源]]を識別するものです
[SRC[>>6]]。

* 構文

[10] 値の構文は次のように定義されています [SRC[>>6]]。
[PRE(ABNF code)[
      PATH_INFO = "" | ( "/" path )
      path      = lsegment *( "/" lsegment )
      lsegment  = *lchar
      lchar     = <any [[TEXT]] or [[CTL]] except "/">
]PRE]

;; [11] つまり実質的に [CODE(URI)[[[/]]]] からはじまる任意の[[文字列]]が認められています。

[12] [CODE(CGI)@en[[[PATH_INFO]]]] は元の [[URL]] の [[path]] 
のうち[[CGIスクリプト]]を識別する部分の後に続く部分から決まる値です。
[[path-segment]] に[[引数]]は認められていません。 [SRC[>>6]]

;; [13] [[path-segment]] の[[引数]]は仕様上は存在しますが、実際には [[path-segment]]
の不透明な一部分として特別扱いされずにいるように思えます。 [[HTTP]] 仕様との整合性で >>12
のような言及があるのでしょうが、実効性のある規定かは疑問です。

[14] [[大文字]]と[[小文字]]は区別され、元の状態を保存しなければ[['''なりません''']] [SRC[>>6]]。

[15] [[鯖]]は [CODE(CGI)@en[[[PATH_INFO]]]] の値に更に制限を課し、それに反するものを[[誤り]]としても[['''構いません''']]
[SRC[>>6]]。

[EG[
[16] 例えば [CODE(URI)[%2F]] と [CODE(URI)[[[/]]]] の区別が[[パーセント復号]]によって失われるので、
これを[[誤り]]としてはじいて [[CGIスクリプト]]に引き渡さなくても構いません。
]EG]

[17] [[非ASCII文字]]の扱いは[[システム定義]]です。 [SRC[>>6]]

[21] [[NULL]] ([[空文字列]]) の意味は明記されていませんが、 [[path]] 全体が [[CGIスクリプト]]を識別する場合、
[CODE(CGI)@en[[[PATH_INFO]]]] は必然的に空になります。

* パーセント符号化の取り扱い

[27] [[RFC]] は、値は[[パーセント符号化]]されていない [SRC[>>6]] としています。

[1] [NCSA] ではこの変数はサーバーが ([[URI符号化]]を) 復号した値にするべき (should) と述べていましたが、 [COAR 03] は何も述べていません。しかしながら、 CGI メタ変数から URI を作る節で [CODE(CGI)[PATH_INFO]] を URI 符号化した値を使うことになっていますから、暗黙のうちに復号を要求しています。

[2] 実際には [[Apache]] はじめどの実装も復号するはずです。たぶん。

[19] [[パーセント復号]]するという仕様は [[CGIスクリプト]]の手間や実装漏れの発生を[[鯖]]側で吸収しようとしたものでしょう。
手軽に[[CGIスクリプト]]を書くためにはそれも良かったのでしょうが、正確な[[Request-URI]]
を[[CGIスクリプト]]側で決定できないことによる [[URL]] 設計の制約などから、
現在では不便な仕様と考えられることが多いようです。

[28] [CODE[HTTP::Request::AsCGI]] は、[[ソースコード]]の[[コメント]]で、
[[パーセント復号]]する仕様は問題があるとしつつも、
[[Apache]] や [[lighttpd]] がそうしているとして、[[RFC]] 通りすべての[[パーセント符号化]]を[[復号]]しています。

* 処理

[24] [[CGIスクリプト]]は [CODE(CGI)@en[[[PATH_INFO]]]] を処理するつもりがないときは
[CODE(HTTP)[[[404]]]] [[応答]]により拒絶するべきです。 [SRC[>>23]]

* セキュリティー

[405] [CODE(CGI)@en[[[PATH_INFO]]]] や [CODE(CGI)@en[[[PATH_TRANSLATED]]]] や
[CODE(CGI)@en[[[SCRIPT_NAME]]]] を扱うときは、空の [[path segment]] ([CODE(URI)[//]])
や特別な [[path segment]] ([CODE(URI)[[[.]]]] や [CODE(URI)[[[..]]]])
の扱いに注意するべきです。 [[OS]] に渡す必要があるときは削除する、あるいは[[誤り]]として
[CODE(HTTP)@en[[[404]]]] を返すなどの処置を行うべきです。 [SRC[>>23]]
[CODE[[[CON]]]] など [[DOS]] で特別な意味を持つ[[ファイル名]]が含まれるとき、
[[非ASCII文字]]など[[ファイル・システム]]や[[ロケール]]によって正しく扱えない可能性がある[[文字]]が含まれるときなども同様に注意が必要です。

[26] 古い [[CGIスクリプト]]を中心に、 [CODE(CGI)@en[[[PATH_INFO]]]] を気にしていないことがよくあります。
[[URL]] に基づくアクセス制御などとの関係で、意図せぬ [[URL]] で [[CGIスクリプト]]にアクセスできてしまうことは、
セキュリティー上の問題につながるかもしれません。 (そのため >>24 の通り、
利用するつもりがなければ拒むべきです。)

* 歴史

[FIG(quote)[
[FIGCAPTION[
[7] 6.1.6. PATH_INFO (経路情報) (CGI/1.1 draft 03)
]FIGCAPTION]
> The PATH_INFO metavariable specifies a path to be interpreted
   by the CGI script. It identifies the resource or sub-resource
   to be returned by the CGI script, and it is derived from the
   portion of the URI path following the script name but
   preceding any query data. The syntax and semantics are similar
   to a decoded HTTP URL 'path' token (defined in RFC 2396 [4]),
   with the exception that a PATH_INFO of "/" represents a single
   void path segment.

PATH_INFO (経路情報) メタ変数には、 CGI スクリプトにより解釈される
経路を指定します。これは CGI スクリプトが返す資源または副資源を
識別するものであり、 URI 経路のうちスクリプト名に続く、
問合せ (query) データの前の部分から得たものです。
構文と意味は復号した HTTP URL 「path」(経路)字句 (RFC 2396 で定義)
と同様ですが、例外として 「/」という PATH_INFO は
単一空経路部分を表します。

    PATH_INFO = "" | ( "/" path )
    path      = segment *( "/" segment )
    segment   = *pchar
    pchar     = <any CHAR except "/">

The PATH_INFO string is the trailing part of the <path>
component of the Script-URI (see section 3.2) that follows the
SCRIPT_NAME portion of the path.

PATH_INFO 文字列は [[Script-URI]] (第3.2節参照) の <path> (経路)
部品の、 [[SCRIPT_NAME]] 部分の後の部分です。

Servers MAY impose their own restrictions and limitations on
what values they will accept for PATH_INFO, and MAY reject or
edit any values they consider objectionable before passing
them to the script.

サーバーは PATH_INFO にいかなる値を受け付けるかという自身の制限を
課しても'''構いません'''し、スクリプトに渡す前に宜しくないと思う
値を却下したり編集したりしても'''構いません'''。

Servers MUST make this URI component available to CGI scripts.
The PATH_INFO value is case-sensitive, and the server MUST
preserve the case of the PATH_INFO element of the URI when
making it available to scripts.

サーバーはこの URI 部品を CGI スクリプトから利用可能にし
'''なければなりません'''。 PATH_INFO 値は大文字・小文字を区別し、
サーバーはスクリプトから利用可能とする時に、
URI の PATH_INFO 要素の大文字・小文字を保存し'''なければなりません'''。
]FIG]

* 実装

[406] [[HTTP::Request::AsCGI]] は与えられた [[URL]] の [[path]] 全体を [CODE(CGI)@en[[[PATH_INFO]]]]
に含めます。 ([CODE[[[SCRIPT_NAME]]]] は [CODE[[[/]]]] で固定です。) 

* 関連

[20] [CODE(CGI)@en[[[PATH_INFO]]]] を[[ファイル・システム]]上の [[path]]
に写像した [CODE(CGI)@en[[[PATH_TRANSLATED]]]] も存在します。

*メモ


[18] 当初 [[CGIスクリプト]]への引数は [CODE(CGI)@en[[[QUERY_STRING]]]] から受け取るのが一般的でしたが、
2000年代の初め頃からそのような [[URL]] は汚いものとみなされるようになり、
しばしば [CODE(CGI)@en[[[PATH_INFO]]]] が使われるようになっていきました。

その場合であっても本来は [[path]] の一部として[[資源]]を識別するとみなせるものは [CODE(CGI)@en[[[PATH_INFO]]]]
に、それ以外は引き続き [CODE(CGI)@en[[[QUERY_STRING]]]] に含めるのが意味的には正しいのでしょうが、
[CODE(CGI)@en[[[QUERY_STRING]]]] を過度に忌避して [CODE(CGI)@en[[[PATH_INFO]]]] に無理に詰め込むような使い方をする人も出てきました。

[3] [[IIS]] は正しい [CODE(CGI)[PATH_INFO]] をくれないことがあるそうです。 

[5] [CITE[Apache2 + mod_perl2 の仕様と正しく mod_perl2 を使うための方法 - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech]]
([TIME[2010-12-22 10:30:07 +09:00]] 版)
<http://subtech.g.hatena.ne.jp/cho45/20101221/1292941055>

[25] [[Twiggy]] は[[要求URL]]として[[絶対URL]]が指定されると、それをすべて
[CODE(CGI)@en[[[PATH_INFO]]]] とするようです。 ([CODE(CGI)@en[[[SCRIPT_NAME]]]]
は[[空文字列]]になります。) [TIME[2014-11-01T09:49:14.400Z]]