meta-variables

メタ変数 (CGI)

[1] CGIメタ変数 (meta-variable) は、 要求についての情報をからCGIスクリプトに提供するものです。 一般的にはオペレーティング・システム環境変数として実装されています。

仕様書

定義

[36]

からスクリプトに情報を伝達する名前付き引数オペレーティング・システム環境変数として実装するのが最も一般的ですが、 必ずしもそうである必要はありません。

>>35

名前

[22] メタ変数には名前があります。変数名は大文字・小文字不区別です。 CGI 仕様においては大文字_ の正準形で表されていますが、 実際の名前はシステム定義となっています。 >>38

[40] 大文字小文字以外の変形について仕様上は明確に述べられているわけではありませんが、 SERVER_NAMEserver-name, serverName, SERVER.NAME, SERVER NAME など一定の規則で変形させたものもシステムごとの表現の範囲内として認められるものと思われます。

[42] 構文上はプロトコルURL scheme 依存、あるいは CGI 本体仕様に含まれない拡張されたメタ変数の名前として token で使えるすべての文字が使えることになっています。また、 長さ制限もありません。 >>38

[43] しかし実際には英数字_ 以外が含まれるメタ変数は使われていなそうです。

[48] 実装定義メタ変数を設定して構いません。その名前は X_ で始まるべきです>>38

値の構文

[53] メタ変数の値は一般に

      meta-variable-value = "" | 1*<TEXT, CHAR or tokens of value>
... と定義されています >>38。更に個別のメタ変数ごとに更に詳細な構文が定義されています。

[54] 実質的に *OCTET と同じですが、そうなっていないのは、 オクテット列でなく文字の列であ (りオクテット表現はシステム定義であ) ることや、 メタ変数によっては単純なオクテット列ではなく構造を持った列であることを意識しているのでしょう。

[52] 大文字小文字は一般に区別されます。

値の授受

[39] からCGIスクリプトへどのようにCGIメタ変数を引き渡すかはシステム定義です >>38

[51] メタ変数の値の文字をどのように表現するかはシステム定義です。 はその表現に変換しなければなりません>>38

[21] サーバーはスクリプトにメタ変数を渡す方法を用意しなければなりません。 多くの実装では環境変数として渡されます。

[18] WinCGI ではINIファイルを使ってメタ変数を渡していたそうです。 (INI のファイル名は CGI スクリプトの第1引数となります。) (WinCGI が他の点でちゃんと CGI に適合するのかは知りませんが。)

[41] 一般的には予め環境変数として設定した後にCGIスクリプトを起動するため、 CGIスクリプトではすべてのメタ変数の値が (利用するかどうかに関わらず) 取得可能なように実装されていますが、 メタ変数メソッド呼び出しの形で実装されている場合など、 CGI の実装方法次第では値の決定が遅延されて必要に応じて行われることもあり得ます。

空の値

[50] CGI では空文字列のことを NULL といいます。更に、空文字列と値が無い、 値が設定されていないことを区別しません。

[4] HTTP CGI では歴史的に両者を基本的には区別しませんが、 SIP CGI ではその区別を要求しています。

[58] QUERY_STRING, SCRIPT_NAME に関しては例外 (かもしれない) 規定があります。

非妥当な値

[56] メタ変数はそれぞれの構文と意味が規定されていますが、クライアントからの要求によってそれが定まる場合、 クライアントプロトコルの仕様に従っていない場合にはメタ変数も同様に仕様に従っていないこともあります。

[57] RFC にはそのような場合にどうするべきか明記されていませんが、 わざわざ HTTP への適合性を細かく検査してからCGIスクリプトを呼び出したりは (特に側の処理で必要がない限り) しないでしょうから、そのような値がそのままCGIスクリプトに渡ってくることはよくあります。

プロトコル非依存のメタ変数

[44] GATEWAY_INTERFACE, REMOTE_ADDR, SERVER_NAME など、 CGI、あるいはクライアントの情報を提供するメタ変数や、 CONTENT_TYPE など要求についての情報を提供するメタ変数があります。

[55] RFC 3875 としてはプロトコル非依存のつもりで書いているのでしょうが、実際には HTTP の強く依存しており、 SIP CGI とは矛盾した要件も存在しています。 (SIP CGI の方が追い越して先に RFC になっているにも関わらず、整合性はありません。)

プロトコル依存のメタ変数

[45] URL scheme と同名のメタ変数や、URL scheme またはプロトコルの名前から始まるメタ変数も存在します。 >>38 そのようなメタ変数は、当該プロトコル特有の情報を提供します。

