
[1] [[CGI]] の[[メタ変数]] [DFN[[CODE(CGI)[REQUEST_URI]]]]
には、[[クライアント]]から送られてきた[[要求]]の
[CODE(ABNF)[[[Request-URI]]]] (最初の行の真ん中に書かれる
[[URI参照]]の一部または全部 
(どの部分かはプロトコルの仕様によります。))
の値が入ります。

* 仕様書

[REFS[
- [14] [[RFC 3050]] ([[SIP CGI]])
- [15] [CITE[PSGI - search.cpan.org]] ([TIME[2012-02-16 22:39:56 +09:00]] 版) <http://search.cpan.org/dist/PSGI/PSGI.pod#The_Environment>
]REFS]

* Request-URI

[13] このメタ変数は、 [[SIP]] の CGI では標準化されています
([[RFC 3050]]) が、 [[HTTP]] の CGI では標準ではありません。
[CODE(CGI)[[[SCRIPT_NAME]]]] や [CODE(CGI)[[[QUERY_STRING]]]]
などから再構成できる (できた) からです。しかし、
実際の HTTP CGI スクリプトの処理では本当にクライアントから送られてきた
[CODE(ABNF)[Request-URI]] がそのまま手に入ると便利なことが多々あります (>>6)。
そのためかどうかは存じませんが、 [[Apache]] などは
[CODE(CGI)[REQUEST_URI]] も提供してくれます。

[6] [CODE(CGI)[REQUEST_URI]] がないと、
- [CODE(ABNF)[[[Script-URI]]]] は得られても
[CODE(ABNF)[Request-URI]] は得られない
- [CODE(ABNF)[Script-URI]] ≒ [CODE(ABNF)[Request-URI]]
な場合に限定するとしても、 [[URI符号化]]も含めて正確な元の文字列は得られない
- 複数のメタ変数を組合せるのは面倒い

ので不便なことがあります。

[5]
メタ変数 [CODE(CGI)[REQUEST_URI]]
は HTTP CGI では非標準ながらも一定の地位を得ており、
デファクト標準と見なしてよいのではないでしょうか。
しかし、標準でない以上実装していない鯖を責めることは当然できません。
[[CGIスクリプト]]は [CODE(CGI)[REQUEST_URI]]
があればこれを利用し、なければ他のメタ変数を組合せるのがよいでしょう。

[19] [CODE(perl)@en[HTTP::Request::AsCGI]] は[[要求URL]] の [F[pathquery]]
を [CODE(CGI)@en[REQUEST_URI]] とします。

[17] 
[[WSGI]] やその派生仕様には明示的に含まれていませんが、 [[PSGI]]
では明示的に定義されています。[[パーセント復号]]するべきではないと規定されています。 [SRC[>>16]]

[20] [CODE(HTTP)@en[OPTIONS]] [[要求]]で[[要求対象]]が [CODE[*][要求対象]]
の時、 [CODE(CGI)@en[REQUEST_URI]] をどう設定するべきかは定かではありません。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[16] RFC 3050 (SIP-CGI/1.1) 5.5.1.13 REQUEST_URI
]FIGCAPTION]

>This metavariable is specific to requests made with SIP.

このメタ変数は、 SIP
で作られた要求に特有です。

        REQUEST_URI  =  absoluteURI  ; defined in RFC 2396 [9]

>If the message triggering the script was a request, this variable
indicates the URI specified with the request method.  This
metavariable is only defined if REQUEST_METHOD is defined; in that
case, servers MUST provide it to scripts.

スクリプトの引き金となったメッセージが要求である時には、
この変数は要求 method
と一緒に指定された [[URI]]
を示します。このメタ変数は
[CODE(CGI)[[[REQUEST_METHOD]]]]
が定義されている時のみ定義されます。
その場合サーバーはこの変数をスクリプトに提供しなければ '''なりません'''。

>This metavariable fills the roles of HTTP CGI's
SCRIPT_NAME, PATH_INFO, and 
QUERY_STRING.

