CGI1.1で、HTTP(S)サーバからCGIスクリプトに渡される変数

# 発端
* HTTP(S)サーバから受け取れる変数で、PHPに限らず他の言語でも使用できる（はずの）ものを把握しておくため。
* [PHPの$_SERVER](http://php.net/manual/ja/reserved.variables.server.php)で使える変数の一覧みたいなのが欲しかった。

# [RFC3875 CGI/1.1](https://tools.ietf.org/html/rfc3875) で定義されてる変数一覧
## AUTH_TYPE
* 例えばBASIC認証やDigest認証などの「認証」を使用した場合は、「どんな認証の仕方をしたか」を特定するためにsetしなければいけない。（**MUST**）
* HTTP(S)リクエストの場合は、authentication フィールドの値を使う。

## CONTENTS_LENGTH
* message-bodyがある場合は、その長さ。
* message-bodyない場合は、NULLにするか、キーそのものを設定しない。
* message-body本体のlegthを反映するように、適宜、transfer-codingなどを取り除く。

## CONTENT_TYPE
*  HTTP Requestで、Content-Typeフィールドが渡された場合は、必ず存在する。
*  [RFC2046 Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types ](https://tools.ietf.org/html/rfc2046)を使う。

## GATEWAY_INTERFACE
基本的に、"CGI/1.1"だと思っておけばいい。
 普段ほとんど使わないと思う。

## PATH_INFO
* SCRIPT_NAMEの後ろに続く、パス情報。
* **[Apache2 だと、デフォルトで「無効」](https://httpd.apache.org/docs/2.2/ja/mod/core.html#acceptpathinfo)**にされている。

## PATH_TRANSLATED

* この変数を使ったCGIスクリプトは、portabilityを下げるので、使用**非推奨**。
* PATH_INFOの内容やis_setに合わせなければいけない。

>  If PATH_INFO is NULL, then the    PATH_TRANSLATED variable MUST be set to NULL (or unset).

[PHPでは、以下の様な注意が書かれてたりする。](http://php.net/manual/ja/reserved.variables.server.php)
> 注意: PHP 4.3.2 以降、PATH_TRANSLATED は、 Apache 2 SAPI において暗黙のうちに設定されなく なりました。一方、Apache 1 では、この値が Apache により設定されない場合、 SCRIPT_FILENAME と同じ値に設定されます。 この変更は、PATH_TRANSLATED は PATH_INFO が定義されている場合のみ 存在するべきであるという CGI の規約を満たすために 行われました。

## QUERY_STRING
**MUST be set**

* [URIのquery](https://tools.ietf.org/html/rfc3986#section-3.4)が入る。
* URIに使用できる文字とかの影響をもろに受けるので、注意が必要。
* 常に存在し、HTTP Request URIにqueryが存在しなかった場合でも、空文字列が代入された状態でなければいけない。
* 逆に言うと、isset($_SERVER['QUERY_STRING']) だと事故るので、注意が必要。

>  The server MUST set this variable; if the Script-URI does not include a query component, the QUERY_STRING MUST be defined as an empty string ("").

## REMOTE_ADDR
**MUST be set**

* 常に存在する。
* Cacheでリバースプロキシとかが入っているときは注意したほうがいいかも。

## REMOTE_HOST
* [FQDN](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&cad=rja&uact=8&ved=0ahUKEwjqzejhoZ_MAhXBnqYKHRBjAVgQFggrMAM&url=https%3A%2F%2Fja.wikipedia.org%2Fwiki%2FFully_Qualified_Domain_Name&usg=AFQjCNHd-dL8CHR2kzTwtyV84eC0yZXFRQ&sig2=idCJQZTnynrB0AUMTAo1FQ)で表現される。
* 可能な限り、HTTP(S)サーバは設定すべき、らしい。
* PHPだと、HTTP(S)サーバから渡されないと、キーが存在しなくなる。
* **[Apache2のデフォルトは、生成しない。](https://httpd.apache.org/docs/2.0/ja/mod/core.html#hostnamelookups)**

> The server SHOULD set this variable.
> If the hostname is not
   available for performance reasons or otherwise, the server MAY
   substitute the REMOTE_ADDR value.

## REMOTE_IDENT
* 現在では実用不可能。

## REMOTE_USER
* 認証したユーザ。

## REQUEST_METHOD
**MUST be set**

> The REQUEST_METHOD meta-variable **MUST be set** to the method which should be used by the script to process the request,

だそうです。

## SCRIPT_NAME
**MUST be set**

>  The SCRIPT_NAME variable **MUST be set to** a URI path **(not URL-encoded)** which could identify the CGI script

だそうです。

## SERVER_NAME
**MUST be set**

> The SERVER_NAME variable **MUST be set** to the name of the server host to which the client request is directed.  
> A deployed server can have more than one possible value for this variable, where several HTTP virtual hosts share the same IP address. In that case, the server would use the contents of the request's Host header field to select the correct virtual host. 

要するに、この変数（PHPなら$_SERVER['SERVER_NAME']）を参照することで、たとえ同じIPアドレス上で動いている別々のWebアプリケーションだったとしても、区別できるようにしてくださいねー、ということ。だと思う。
多分ないと思うけど、「複数のWebサーバが動くサーバインスタンス」をスケールアウトしたりすると、IPアドレスとSERVER_NAMEとの関連がより希薄になってくるので、正しく設定して、各HTTP(S)サーバとCGI InvokerのIdentityを確保しましょう、ということかなぁと思う。

## SERVER_PORT
**MUST be set**

> The SERVER_PORT variable **MUST be set** to the TCP/IP port number on which this request is received from the client.
> **This value is used in the port part of the Script-URI.**

キャッシュのためのリバースプロキシとかが入っていると、8000とか8080とか8888とかになってたりもするので、注意した方がいい。

## SERVER_PROTOCOL
**MUST be set**
 [細かいこと](https://tools.ietf.org/html/rfc3875#section-4.1.16)を気にしなければ、そのまま使えばいいと思う。大抵、意図通りに取れる。

## SERVER_SOFTWARE
**MUST be set**
 正直、何に使うのかよくわかってない。HTTP(S)サーバ側に依存する処理を、CGIに書くなって感じある。依存するんなら、mod_phpとかで完全に依存し、PHP_SAPIとかで判別したほうが楽だし便利だろう。

# 参考文献
[RFC 3875 The Common Gateway Interface (CGI) Version 1.1](https://tools.ietf.org/html/rfc3875) 
[RFC 3986 Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986)