[59] プロトコルURL scheme に依存したメタ変数を設定するべきです。 その解釈は SERVER_PROTOCOL に示されたプロトコルの版に拠ります。 >>60

[5] 次のものがあります。

[46] 例えば HTTP というプロトコルにおいては、 HTTP_USER_AGENT という名前のメタ変数HTTP 要求メッセージUser-Agent: の値を提供することになっています。

[61] URL schemeプロトコルが異なるときに URL scheme と同名のメタ変数を非 NULL 値に設定して構いません>>60

[47] また、 https: という URL scheme (で表現される HTTP/TLS) が使われている時には HTTPS という名前のメタ変数が定義されることになっています。

[8] 次のものがあります。

[66] WSGI とその派生仕様は、 wsgi.url_scheme のような URL scheme を直接提供する変数を (CGI 由来の変数とは別に) 提供しています。

[9] SSL / TLS に関する情報は、 SSL_* という名前のメタ変数に設定されます。

実装

Apache

AmigaDOS

[62] AmigaDOS ではメタ変数は同名の環境変数としてCGIスクリプトに渡されます。 CGIスクリプトからは DOS ライブラリーGetVar() によりアクセスできます。 flags 引数0 とするべきです大文字・小文字不区別ですが、区別するシステムとの互換性ために大文字を使うべきです。 >>63

Unix, EBCDIC/POSIX

[64] UnixPOSIX 互換のシステムではメタ変数は同名の環境変数として CGIスクリプトに渡されます。 CGIスクリプトからは C ライブラリーgetenv()変数 environ によりアクセスできます。 >>63 大文字小文字は区別されます。

Windows

[65] Windows ではメタ変数は同名の環境変数としてCGIスクリプトに渡されます。 大文字・小文字不区別ですが、区別するシステムとの互換性のために大文字を使うべきです。

狭義の CGI 以外

[16] 元々の CGI の他に、 WSGIPSGIP6W などの派生仕様でも、 メタ変数の仕組みが継承されています。ただし、細かくはそれぞれの規定があって、 統一されていません。

CGI も参照。

[24] Apache では要求の処理の際にメタ変数環境変数と設定され、 CGI に限らず用いられています。 httpd.conf.htaccess指令 (mod_rewriteRewriteRule など) や、 mod_perlPerlスクリプトmod_phpPHPスクリプトなどからも環境変数が参照されます。

[72] A Guide to the Internet Connection Servers - SG244805.PDF, , http://ps-2.kev009.com/rs6000/redbook-cd/SG244805.PDF#page=284

[73] >>72 IBMICAPICGIと同じメタ変数を採用。

メタ変数の一覧

[7]

