[5] [[CGI]] の[[メタ変数]]群 [DFN[[CODE(CGI)[HTTP_[VAR[*]]]]]]
は、[[クライアント]]から送られてきた[[要求メッセージ]]中の[[頭欄]]を[[鯖]]が
[[CGIスクリプト]]に提供するためのものです。

* 仕様書
[REFS[
- [25] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] 
-- [7] '''<http://tools.ietf.org/html/rfc3875#section-4.1.18>'''
-- [26] <http://tools.ietf.org/html/rfc3875#section-9.2>
- [28] [CITE@en[PEP 333 -- Python Web Server Gateway Interface v1.0]] ([TIME[2012-02-16 21:06:34 +09:00]] 版) <http://www.python.org/dev/peps/pep-0333/#environ-variables>
- [29] [CITE@en[File: SPEC '''[''''Rack Documentation'''']''']] ([TIME[2010-01-11 00:57:50 +09:00]] 版) <http://rack.rubyforge.org/doc/SPEC.html>
- [30] [CITE[jack - jsgi spec]] ([TIME[2009-09-04 16:47:22 +09:00]] 版) <http://jackjs.org/jsgi-spec.html#the_environment>
- [31] [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]

* 名前

[6]
[CODE(CGI)[HTTP_[VAR[*]]]] の [CODE(CGI)[[VAR[*]]]]
の部分は、[[頭欄]]の[[名前]]をすべて[[大文字]]にし、
[CODE(HTTP)[-]] が含まれていればすべて [CODE(CGI)[_]]
に置き換えたものとなります。 [SRC[>>7]]

[EG[
[20] 例えば、
[CODE(HTTP)[[[Accept]]:]] 欄に対応する[[メタ変数]]名は
[CODE(CGI)[[[HTTP_ACCEPT]]]] となりますし、
[CODE(HTTP)[[[If-Modified-Since]]:]] 欄に対応するものは
[CODE(CGI)[[[HTTP_IF_MODIFIED_SINCE]]]] となります。
]EG]

[33] [CODE(HTTP)[[[_]]]] が元々[[頭欄]]の[[名前]]に含まれている場合どうしたらいいのでしょう・・・。

* 値

[13] 各 [CODE(CGI)[HTTP_[VAR[*]]]] [[メタ変数]]の値には、
[[クライアント]]からの [[HTTP]] [[要求]]の[[頭欄]]の[[欄本体]]がそのまま入れられます。
ただし、次に示すものも含め、意味的に等価な変形を行なって構わないことになっています。 [SRC[>>7]]

- [21] 同じ名前の[[頭欄]]が複数あれば、 [CODE[[[,]]]] で連結することによって1つにしなければ[['''なりません''']]。
- [22] [[欄本体]]が複数行で表されていれば ([[折り畳み]])、一行に直さなければ[['''なりません''']]。
- [23] [[メタ変数]]として適当になるように[[文字コード]]変換などを適宜行わなければ[['''なりません''']]。

;; [24] [CODE(HTTP)@en[[[Accept-Language]]]] と [CODE(HTTP)@en[[[Accept_language]]]] のように本来別の[[頭欄]]が命名規則のために衝突する場合や、
複数の値を [CODE(HTTP)[,]] によって意味的に等価でありつつ連結できない場合 
[WEAK[(本来それは [[HTTP]] 違反ですが、しばしばあります。)]] にどうするべきかは規定されていません。
後者については実際には[[頭欄]]の種類ごとに処理を分ける意味もないでしょうから、
何も考えずに連結しているものと思われます。

* 提供されないことが多い頭欄

[14] 鯖はすべての[[頭欄]]をこの形の[[メタ変数]]として提供する必要はありません。
[SRC[[[RFC 3875]] 4.1.18]] 特に [CODE(CGI)[[[CONTENT_TYPE]]]]
([CODE(HTTP)[[[Content-Type]]]]) 
など他に[[メタ変数]]が用意されているもの、
[CODE(HTTP)[[[Authorization]]]] など安全上好ましくないもの、
[CODE(HTTP)[[[Connection]]]] など通信にのみ関係するものは提供されないかもしれません。

[11] >>9 に規定されているように、鯖は CGI スクリプトに要求メッセージのすべての頭欄を
[CODE(CGI)[HTTP_[VAR[*]]]] メタ変数を通じて提供する必要はありません。
多くの実装では、次の頭欄は提供されません。

,HTTP 頭欄                     ,代替メタ変数
,[CODE(HTTP)[[[Authorization]]]],[CODE(CGI)[[[AUTH_[VAR[*]]]]]]
,[CODE(HTTP)[[[Content-Length]]]],[CODE(CGI)[[[CONTENT_LENGTH]]]]
,[CODE(HTTP)[[[Content-Type]]]],[CODE(CGI)[[[CONTENT_TYPE]]]]

[3] >>9 つまり、 CGI 的には [CODE(CGI)[HTTP_AUTHORIZATION]] と かが提供されていて''も''問題がないということです。

[4] >>3 でも [[Apache]] は提供してくれません。

[39] 
このようないびつな仕様は、 [[CGI/1.0]] 時代に [CODE[HTTP_[VAR[*]]]] 
が存在しなかったことに由来するものです。 (>>17)


[10] CGI メタ変数はほとんどの環境では[[環境変数]]として実装されていますが、
環境変数が安全でない環境も少なくありません。
その鯖の任意の利用者が環境変数の値を見ることができるかもしれません。
CGI で昔から認証系の頭欄が提供されないことになっているのはそのような事情があります。

[27] [CODE(HTTP)@en[[[Authorization:]]]] の他、 [CODE(HTTP)@en[[[Proxy-Authorization:]]]]
も安全上注意が必要であり、提供しないことも検討するべきだと指摘されています [SRC[>>26]]。

[35] [[サーバー]]によっては、 [CODE[HTTP_PROXY]] [[環境変数]]に関する[[脆弱性]]を防ぐため、
[CODE(HTTP)@en[Proxy:]] [[ヘッダー]]があっても [CODE(CGI)@en[HTTP_PROXY]]
[[メタ変数]]を省略するようです。
[CODE[Proxy:]] は通常使われないので、
この挙動は[[環境変数]]を使うすべての実装で推奨されます。
[SEE[ [[HTTP_PROXY]] ]]


[32] [[WSGI]] と派生仕様は [CODE(CGI)@en[[[HTTP_*]]]] は [[HTTP]] [[要求]]の[[頭欄]]に対応するべきであるとしており、
[CODE(CGI)@en[[[CONTENT_TYPE]]]] と [CODE(CGI)@en[[[CONTENT_LENGTH]]]] を除き、
一部の[[頭欄]]を引き渡さないことは原則として認められていないようです。 [SRC[>>28, >>29, >>30, >>31]]

[40] [[WSGI]] 等は[[環境変数]]と異なる安全な方法で[[アプリケーション]]に[[メタ変数]]を引き渡しますから、
保安に関する要件も緩められていると考えられます。

[38] 
[[SIP CGI]] は他の手段で取得できるものも含めすべての[[ヘッダー]]を 
[CODE[SIP_[VAR[*]]]]
で提供する[SHOULD[べき]]と定めています。 [SRC[>>36]]
[[HTTP CGI]]
よりはかなり強い要件 (原則として提供する) となっていますが、
それでもなぜか提供しない余地を残しています。

* 歴史

[17] [CODE(CGI)[HTTP_[VAR[*]]]] メタ変数群を使った[[要求]]中の一般の[[頭欄]]を
[[CGIスクリプト]]に提供する方法は [[CGI/1.1]]
で導入されました。 [[CGI/1.0]] では [CODE(CGI)[[[CONTENT_TYPE]]]]
や [CODE(CGI)[[[HTTP_ACCEPT]]]] など一部の[[頭欄]]のみが提供されていました。

** [NCSA] での説明
[6]
>In addition to these, the header lines received from
the client, if any, are placed into the environment
with the prefix HTTP_ followed by the header name.
Any - characters in the header name are changed to _
characters. The server may exclude any headers which
it has already processed, such as Authorization,
Content-type, and Content-length. If necessary, the
server may choose to exclude any or all of these
headers if including them would exceed any system
environment limits. 

これら [INS[(訳注: 他の CGI メタ変数群)]]
に加えて、クライアントから受け取った[[頭行]]があれば、
これが接頭辞 [CODE(CGI)[HTTP_]]
で始まって頭名が続く環境[INS[変数]]に入れられます。
頭名中の [CODE(HTTP)[[[-]]]]
はすべて [CODE(CGI)[[[_]]]]
に変更します。
サーバーは既に処理した頭、
例えば [CODE(HTTP)[Authorization]],
[CODE(HTTP)[Content-type]],
[CODE(HTTP)[Content-length]]
は除いても構いません。
必要なら、サーバーはこうした頭の一部又は全部を含めるとシステムの環境制限を越える時には除いても構いません。

**RFC 3875 (CGI/1.1)

[7] [[RFC 3875]] 4.1.18 節を参照。

* セキュリティー

[15] [[要求メッセージ]]の[[頭欄]]には安全上注意して扱うべき情報が含まれていることもあります。
>>10 のように実装方法によっては[[メタ変数]]は安全ではないので、
>>14 の通り危険な情報は提供しないなどの注意を[[鯖]]は払う必要があります。

[16] ただし >>15 のような配慮が可能なのは、
注意するべき[[頭欄]]の種類をあらかじめ[[鯖]]が把握している場合だけです。
[SAMP(HTTP)[X-Foo-Private-Information: some-important-thing]]
のような[[頭欄]]を使っていると、[[鯖]]が[[メタ変数]]を生成し、
それによって [[CGI]] が使われている環境にアクセス可能な第三者に盗み見られる危険性があります。

もちろん、[Q[盗み見]]ることができる権限があるのが信頼できる限定された人だけである場合など、
必ずしも危険であるわけではありません。
このようなシステムの設計者は使用するシステムの技術的・
運用上の性質によく注意して、
安全性と技術的な実装の簡単さや技術的整合性のバランスが取れるようにしなければなりません。

[9] [CODE(CGI)[HTTP_]] から始まる名前の[[環境変数]]を参照する[[プログラム]]や[[ライブラリー]]を利用する際には、
[[メタ変数]]が[[環境変数]]として設定された状態のまま呼び出してしまうことが無いよう、
注意する必要があります。

;; [8] [CODE@en[[[http_proxy]]]] も参照してください。

[34] [[環境変数]] [CODE[WWW_HOME]] の意味で [CODE[HTTP_HOME]] が使われることがあります。

* 関連

** HTTP/TLS、HTTP/SSL (HTTPS)

[12]
[[SSL]] や [[TLS]] の上で [[HTTP]] 通信を行っている場合
(いわゆる [[HTTPS]]) であっても、
[[HTTP]] であることには変わりありませんので、
[[TCP]] 上の [[HTTP]] と同じ名前で同じように[[メタ変数]]が提供されます。
(ただし実装によってはより安全を配慮した形になっているかもしれません。)
実装によっては [[SSL]] や [[TLS]] 
によって得られた情報が別の[[メタ変数]]を通じて提供されています。

[DEL[
- [1] 方式 (scheme) が [[https:]] だったら ''HTTPS_[VAR[*]]'' になるんでしょうか。そんなの見たこと無いなあ。
- [2] >>1 そんなことはないです。 HTTP over SSL でも [CODE(CGI)[HTTP_[VAR[*]]]] になります。
]DEL]

[19] [[HTTPS]] であることは[[メタ変数]] [CODE(CGI)@en[[[HTTPS]]]] によって表されます。

** [CODE[SIP_[VAR[*]]]] メタ変数

[18] [[SIP CGI]] では [[SIP]] [[要求メッセージ]]は[[メタ変数]]
[DFN[[CODE(CGI)@en[SIP_[VAR[*]]]]]] として提供されます。

[37] 
[CODE(CGI)[SIP_[VAR[*]]]]
[[メタ変数]]群は、 [[SIP]] 
[[要求]]の[[頭欄]]が反映されるもので、
[[HTTP CGI]] では
[CODE(CGI)[HTTP_[VAR[*]]]]
メタ変数群に相当します。


[FIG(quote)[ [36] [[RFC 3050]] (SIP-CGI/1.1) 5.5.1.5 Protocol-Specific Metavariables
>These metavariables are specific to the protocol via which the method
is sent.  Interpretation of these variables depends on the value of
the SERVER_PROTOCOL metavariable (see section 5.5.1.20).

これらのメタ変数群は、
method が送信されたプロトコルに特有のものです。
これらの変数の解釈は
[CODE(CGI)[[[SERVER_PROTOCOL]]]]
メタ変数の値に依存します。

>Metavariables with names beginning with "SIP_" contain values from
the message header, if the protocol used was SIP.  Each SIP header
field name is converted to upper case, has all occurrences of "-"
replaced with "_", and has "SIP_" prepended to form the metavariable
name.  Similar transformations are applied for other protocols.  The
header data MAY be presented as sent by the client, or MAY be
rewritten in ways which do not change its semantics.  If multiple
header fields with the same field-name are received then the server
MUST rewrite them as though they had been received as a single header
field having the same semantics before being represented in a
metavariable.  Similarly, a header field that is received on more
than one line MUST be merged into a single line.  The server MUST, if
necessary, change the representation of the data (for example, the
character set) to be appropriate for a CGI metavariable.

名前が [CODE(CGI)[SIP_]]
から始まるメタ変数群には、
使用されているプロトコルが SIP
である時にメッセージ頭からの値を設定します。
各 SIP 頭欄名は大文字に変換され、
全ての [CODE(SIP)[-]]
を [CODE(CGI)[_]]
に置換し、 [CODE(CGI)[SIP_]]
を頭につけてメタ変数名を形成します。
同様の変換が他のプロトコルにも適用されます。
頭データはクライアントから送られたままにしても'''構いません ([[MAY]])'''
し、その意味を変更しない範囲で書き換えても'''構いません (MAY)'''。
同じ欄名の複数の頭欄を受信した時は、
サーバーはメタ変数として表現する前にこれを書き換えて同じ意味を持つ単一の頭欄を受信したようにしなければ'''なりません ([[MUST]])'''。
同様に、複数行で受信した頭欄は単一行に併合しなければ'''なりません (MUST)'''。
サーバーは、必要であれば、
データの表現 (例えば[[文字集合]])
を変更して CGI
メタ変数として適切なものとしなければ'''なりません (MUST)'''。

> Note: these metavariables' names were changed from HTTP_*
to SIP_* since the first draft of this specification.  The
intention had been to make it easier to use existing CGI
libraries unmodified, but this convenience was felt to be
outweighed by the confusion this introduced.

注意: これらのメタ変数群の名前は、
この仕様書の最初の原案から、
[CODE(CGI)[HTTP_*]] から
[CODE(CGI)[SIP_*]] に変更しました。
その意図は、既存の CGI
ライブラリを修正せずに使用することを用意とすることにありますが、
この便宜はこれが招く混乱より価値があると感じられます。

>Servers are not required to create metavariables for all the message
header fields they receive.  However, because of the relatively high
importance of headers in SIP for messages' semantic content, the
server SHOULD provide all headers which do not contain potentially
sensitive authorization information, such as Authorization.  Servers
SHOULD provide protocol-specific metavariables even for information
which is available through other SIP CGI metavariables, such as
CONTENT_LENGTH and CONTENT_TYPE.

サーバーに対してその受信した全てのメッセージ頭欄に関してメタ変数を作成することは要求していません。
しかし、 SIP においてメッセージの意味内容に頭が比較的高い重要性を持つことから、
サーバーは繊細な認証情報を含む可能性がある
[CODE(SIP)[Authorization]] のようなものの他は全ての頭欄を提供する'''べきです ([[SHOULD]])'''。
サーバーは、他の SIP CGI
メタ変数、例えば [CODE(CGI)[[[CONTENT_LENGTH]]]]
や [CODE(CGI)[[[CONTENT_TYPE]]]]
から利用可能な情報であっても、
プロトコル特有メタ変数を提供する'''べきです (SHOULD)'''。

> This allows a SIP CGI script to determine, if necessary,
whether the information in the other metavariables was in
the original message, or was synthesized by the server.

これによって SIP CGI
が必要であれば他のメタ変数の情報が元のメッセージにあったものか、
それともサーバーが生成したものかを判断できます。

]FIG]



** [CODE[HTTP_[VAR[*]]]] 環境変数

[12] 
:[CODE(CGI)[[[HTTP_[VAR[*]]]]]]:[[Apache]] をはじめ多くの [[CGI]]
の実装で、 [CODE(CGI)[[[HTTP_[VAR[*]]]]]] 
[[メタ変数]] (>>5) は同名の[[環境変数]]として実装されています。
:[CODE[[[HTTP_HOME]]]]:[[w3m]] など [[Webブラウザ]]類で[[ホーム頁]]の
[[URI]] を指定する[[環境変数]]として使われています。
:[CODE[[[HTTP_PROXY]]]]:[[w3m]] など [[WWW]]
系プログラムで利用するべき[[串]]を指定する[[環境変数]]として使われています。