この変数は、 HTTP CGI
での [CODE(CGI)[[[SCRIPT_NAME]]]],
[CODE(CGI)[[[PATH_INFO]]]],
[CODE(CGI)[[[QUERY_STRING]]]]
の役割を担っています。
]FIG]

* 実装

[4] [[w3m]] の [[local CGI]] 機能を使って呼出された CGI スクリプトでも [CODE(CGI)[REQUEST_URI]] が得られます。 Apache と似たように、 [CODE(URI)[file:///cgi-bin/foo.cgi]] なら [CODE(URI)[/cgi-bin/foo.cgi]] が得られるみたいです。

[10] [[Apache]] 2.2.3 の [[mod_rewrite]] を使っているのですが、[CODE[[[RewriteRule]]]]
そのものでもその中で参照する [CODE(CGI)@en[[[REQUEST_URI]]]] 
([CODE@en[%{[[REQUEST_URI]]}]], [CODE@en[%{ENV:[[REQUEST_URI]]}]]) でも、
[CODE(URI)@en[[[%2B]]]] が [CODE(char)[[[+]]]] に [[percent-decode]]
されてしまいます。(同じ [[Apache]] でも [[CGI]]
の中で [CODE(CGI)@en[[[REQUEST_URI]]]] を参照するとちゃんと [CODE(URI)@en[[[%2B]]]]
のままになっています。)

[11] >>10 [CODE@en[[[SetEnvIf]]]] なら正しい [CODE(CGI)@en[[[REQUEST_URI]]]]
がとれるので、そこで値を取得して、 [CODE@en[[[RewriteRule]]]]
の中でその[[環境変数]]を [[query]] に埋め込む ([[path]] だと余計に [[percent-encode]]
されるからだめ!) というまわりくどいことをしたら回避できましたwwwwww
ただしこの版の [[Apache]] では [E] オプションを指定できないので、
[[percent-encode]] されないで [[query]] に埋め込まれますwwwww

[12] [[HTTP::Request::AsCGI]] もこの[[メタ変数]]を設定します。

* 例

- HTTP CGI
--[2] [SAMP(CGI)[/path/to/cgi/path/info?query]]
--[7] [SAMP(CGI)[http://foo.example/path]]
- SIP CGI
--[8] [SAMP(CGI)[sip:foo@bar.example]]

*メモ

[3] HTTP CGI スクリプトの作者は、この CGI メタ変数が現時点では非標準のものであることに注意するべきです。この変数が色々な環境で将来にわたって利用可能かどうかは未知数ですから、得られなかった場合は [CODE(CGI)[[[PATH_INFO]]]] とか [CODE(CGI)[[[QUERY_STRING]]]] とかで代替する策を練っとかないといけません。[WEAK[もっとも、 SIP CGI で標準化された以上、 HTTP CGI でもこのメタ変数を使わないのも惜しいってものです(謎)。]]

[18] [[HTTP/2]] には[[要求行]]がなく、複数の[[疑似ヘッダー]]で表現されますから、
[[サーバー]]はその値を組み合わせたものを[[CGIスクリプト]]に渡すことになります。
この処理はどこでも規定されていませんから、どのように行われるかは定かではありません。
単純な文字列連結で[[絶対URL]]を得たものかもしれませんし、
何らかの[[正規化]]が行われるかもしれません。あるいは [[URL scheme]]
や [[authority]] が含まれない可能性もなくはありません。

[FIG(quote)[
[FIGCAPTION[
[21] [CITE@en[mod_rewrite - Apache HTTP Server Version 2.5]]
([TIME[2017-08-18 17:24:45 +09:00]])
<https://httpd.apache.org/docs/trunk/mod/mod_rewrite.html#RewriteCond>
]FIGCAPTION]

> REQUEST_URI
> The path component of the requested URI, such as "/index.html". This notably excludes the query string which is available as its own variable named QUERY_STRING.

]FIG]