1.1SIP名前実装
ALL_HTTP
ALL_RAW
API_VERSION
AUTH_PASS
AUTH_PASSWORD
AUTH_TYPE
AUTH_USER
CERT_COOKIE
CERT_FLAGS
CERT_ISSUER
CERT_KEYSIZE
CERT_SECRETKEYSIZE
CERT_SERIALNUMBER
CERT_SERVER_ISSUER
CERT_SERVER_SUBJECT
CERT_SUBJECT
CHARSET[Russian Apache]
CHARSET_DETERMINED_BY[Russian Apache]
CHARSET_HTTP_METHOD[Russian Apache]
CHARSET_NOREDIRECT[Russian Apache]
CHARSET_SERVER_NAME[Russian Apache]
CHARSET_SERVER_PORT[Russian Apache]
CLIENT_CERT_ENCODING
CONN_REMOTE_ADDR
CONTENT_LENGTH
CONTENT_TYPE
DATE_GMT[SSI]
DATE_LOCAL[SSI]
DOCUMENT_NAME[SSI]
DOCUMENT_PATH_INFO[SSI]
DOCUMENT_ROOT[Apache]
DOCUMENT_URI[SSI]
DOCUMENT_URL
FCGI_DATA_LENGTH[FastCGI]
FCGI_LISTEN_QUEUE[FastCGI]
FCGI_PROCESS_ID[FastCGI]
FCGI_ROLE[FastCGI]
FCGI_SOCKET_PATH[FastCGI]
FILE_LAST_MOD[FastCGI]
FORCE_CHARSET[Russian Apache]
FORCE_SOURCE_CHARSET[Russian Apache]
GATEWAY_INTERFACE
HTTP_*
HTTPS[Apache]
HTTPS_*
HTTPS_KEYSIZE
HTTPS_SECRETKEYSIZE
HTTPS_SERVER_ISSUER
HTTPS_SERVER_SUBJECT
IBM_CCSID_VALUE
INSTANCE_ID
IS_SUBREQ[Apache]?
LAST_MODIFIED[SSI]
LOCAL_ADDR
LOCAL_COOKIE[w3m] 廃止
LOCAL_COOKIE_FILE[w3m]
MOD_PERL[mod_perl]
PATH_INFO
PATH_TRANSLATED
PERL_SEND_HEADER[mod_perl]
QUERY_STRING
QUERY_STRING_UNESCAPED[SSI]
REDIRECT_ERROR_NOTES[Apache]
REDIRECT_FORCE_CHARSET[Russian Apache]
REDIRECT_FORCE_CHARSET_CHARSET[Russian Apache]
REDIRECT_PATH*
REDIRECT_REQUEST_METHOD[Apache]
REDIRECT_QUERY_STRING*
REDIRECT_SCRIPT_URI[Apache]
REDIRECT_SCRIPT_URL[Apache]
REDIRECT_STATUS[Apache]*
REDIRECT_URL[Apache]*
??REGISTRATIONS
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_PASSWORD
REMOTE_PORT[Apache]
REMOTE_USER
REQUEST_FILENAME
REQUEST_METHOD
REQUEST_SCHEME
??REQUEST_TOKEN
REQUEST_URI
RESPONSE_REASON
??RESPONSE_STATUS
??RESPONSE_TOKEN
ROOT
SCGI
??SCRIPT_COOKIE
SCRIPT_DIRECTORY[Protozilla]
SCRIPT_FILENAME[Apache] など
SCRIPT_NAME
SCRIPT_URI[Apache]
SCRIPT_URL[Apache]
SERVER_ADDR
SERVER_ADMIN[Apache]
SERVER_NAME
SERVER_PORT
SERVER_PORT_SECURE
SERVER_PROTOCOL
SERVER_SIGNATURE[Apache]
SERVER_SOFTWARE
SERVER_URL[Netscape]
SIP_*
SOURCE_CHARSET[Russian Apache]
SSL_*
SSL_CIPHER[Apache]
SSL_CIPHER_ALGKEYSIZE[Apache]
SSL_CIPHER_EXPORT[Apache]
SSL_CIPHER_USEKEYSIZE[Apache]
SSL_CLIENT_A_KEY[Apache]
SSL_CLIENT_A_SIG[Apache]
SSL_CLIENT_CERT[Apache]
SSL_CLIENT_CERT_CHAINn[Apache]
SSL_CLIENT_I_DN[Apache]
SSL_CLIENT_I_DN_C[Apache]
SSL_CLIENT_I_DN_CN[Apache]
SSL_CLIENT_I_DN_D[Apache]
SSL_CLIENT_I_DN_Email[Apache]
SSL_CLIENT_I_DN_G[Apache]
SSL_CLIENT_I_DN_I[Apache]
SSL_CLIENT_I_DN_L[Apache]
SSL_CLIENT_I_DN_O[Apache]
SSL_CLIENT_I_DN_OU[Apache]
SSL_CLIENT_I_DN_S[Apache]
SSL_CLIENT_I_DN_ST[Apache]
SSL_CLIENT_I_DN_T[Apache]
SSL_CLIENT_I_DN_UID[Apache]
SSL_CLIENT_M_SERIAL[Apache]
SSL_CLIENT_M_VERSION[Apache]
SSL_CLIENT_S_DN[Apache]
SSL_CLIENT_S_DN_C[Apache]
SSL_CLIENT_S_DN_CN[Apache]
SSL_CLIENT_S_DN_D[Apache]
SSL_CLIENT_S_DN_Email[Apache]
SSL_CLIENT_S_DN_G[Apache]
SSL_CLIENT_S_DN_I[Apache]
SSL_CLIENT_S_DN_L[Apache]
SSL_CLIENT_S_DN_O[Apache]
SSL_CLIENT_S_DN_OU[Apache]
SSL_CLIENT_S_DN_S[Apache]
SSL_CLIENT_S_DN_ST[Apache]
SSL_CLIENT_S_DN_T[Apache]
SSL_CLIENT_S_DN_UID[Apache]
SSL_CLIENT_V_END[Apache]
SSL_CLIENT_V_START[Apache]
SSL_CLIENT_VERIFY[Apache]
SSL_PROTOCOL[Apache]
SSL_SERVER_A_KEY[Apache]
SSL_SERVER_A_SIG[Apache]
SSL_SERVER_CERT[Apache]
SSL_SERVER_I_DN[Apache]
SSL_SERVER_I_DN_C[Apache]
SSL_SERVER_I_DN_CN[Apache]
SSL_SERVER_I_DN_D[Apache]
SSL_SERVER_I_DN_Email[Apache]
SSL_SERVER_I_DN_G[Apache]
SSL_SERVER_I_DN_I[Apache]
SSL_SERVER_I_DN_L[Apache]
SSL_SERVER_I_DN_O[Apache]
SSL_SERVER_I_DN_OU[Apache]
SSL_SERVER_I_DN_S[Apache]
SSL_SERVER_I_DN_ST[Apache]
SSL_SERVER_I_DN_T[Apache]
SSL_SERVER_I_DN_UID[Apache]
SSL_SERVER_M_SERIAL[Apache]
SSL_SERVER_M_VERSION[Apache]
SSL_SERVER_S_DN[Apache]
SSL_SERVER_S_DN_C[Apache]
SSL_SERVER_S_DN_CN[Apache]
SSL_SERVER_S_DN_D[Apache]
SSL_SERVER_S_DN_Email[Apache]
SSL_SERVER_S_DN_G[Apache]
SSL_SERVER_S_DN_I[Apache]
SSL_SERVER_S_DN_L[Apache]
SSL_SERVER_S_DN_O[Apache]
SSL_SERVER_S_DN_OU[Apache]
SSL_SERVER_S_DN_S[Apache]
SSL_SERVER_S_DN_ST[Apache]
SSL_SERVER_S_DN_T[Apache]
SSL_SERVER_S_DN_UID[Apache]
SSL_SERVER_V_END[Apache]
SSL_SERVER_V_START[Apache]
SSL_SESSION_ID[Apache]
SSL_SRP_USERApache
SSL_SRP_USERINFOApache
SSL_TLS_SNIApache
SSL_VERSION
SSL_VERSION_INTERFACE[Apache]?
SSL_VERSION_LIBRARY[Apache]
THE_REQUEST
TIME[Apache]?
TIME_DAY[Apache]?
TIME_HOUR[Apache]?
TIME_MIN[Apache]?
TIME_MON[Apache]?
TIME_SEC[Apache]?
TIME_YEAR[Apache]?
URI_DATA[Protozilla]
URI_HOST[Protozilla]
URI_POST[Protozilla]
URI_SPEC[Protozilla]
URL
USER_NAME[Apache]*
W3M_*[w3m]*
X_*
X_IS_PRIVATE_ADDR[Apache]

これは CGI メタ変数ではない!

[14] よく CGI 環境変数として取り上げられるが CGI とは関係のない (たまたま設定されているだけの) 変数:

[15] こういうのを CGI 環境変数として挙げているような解説は参考にしない方が身のためです。

実装ごとの提供メタ変数

[13]

name
メタ変数
rfc
RFC 3875
wsgi
WSGI
psgi
PSGI
starman
Starman (PSGI)
twiggy
Twiggy (PSGI)
ascgi
HTTP::Request::AsCGI
name
GATEWAY_INTERFACE
ascgi
rfc
name
SERVER_SOFTWARE
ascgi
rfc
name
REMOTE_ADDR
ascgi
starman
twiggy
rfc
name
REMOTE_HOST
ascgi
starman
rfc
SHOULD
name
REMOTE_PORT
ascgi
starman
name
HTTPS
ascgi
wsgi
TLS 利用時 SHOULD
name
SSL_PROTOCOL
wsgi
TLS 利用時 SHOULD
name
SERVER_PROTOCOL
psgi
ascgi
starman
twiggy
wsgi
rfc
name
REQUEST_METHOD
psgi
ascgi
starman
twiggy
wsgi
rfc
name
REQUEST_URI
psgi
ascgi
starman
twiggy
name
SERVER_NAME
psgi
ascgi
starman
twiggy
wsgi
rfc
name
SERVER_PORT
psgi
ascgi
starman
twiggy
wsgi
rfc
name
SCRIPT_NAME
psgi
ascgi
starman
twiggy
wsgi
必要に応じて
rfc
必要に応じて
name
PATH_INFO
psgi
ascgi
starman
twiggy
wsgi
必要に応じて
rfc
必要に応じて
name
PATH_TRANSLATED
rfc
必要に応じて SHOULD
name
QUERY_STRING
psgi
ascgi
starman
twiggy
wsgi
必要に応じて
rfc
必要に応じて
name
HTTP_*
psgi
必要に応じて
ascgi
必要に応じて
starman
必要に応じて
twiggy
必要に応じて
wsgi
必要に応じて
rfc
必要に応じて
name
HTTP_HOST
ascgi
psgi
必要に応じて
starman
必要に応じて
twiggy
必要に応じて
wsgi
必要に応じて
rfc
必要に応じて
name
CONTENT_TYPE
psgi
必要に応じて
ascgi
必要に応じて
starman
必要に応じて
twiggy
必要に応じて
wsgi
必要に応じて
rfc
必要に応じて
name
CONTENT_LENGTH
psgi
必要に応じて
ascgi
必要に応じて
starman
必要に応じて
twiggy
必要に応じて
wsgi
必要に応じて
rfc
必要に応じて
name
AUTH_TYPE
rfc
必要に応じて
name
REMOTE_USER
rfc
必要に応じて
name
REMOTE_IDENT
rfc
MAY

メモ

CGI の肝はメタ変数。メタ変数の説明次第で CGI 解説文がトンデモかどうか判断できる。

  • [6] よく、「CGI 環境変数の説明」などと称して、色々な環境変数の一覧を示している文書があります。そしてそのような文書にはたいてい、 TZ のようにたまたまそのサーバーで設定されていただけの環境変数が載っていたりします。筆者がちゃんとわかっているかを判断する一つの材料となります。
  • [7] また、 >>6 ほどではありませんが重要なポイントとして、一般的な CGI のめた変数と、 HTTP_* のめた変数をきちんと区別して扱っているかも要注意でしょう。厳しいことを言えば、このメタ変数群と HTTP 頭欄の関係に全く触れていなければその時点で HTTP CGI の説明として失格です。
  • [11] 環境変数はブラウザが送ると思っている人がいます。仕組みを知らない証拠です。

memo

[2] [NCSA] では環境変数とされていましたが、 [COAR] では CGI の普及を反映して、 より汎用的にメタ変数と呼んでいます。 Un|xWindoze のような環境で、 ApacheIIS などを使っている場合など、 ほとんどの場合においてはメタ変数の手段として環境変数が使われますから、 現在でも環境変数で情報を伝えていると表現することは間違いではありませんが、 特に実装に依存した話をする場合以外は [COAR] を尊重してメタ変数と呼ぶのがよいとおもいます。 RFC3050 もメタ変数と呼んでいます。

[3] メタ変数は、サーバーから CGI スクリプトへの情報伝達にのみ使われます。 変数の値を変更しても、サーバーの動作などに影響は出ません。 (メタ変数の手段によっては変更すること自体できないかもしれません。)

[49] HTTP CGI であっても、 NULL と値なしは 「実装依存」であって、 適当でよいわけではありません。 例えばサーバーはある時 QUERY_STRING

[31] mod_rewrite - shima111の日記 ( 版) http://d.hatena.ne.jp/shima111/20070125/p1

[67] ESI Language Specification 1.0 ( ( 版)) http://www.w3.org/TR/esi-lang

[68] XQuery 3.0: An XML Query Language ( ( 版)) http://www.w3.org/TR/xquery-30/#dt-environment-variables

[69] Bash specially-crafted environment variables code injection attack | Red Hat Security ( ( 版)) https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/

[10] specifications/spore_implementation.pod at master · SPORE/specifications ( 版) https://github.com/SPORE/specifications/blob/master/spore_implementation.pod#the-request-environment

[12] Bash specially-crafted environment variables code injection attack | Red Hat Security ( ( 版)) https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/

[25] XPath and XQuery Functions and Operators 3.1 () https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/#func-environment-variable

[26] Remove parse error on NULLs from input stream preprocessing stage (inikulin著, ) https://github.com/whatwg/html/commit/8fa65b73575ed692ec7f75665bde32134acc4dd6

[27] EventSource: ignore IDs with U+0000 by annevk · Pull Request #2849 · whatwg/html () https://github.com/whatwg/html/pull/2849

[28] Make U+0000 a parse error in bogus comment and bogus DOCTYPE states (zcorpan著, ) https://github.com/whatwg/html/commit/5a6fef58056832140fecf1580ca815f385730cec

[29] Parse errors on NULLs in bogus comment. · Issue #2684 · whatwg/html () https://github.com/whatwg/html/issues/2684

[30] Make U+0000 a parse error in bogus comment and bogus DOCTYPE states by zcorpan · Pull Request #2939 · whatwg/html () https://github.com/whatwg/html/pull/2939

[70] Editorial: Clarify what happens to U+0000 chars (sideshowbarker著, ) https://github.com/whatwg/html/commit/05d0ae71e82871e2fd1785829d180218da83abe7

[71] Editorial: Clarify what happens to U+0000 chars by sideshowbarker · Pull Request #2968 · whatwg/html () https://github.com/whatwg/html/pull/2968