INTERNET-DRAFT Ken A L Coar
draft-coar-cgi-v11-03.{html,txt} IBM Corporation
D.R.T. Robinson
E*TRADE UK Ltd.
25 June 1999

The WWW Common Gateway Interface
Version 1.1

この翻訳に関する注意

この文書は、服部憲雄が個人的興味により翻訳したものである。 改変、配布等、無制限に使用可能である。 誤訳を修正された方は、反映させていただきたいので御連絡頂けると有り難い。

正式な文書は原文であり、 この翻訳の正確さは疑わしく、保証などできない。 引用や参考にする場合は、原文を用いた方がよく、この文書は補助的なものとして扱うべきである。 服部憲雄は正確さを追求する努力はするが、これを要求されないものとする。

公開されているdraftは、 http://www.ietf.org/internet-drafts/draft-coar-cgi-v11-03.txtミラーサイト等から取得できる。 この文書は公開されているdraftの原文に当たるものを翻訳した為、 付加情報(改変履歴、コメント文(<!--..-->)等)が含まれている。 しかし、draftの翻訳として機能している為、何ら気にする必要はない。

このメモの位置付(Status of this Memo)

このドキュメントはInternet-Draftであり、RFC2026第10章の全条項に順応している。

Internet-Draftは、Internet Engineering Task Force(IETF)と、 その領域、及びその管理グループによる作業ドキュメントである。 他のグループがInternet-Draftとして作業ドキュメントを 配布するかもしれない点に注意。

Internet-Draftは、最大6ヶ月間有効なdraft(草稿)ドキュメントであり、 他のドキュメントにより更新、交換、廃棄がいつでも起こりうる。 Internet-Draftを「作業中(work in progress)」と記載せず、資料として参照、引用 する事は適切ではない。

最新のInternet-Draftリストは、 <http://www.ietf.org/ietf/1id-abstracts.txt> から取得できる。

Internet-Draftのミラーリストは、 <http://www.ietf.org/shadow.html> である。

概論(Abstract)

Common Gateway Interface(CGI)は、プラットフォームに依存しない情報サーバ下で、 外部プログラム、ソフトウェア、ゲートウェイを実行する為の、シンプルなインタフェイスである。 現在、サポートされている情報サーバは、HTTPサーバである。

このインタフェイスは、1993年以来World-Wide Webにより使用されてきた。 この仕様書は、合衆国国際センターのスーパーコンピューティングアプリケーション[NCSA-CGI]として開発され、 ドキュメント化された、「CGI/1.1」インタフェイスの「現在の慣習的な(current practice)」要素を定義する。 このドキュメントでは、UnixとAmigaDOS(tm)システム上でのCGI/1.1インタフェイスの使用法も定義する。

このdraftの議論は、CGI-WGメイリングリスト上で行われる。 メイリングリストの詳細とプロジェクトの状態は、Web page <URL:http://Web.Golux.Com/coar/cgi/> を参照のこと。

改訂履歴(Revision History)

この草稿の改訂履歴は、削除文字や色コードによるWeb上のGUI表記で管理されている。 以下はカラーテキスト原書からの詳細な履歴である。

改訂00版 1998年5月28日リリース
改訂01版 1998年12月28日リリース
Major structure change: Section 4, "Request Metadata (Meta-Variables)" was moved entirely under Section 7, "Data Input to the CGI Script." Due to the size of this change, it is noted here and the text in its former location does not appear as struckthrough. This has caused major sections 5 and following to decrement by one. Other large text movements are likewise not marked up. References to RFC 1738 were changed to 2396 (1738's replacement).
改訂02版 1999年4月2日リリース
Added text to section 8.3 defining correct handling of HTTP/1.1 requests using "chunked" Transfer-Encoding. Labelled metavariable names in section 8 with the appropriate detail section numbers. Clarified allowed usage of Status and Location response header fields. Included new Internet-Draft language.
改訂03版 1999年6月25日リリース
Changed references from "HTTP" to "Protocol-Specific" for the listing of things like HTTP_ACCEPT. Changed 'entity-body' and 'content-body' to 'message-body.' Added a note that response headers must comply with requirements of the protocol level in use. Added a lot of stuff about security (section 11). Clarified a bunch of productions. Pointed out that zero-length and omitted values are indistinguishable in this specification. Clarified production describing order of fields in script response header. Clarified issues surrounding encoding of data. Acknowledged additional contributors, and changed one of the authors' addresses.

目次一覧(Table of Contents)

  1 序論(Introduction)
   1.1 目的(Purpose)
   1.2 要求事項(Requirements)
   1.3 仕様(Specifications)
   1.4 用語解説(Terminology)
  2 表記上の慣習と一般的な文法(Notational Conventions and Generic Grammar)
   2.1 拡張BNF記法(Augmented BNF)
   2.2 基本規則(Basic Rules)
  3 プロトコルパラメータ(Protocol Parameters)
   3.1 URLエンコード(URL Encoding)
   3.2 スクリプトURI(The Script-URI)
  4 スクリプトの実行(Invoking the Script)
  5 CGIスクリプトのコマンドライン(The CGI Script Command Line)
  6 CGIスクリプトへのデータ入力(Data Input to the CGI Script)
   6.1 メタデータリクエスト(メタ変数)(Request Metadata (Metavariables))
    6.1.1 AUTH_TYPE
    6.1.2 CONTENT_LENGTH
    6.1.3 CONTENT_TYPE
    6.1.4 GATEWAY_INTERFACE
    6.1.5 プロトコル特有のメタ変数(Protocol-Specific Metavariables)
    6.1.6 PATH_INFO
    6.1.7 PATH_TRANSLATED
    6.1.8 QUERY_STRING
    6.1.9 REMOTE_ADDR
    6.1.10 REMOTE_HOST
    6.1.11 REMOTE_IDENT
    6.1.12 REMOTE_USER
    6.1.13 REQUEST_METHOD
    6.1.14 SCRIPT_NAME
    6.1.15 SERVER_NAME
    6.1.16 SERVER_PORT
    6.1.17 SERVER_PROTOCOL
    6.1.18 SERVER_SOFTWARE
   6.2 メッセージボディリクエスト(Request Message-Bodies)
  7 CGIスクリプトからのデータ出力(Data Output from the CGI Script)
   7.1 非解析ヘッダ出力(Non-Parsed Header Output)
   7.2 解析ヘッダ出力(Parsed Header Output)
    7.2.1 CGIヘッダフィールド(CGI header fields)
     7.2.1.1 Content-Type
     7.2.1.2 Location
     7.2.1.3 Status
     7.2.1.4 拡張ヘッダフィールド(Extension header fields)
    7.2.2 HTTPヘッダフィールド(HTTP header fields)
  8 サーバの実装(Server Implementation)
   8.1 サーバの要求事項(Requirements for Servers)
    8.1.1 スクリプトURI(Script-URI)
    8.1.2 要求されるメッセージボディの処理(Request Message-body Handling)
    8.1.3 要求されるメタ変数(Required Metavariables)
    8.1.4 要求されるレスポンス(Response Compliance)
   8.2 サーバの推奨事項(Recommendations for Servers)
   8.3 メタ変数の概要(Summary of Metavariables)
  9 スクリプトの実装(Script Implementation)
   9.1 スクリプトの要求事項(Requirements for Scripts)
   9.2 スクリプトの推奨事項(Recommendations for Scripts)
  10 システムの仕様(System Specifications)
   10.1 AmigaDOS
   10.2 Unix
  11 セキュリティへの配慮(Security Considerations)
   11.1 安全なメソッド(Safe Methods)
   11.2 機密情報を含むHTTPヘッダフィールド(HTTP Header Fields Containing Sensitive Information)
   11.3 スクリプトのサーバへの妨害(Script Interference with the Server)
   11.4 データの長さとバッファへの配慮(Data Length and Buffering Considerations)
   11.5 状態を保存しない処理(Stateless Processing)
  12 謝辞(Acknowledgments)
  13 参考文献(References)
  14 著者のアドレス(Authors' Addresses)

1. 序論(Introduction)

1.1. 目的(Purpose)

HTTP[3,8]サーバとCGIスクリプトは協力して、 クライアントリクエストに応答する。 クライアントリクエストは、Universal Resource Identifier(URI)[1]、 リクエストメソッド、トランスポートメカニズムにより提供されたリクエストに関する様々な補助情報により 構成される。

CGIは、メタ変数として知られている、クライアントリクエストを記述する 抽象的な変数を定義する。 具体的なプログラマインタフェイスと共に、 スクリプトとHTTPサーバの間で特定のプラットフォームに依存しない事も記載する。

1.2. 要求事項(Requirements)

この仕様書は、RFC 1123[5]と同じ言葉を使用し、 それぞれ特別な要求の意味を定義している。 以下が其れである。

する必要がある(MUST)

この言葉、又は形容詞「要求(required)」は、仕様の絶対必要項目を意味する。

すべきである(SHOULD)

この言葉、又は形容詞「推奨(recommended)」は、特別な環境において正当な理由が存在するなら、 この項目を無視できる事を意味する。 但し、完全に意味を理解し、異なる振る舞いを選ぶ前に慎重に調節すべきである。

するほうがよい(MAY)

この言葉、又は形容詞「随意(optional)」は、通例、随意項目を意味する。 あるベンダーは、正確さが要求される市場ではこれが必要である為、この項目を入れるかもしれないし、 他のベンダーは、製品を拡張する形で、同じ項目を省略するかもしれない。

実装しているプロトコルの要求事項が、一つ以上「必要である(must)」を 満足していない場合、その実装は仕様に対応していない事になる。 「完全対応(unconditionally compliant)」と呼ばれる実装の為には、 全ての「必要である(must)」と全ての「すべき(should)」を満足している必要がある。 全ての「必要である(must)」を満足しており、全ての「すべき(should)」を満足していない場合、 「暫定対応(conditionally compliant)」と呼ばれる事になる。

1.3. 仕様(Specifications)

CGIの機能と特徴を全てではないが、この仕様書の主要部で定義している。 以下の慣用句は、具体的ではない特徴を記述する事に使用される。

システムによる定義(system defined)

特徴がシステム間で異なるかもしれないが、 同じシステムでは実装を同じにしなければならない。 システムは通常、オペレーティングシステムの種類に関係する。 一部のシステムは、このドキュメントの第10章にて定義される。 新しいシステムは、このドキュメントの改訂時に新しく定義されるだろう。

実装による定義(implementation defined)

特徴は実装により異なるが、特別な実装は特徴を文書にする必要がある。

1.4. 用語解説(Terminology)

この仕様書は、HTTP/1.1仕様書[8]内にて定義された、 多くの用語を使用する。 しかしながら、ここで使用されている以下の用語は、 そのドキュメント中の定義や通例の意味と、意味が一致しないかもしれない。

メタ変数(metavariable)

サーバからスクリプトへ情報を運ぶ変数を、このように呼称する。 多くの一般的なオペレーティングシステムで、これは環境変数であるのだが、 必ずしも環境変数であるとは限らない。

スクリプト(script)

このインタフェイス経由で、サーバに呼ばれるソフトウェアの事。 スタンドアロンプログラムである必要はなく、動的ロード又は共有ライブラリ、 又はサーバ内のサブルーチンかもしれない。 用語「スクリプト(script)」として頻繁に理解されている、 実行時に翻訳されるステートメントセットであるかもしれないが、 それは要求事項ではなく、この仕様書の文脈内におけるこの用語は、更に広い定義として用いられる。

サーバ(server)

リクエストを供給する為に、スクリプトを呼び出すアプリケーションプログラムの事。

2. 表記上の慣習と一般的な文法(Notational Conventions and Generic Grammar)

2.1. 拡張BNF記法(Augmented BNF)

このドキュメント内の全ての構造仕様は、単純な文と、RFC 822[6]にて使用されている、 拡張バッカス・ナウアー型(Backus-Naur Form(BNF))と類似のもので記述されている。 この拡張BNFは、以下の構造を含んでいる。

名前 = 定義(name = definition)

イコール文字(「=」)により定義する。 ホワイトスペースは、インデントされた定義の継続行を意味するだけである。

"文字"("literal")

引用符(")はテキスト文字を囲む。 但し、山型括弧(「<」と「>」)により囲まれた引用符文字を除く。 通例、テキストは大文字小文字を区別する。

規則1 | 規則2(rule1 | rule2)

二者択一の規則は、垂直棒(「|」)によって区切られる。

(規則1 規則2 規則3)((rule1 rule2 rule3))

丸括弧によって囲まれた要素は、一つの要素として扱われる。

*規則(*rule)

アスタリスク(「*」)が前に置かれると、0回以上出現しうる規則となる。 アスタリスクの前に整数が置かれると、最小限度、 指定数が出現しなければならない規則となる。

[規則]([rule])

角括弧(「[」と「]」)により囲まれた要素は随意。

2.2. 基本規則(Basic Rules)

以下は、基本的な構文構造を記述する為に、 この仕様書の至る所で使用されている規則である。

    alpha         = lowalpha | hialpha
    alphanum      = alpha | digit
    lowalpha      = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h"
                    | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p"
                    | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
                    | "y" | "z"
    hialpha       = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H"
                    | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P"
                    | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X"
                    | "Y" | "Z"
    digit         = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7"
                    | "8" | "9"
    hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" | "a"
                    | "b" | "c" | "d" | "e" | "f"
    escaped       = "%" hex hex
    OCTET         = <全ての8-bitデータ>
    CHAR          = <全てのUS-ASCII文字(0 - 127の8bitデータ)>
    CTL           = <全てのUS-ASCIIコントロール文字(0 - 31の8bitデータ)とDEL(127)>
    CR            = <US-ASCII CR, 復帰(13)>
    LF            = <US-ASCII LF, 改行(10)>
    SP            = <US-ASCII SP, 空白(32)>
    HT            = <US-ASCII HT, 水平タブ(9)>
    NL            = CR | LF
    LWSP          = SP | HT | NL
    tspecial      = "(" | ")" | "@" | "," | ";" | ":" | "\" | <">
                    | "/" | "[" | "]" | "?" | "<" | ">" | "{" | "}"
                    | SP | HT | NL
    token         = 1*<CTLとtspecialを除く全てのCHAR>
    quoted-string = ( <"> *qdtext <"> ) | ( "<" *qatext ">")
    qdtext        = <<">とCTLを除きLWSPを含む全てのCHAR>
    qatext        = <"<"と">"とCTLを除きLWSPを含む全てのCHAR>
    mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
    unreserved    = alphanum | mark
    reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" |
                    "$" | ","
    uric          = reserved | unreserved | escaped

newline(NL)はシングル文字である必要がなく、文字列であり得る。

3. プロトコルパラメータ(Protocol Parameters)

3.1. URLエンコード(URL Encoding)

ここで使用される、いくつかの変数と構造は、「URLエンコード(URL-encoded)」として表現される。 このエンコーディングは、RFC 2396[4]内第2章に記述される。

空白文字を表現する為に「最も簡単な」エンコーディングがあり、それは一般に使用される。 URLエンコード値の中の、エンコードされた空白として「+」と「%20」の両方を認識する用意が、 スクリプトに必要である

注意: いくつかの危険な文字は、エンコードされている場合、異なる意味を持つかもしれない。 文字が危険となる定義は、その状況に依存する。 例えば、以下の2つのURLは、必ずしも同一のリソースを示すとは限らない。

    http://somehost.com/somedir%2Fvalue
    http://somehost.com/somedir/value

この問題を正確に扱うには、RFC 2396[4]の第2章を参照のこと。

3.2. スクリプトURI(The Script-URI)

「スクリプトURI(Script-URI)」は、メタ変数により認識されたリソースのURIとして定義される。 しばしば、このURIは、クライアントによるURIリクエスト(「クライアントURI(Client-URI)」)と同一となるだろう。 しかし、同一である必要はない。 その代わり、それは、サーバに呼ばれるURIであり、 サーバ内、及びCGIインタフェイスにおいてのみ使用され得る。

スクリプトURIは、RFC 1808[7]の第2.1章にて定義された、 基本RL(generic-RL)の文法を持つ。 例外として、以下の様な、オブジェクトパラメータや断片関係は許可されていない。

    <scheme>://<host><port>/<path>?<query>

スクリプトURIの多様な構成要素は、いくつかのメタ変数により定義される。 (第4章以降を参照)

    script-uri = protocol "://" SERVER_NAME ":" SERVER_PORT enc-script
                 enc-path-info "?" QUERY_STRING

「protocol」は、SERVER_PROTOCOLから、 「enc-script」は、SCRIPT_NAMEのURLエンコードバージョンから、 「enc-path-info」は、PATH_INFOのURLエンコードバージョンから取得される。 PATH_INFOメタ変数に関する詳細な情報は、第4.6章を参照。

注意: schemeとprotocolは同一ではない。 例えば、SSLメカニズムを経てアクセスされたリソースは、 「http」ではなく「https」スキーム(scheme)のクライアントURIを持つだろう。 スクリプトURIは、使用される基本プロトコルが含まれる為、 スクリプト用にこれを再構成するものは、CGI/1.1で提供しない。

4. スクリプトの実行(Invoking the Script)

スクリプトは、システムに定義された方法により呼び出される。 別の方法で指定されない限り、スクリプトを含むファイルは、 実行可能プログラムとして呼び出されるだろう。

5. CGIスクリプトのコマンドライン(The CGI Script Command Line)

いくつかのシステムは、文字列の配列をCGIスクリプトへ供給する為にメソッド(method)をサポートする。 これは、「インデックス付き」クエリーに関してのみ使用される。 これは、エンコードされていない「=」文字を含まないURLクエリー文字列と共に、 「GET」や「HEAD」HTTPリクエストにより認識される。 そのようなリクエストの為に、以下の規則を使用し、 語句内の検索文字列(search string)をサーバは解析すべきである。

    search-string = search-word *( "+" search-word )
    search-word   = 1*schar
    schar         = xunreserved | escaped | xreserved
    xunreserved   = alpha | digit | xsafe | extra
    xsafe         = "$" | "-" | "_" | "."
    xreserved     = ";" | "/" | "?" | ":" | "@" | "&"

解析後、各々の語句はURLデコードされ、 システムに定義された方法により随意エンコードされ、 そして、引数リストに語句リストがセットされる。

サーバが引数リストの一部を作成できなかったら、 サーバは、コマンドライン情報を全て生成すべきでない。 例えば、引数の数がオペレーティングシステムやサーバの許容範囲を越えて生成される場合や、 語句の一部が、引数で表現できない場合等。

スクリプトは、QUERY_STRINGの値がエンコードしていない「=」文字を含むか、 チェックすべきであり、 もしそうなら、コマンドライン引数を使用すべきではない

6. CGIスクリプトへのデータ入力(Data Input to the CGI Script)

異なる2つの所から来る、リクエストヘッダやそれのメッセージボディ等のリクエストに関して。 サーバは、この情報の一部をスクリプトが利用できるようする必要がある

6.1. メタデータリクエスト(メタ変数)(Request Metadata (Metavariables))

各種CGIサーバ実装は、サーバからスクリプトへ、 リクエストに関するデータを送る為のメカニズムを定義しなければならない。 メタ変数は、システムにより定義された方法で、スクリプトによりアクセスされるデータを含有する。 メタ変数内の文字の表現は、システムによる定義である。

この仕様は、ヌル値とエラー値の表記を区別しない。 どのようなヌル値やエラー値(クエリー要素「?」や「」のようなもの)でも、 実装による定義により、未定義メタ変数か、値が「」のメタ変数として表現される。

メタ変数の名前において、大文字小文字は重要ではなく、 大文字小文字のみ異なる名前で、異なる2つの変数は存在し得ない。 これらは、標準的に下線(「_」)を加えた、大文字の表記を使用する。 実際の名前の表現は、システムにより定義される。 特殊なシステム用の表現は、これとは異なる定義をしてもよい

メタ変数の値は、特別な場合を除き、大文字小文字を考慮する必要がある

この仕様書にて定義された、正規のメタ変数は以下。

    AUTH_TYPE
    CONTENT_LENGTH
    CONTENT_TYPE
    GATEWAY_INTERFACE
    PATH_INFO
    PATH_TRANSLATED
    QUERY_STRING
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_IDENT
    REMOTE_USER
    REQUEST_METHOD
    SCRIPT_NAME
    SERVER_NAME
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE

始めにプロトコル名、次に名前というメタ変数(例えば「HTTP_ACCEPT」)も、 ヘッダフィールドリクエストの記述内にて許可される。 これらのフィールドの数と意味は、この仕様書に関係なく変更され得る。 (第6.1.5章も参照。)

6.1.1. AUTH_TYPE

この変数は、「http」スキームを経て作成されたリクエストを表す。

スクリプトURIが外部アクセス用のアクセス認証を要求したら、 「auth-scheme」トークンからこの変数の値を、 リクエストの「Authorization」ヘッダフィールドへ、 サーバはセットしなければならない。 そうでなければ、NULLにセットされる。

    AUTH_TYPE   = "" | auth-scheme
    auth-scheme = "Basic" | "Digest" | token

HTTPアクセス認証スキームは、HTTP/1.1仕様書[8]の第11章に記述される。 auth-schemeは大文字小文字を区別しない。

リクエストヘッダに、認証された「Authorization」フィールドが含まれる場合、 サーバはこのメタ変数をスクリプトへ供給しなければならない

6.1.2. CONTENT_LENGTH

このメタ変数は、リクエストに添えられた、メッセージボディの内容物のサイズがセットされる。 8bit単位の10進数で表す。 添付データが無い場合、このメタ変数は、NULLか未定義のどちらかである。 HTTP「Content-Length」ヘッダフィールド (HTTP/1.1仕様書[8]の第14.14章)用と同じ文法である。

    CONTENT_LENGTH = "" | 1*digit

メッセージボディの内容が添付されるリクエストならば、 サーバは、このメタ変数をスクリプトへ提供する必要がある

6.1.3. CONTENT_TYPE

リクエストにメッセージボディが含まれる場合、 リクエストヘッダ内の「Content-type」フィールドを経て提供された、 若しくは、「Content-type」フィールドによって供給されない場合は、サーバが決定した、 添付物のInternet Media Type[9]がCONTENT_TYPEにセットされる。 HTTP「Content-type」ヘッダフィールド用と同じ文法である。

    CONTENT_TYPE = "" | media-type
    media-type   = type "/" subtype *( ";" parameter)
    type         = token
    subtype      = token
    parameter    = attribute "=" value
    attribute    = token
    value        = token | quoted-string

type、subtype、parameter属性名は、大文字小文字を区別しない。 parameterの値は、大文字小文字を区別するほうがよい。 media typeやHTTP内で使用されるものは、 HTTP/1.1仕様書[8]の第3.7章に記述されている。

例:

    application/x-www-form-urlencoded

この変数のデフォルト値はない。 セットされていない場合においてのみ、スクリプトは受信データから、 メディアタイプを確定する試みをする方がよい。 タイプが不明なままである場合、スクリプトは、 content-typeをapplication/octet-streamと仮定するか、 415(「Unsupported Media Type」)エラーと共にリクエストを却下してもよい。 エラーステータス戻り値に関する詳細な情報は、第7.2.1.3章を参照。

オリジナルリクエストヘッダ内に「Content-Type」フィールドが存在した場合、 サーバはこのメタ変数をスクリプトへ供給する必要がある。 「Content-Type」ヘッダフィールドが無く、添付物を含むリクエストをサーバが受信したら、 正確なデータタイプを確定する試み、若しくは、 リクエスト情報をスクリプトへ送る時に、このメタ変数を省略してもよい

6.1.4. GATEWAY_INTERFACE

このメタ変数は、サーバによってスクリプトとの通信に使用されているCGIの言語がセットされる。 以下が文法。

    GATEWAY_INTERFACE = "CGI" "/" major "." minor
    major             = 1*digit
    minor             = 1*digit

注: major、minor番号は分けられた整数として扱われるので、 それぞれ一桁以上のdigitとなるかもしれない。 例えば、CGI/2.4は、CGI/2.13より低いバージョンであり、 CGI/2.13は、CGI/12.3より低いバージョンである。 majorかminor番号のどちらを主に焦点を合わせるかは、 スクリプトにより選別却下される必要があり、 サーバによってもたらされるべきではない。

このドキュメントは、CGIインタフェイスの1.1バージョン(「CGI/1.1」)を定義する。

サーバは、このメタ変数をスクリプトへ供給する必要がある

6.1.5. プロトコル特有のメタ変数(Protocol-Specific Metavariables)

これらのメタ変数は、生成されたリクエストを経て、プロトコルにより特有である。 これらの変数の解釈は、SERVER_PROTOCOLメタ変数(第6.1.17章参照)の値に依存する。

HTTPが使用されるスキームの場合、「HTTP_」で始まる名前のメタ変数は、 リクエストヘッダからの値を含有する。 各HTTPヘッダフィールド名は大文字に変換され、存在する全ての「-」は「_」に変わり、 「HTTP_」が前に付加されてメタ変数となる。 同様の変換が、他のプロトコルにも適用される。 ヘッダデータは、クライアントにより送られたまま与えるか、 意味を変更しない方法で書き直してもよい。 同じヘッダ名の複数ヘッダフィールドが受信される場合、メタ変数を記述する前に、 同じ意味となる一つのヘッダフィールドとして、サーバは書き直す必要がある。 同様に、一行以上受信したヘッダフィールドは、一行に結合する必要がある。 サーバは、必要ならばデータ表記(例えば文字セット等)を、 CGIメタ変数に適したものに変更しなければならない

サーバは、受信する全てのリクエストヘッダフィールド用に、 メタ変数を生成する事を要求されない。 特に、「Authorization」の様な認証情報を運ぶ多くのヘッダフィールドや、 「Content-Length」や「Content-Type」の様な、 他のメタ変数を経由してスクリプトに送られるものを生成しなくてもよい

6.1.6. PATH_INFO

PATH_INFOメタ変数は、CGIスクリプトにより解釈されるパスを指定する。 これは、CGIスクリプトにより返されるリソース又はサブリソースを識別し、 スクリプト名の後ろでクエリーデータ前のURIパスの一部から得られる。 文法と意味は、デコード済みHTTP URLの「path」トークン(RFC 2396[4]にて定義される)と同じである。 但し、例外として、「/」のPATH_INFOは一つの無効なパス区切りを表現する。

    PATH_INFO = "" | ( "/" path )
    path      = segment *( "/" segment )
    segment   = *pchar
    pchar     = <"/"を除く全てのCHAR>

PATH_INFO文字列は、以下のSCRIPT_NAMEのパスの一部である、 スクリプトURI(第3.2章参照)の<path>要素の一部を引きずっている。

サーバは、受け入れるPATH_INFOの値を、サーバ自信の制限と限界に任せ、 スクリプトへ送る前に、不適切とみなす値は拒否や編集してもよい

サーバは、CGIスクリプトが使用する、このURI要素を生成しなければならない。 PATH_INFOの値は大文字小文字を区別し、 スクリプトにより使用される為に生成した時、 サーバはURIのPATH_INFO要素の大文字小文字を保存しなければならない

6.1.7. PATH_TRANSLATED

リクエストURI(第6.1.6章参照)のpath-info要素を取得し、 それをデコードして(第3.1章参照)、 URIとして適したものになるよう解析し、 サーバのドキュメントリポジトリ構造に記述するのに適したvirtual-to-physical変換を実行して、 PATH_TRANSLATEDが得られる。 リクエストURIがpath-info要素を含まない場合、 PATH_TRANSLATEDメタ変数は定義されるべきではない

    PATH_TRANSLATED = *CHAR

以下の様なリクエスト用

    http://somehost.com/cgi-bin/somescript/this%2eis%2epath%2einfo

PATH_INFO要素はデコードされ、その結果、以下のリクエストの様に解析されるだろう。

    http://somehost.com/this.is.the.path.info

これはサーバのドキュメントリポジトリ内の位置へ変換されるだろう。 例えば、以下の様なあるファイルシステムパスかもしれない。

    /usr/local/www/htdocs/this.is.the.path.info

変換の結果、PATH_TRANSLATEDの値となる。

PATH_TRANSLATEDの値は、正確なリポジトリの位置を表すかもしれないし、 そうでないかもしれない。 基礎が名前の大文字小文字の区別をサポートしたリポジトリならば、 サーバは、path-info部分の大文字小文字を保存する必要がある。 リポジトリがドキュメント名に関し、大文字小文字を認知、保存のみする、又は理解しない場合、 変換を経た元の部分の大文字小文字を保存する事を、サーバは要求されない。

サーバがPATH_TRANSLATEDを得る為に使用する変換アルゴリズムは、 実装により定義される。 この変数を使用するCGIスクリプトは、 運用上の限界を受ける事になるだろう。

リクエストURIがpath-info要素を含む場合、 サーバは、このメタ変数をスクリプトへ提供するべきである

6.1.8. QUERY_STRING

URLエンコードされた文字列。 スクリプトURIの<query>部分である。 (第3.2章参照。)

    QUERY_STRING = query-string
    query-string = *uric

クエリー文字列用のURL文法は、 RFC 2396[4]の第3章に記述されている。

サーバは、この値をスクリプトへ供給する必要がある。 QUERY_STRINGの値は大文字小文字を区別する。 スクリプトURIがクエリー要素を含まない場合、 QUERY_STRINGメタ変数は空文字列(「」)として定義される必要がある

6.1.9. REMOTE_ADDR

サーバへリクエストを送信するクライアントのIPアドレス。 これは、必ずしもユーザエージェントであるとは限らない (プロクシ経由で来るリクエスト等)。

    REMOTE_ADDR  = hostnumber
    hostnumber   = ipv4-address | ipv6-address

ipv4-addressipv6-addressの定義は、 RFC 2373[13]の付録B内で規定されている。

サーバはこの値を、スクリプトへ供給する必要がある

6.1.10. REMOTE_HOST

利用可能ならば、サーバへリクエストを送信する、 クライアントの完全なドメイン名で、 そうでなければNULL。(第6.1.9章参照。) 完全なドメイン名は、RFC 1034[10]の第3.5章、 RFC 1123[5]の第2.1章に記述された表現形式をとる。 ドメイン名は大文字小文字を区別しない。

サーバはこの情報をスクリプトへ供給するべきである

6.1.11. REMOTE_IDENT

利用可能ならば、RFC 1413[11]リクエストによる、 リモートエージェントへの接続に関する身元情報。 サーバは能率を理由に、この特徴をサポートする事、 若しくは、データをリクエストする事をしなくてもよい

    REMOTE_IDENT = *CHAR

返されたデータは認証目的に使用してもよいが、 それに依存する信用レベルはごくわずかであるべきである。

RFC1413[11]検索が実行されるなら、 サーバはこの情報をスクリプトへ供給する方がよい

6.1.12. REMOTE_USER

リクエストが、「Basic」メカニズムを使用する認証 (例えば、AUTH_TYPEメタ変数が「Basic」にセットされる等)を要求した場合、 REMOTE_USERメタ変数の値は与えられたユーザIDがセットされる。 その他の全ての場合、このメタ変数の値は未定義である。

    REMOTE_USER = *OCTET

この変数はHTTPプロトコル経由で生成されたリクエスト特有である。

サーバはこのメタ変数をスクリプトへ供給するべきである

6.1.13. REQUEST_METHOD

REQUEST_METHODメタ変数は、 HTTP/1.0仕様書[3]の第5.1.1章、 HTTP/1.1仕様書[8]の第5.1.1章で記述された様に、 リクエストされたメソッドがセットされる。

    REQUEST_METHOD   = http-method
    http-method      = "GET" | "HEAD" | "POST" | "PUT" | "DELETE"
                       | "OPTIONS" | "TRACE" | extension-method
    extension-method = token

メソッドは大文字小文字を区別する。 CGI/1.1サーバは、直接メソッドをスクリプトへ送る事より、 メソッドを処理する事を選んでもよい

この変数は、HTTPにより生成されたリクエスト特有である。

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.1.14. SCRIPT_NAME

SCRIPT_NAMEメタ変数は、(スクリプトの出力というより) CGIスクリプトを識別するURLパスがセットされる。 文法と意味はデコード済みHTTP URL「path」トークンと同じである (RFC 2396 [4]参照)。

    SCRIPT_NAME = "" | ( "/" [ path ] )

SCRIPT_NAME文字列は、定義された実装方法により得られた、 スクリプトURIの<path>要素の主要な一部である。 PATH_INFOやQUERY_STRING区切り (第6.1.6章第6.1.8章参照) はSCRIPT_NAMEの値内に含まれない。

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.1.15. SERVER_NAME

SERVER_NAMEメタ変数は、 スクリプトURI(第3.2章参照)の<host>部分から得られた、 サーバの名称がセットされる。

    SERVER_NAME = hostname | hostnumber

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.1.16. SERVER_PORT

SERVER_PORTメタ変数はスクリプトURIの<port>部分で使用される、 受信したリクエスト上のポートがセットされる。

    SERVER_PORT = 1*digit

スクリプトURIの<port>部分が空の場合、 受信したリクエスト上の実際のポート番号が与えられなければならない

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.1.17. SERVER_PROTOCOL

SERVER_PROTOCOLメタ変数は、リクエストが着いた情報プロトコルの、 名称と改訂番号がセットされる。 これはクライアントへのレスポンスにおいて、 サーバにより使用されるプロトコルバージョンと、 必ずしも同じではない。

    SERVER_PROTOCOL   = HTTP-Version | extension-version
                        | extension-token
    HTTP-Version      = "HTTP" "/" 1*digit "." 1*digit
    extension-version = protocol "/" 1*digit "." 1*digit
    protocol          = 1*( alpha | digit | "+" | "-" | "." )
    extension-token   = token

「protocol」は、スクリプトURIの<scheme>部分のバージョンであるが、 それとは同一ではない。 例えば、依然としてプロトコルが「http」である間、 リクエストのスキームは「https」であるかもしれない。 プロトコルは大文字小文字を区別しないが、規定により、 「protocol」は大文字である。

周知の拡張トークン値は、 クライアントリクエストの直接目標というより、合成ドキュメントの一部を含んだ、 現在のドキュメントの一つ、「INCLUDED」である。

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.1.18. SERVER_SOFTWARE

SERVER_SOFTWAREメタ変数は、リクエストに答えている (そしてゲートウェイを実行している)、 情報サーバソフトウェアの名称とバージョンがセットされる。

    SERVER_SOFTWARE = 1*product
    product         = token [ "/" product-version ]
    product-version = token

サーバはこのメタ変数をスクリプトへ供給する必要がある

6.2. メッセージボディリクエスト(Request Message-Bodies)

リクエストに添付されたデータ物が存在するかもしれないので、 これらのデータを読み込むスクリプトの為に、 システムにより定義された方法が必要である。 別の方法で指定されない限り、これは「標準入力」ファイルディスクリプタ経由である。

CONTENT_LENGTHの値(第6.1.2章参照)がNULLでない場合、 少なくともそのバイトを、標準入力ストリームでスクリプトに供給する必要がある。 スクリプトはデータを読み込む事を強要されない。 CONTENT_LENGTHバイトが読み込まれた後、サーバはEOF状態となる方がよいが、 それは強要されない。 従って、より多くのデータが利用可能であるとしても、 スクリプトはCONTENT_LENGTHバイト以上読み込む事を試みてはいけない

非解析ヘッダ(NPH)スクリプト(第7.1章参照)の為に、 クライアントにより供給され、サーバにより変更されないよう、 サーバはスクリプトへ供給するデータを保証する試みをすべきである

第8.1.2章は、メッセージボディを含むリクエストに関する、 サーバの要求事項を記述する。

7. CGIスクリプトからのデータ出力(Data Output from the CGI Script)

サーバやクライアントへデータを送り返す、 スクリプトの為のシステムにより定義された方法が必要である。 尚、スクリプトは、いくらかのデータを常に返す必要がある。 別の方法で指定されない限り、これは「標準出力」ファイルディスクリプタ経由である。

スクリプトがサーバへ供給できる出力には、2つの形式がある。 非解析ヘッダ(NPH)出力と、解析ヘッダ出力である。 サーバは解析ヘッダ出力をサポートする必要があり、 NPH出力をサポートする方がよい。 2つの出力形式(又はスクリプト)を区別する方法は、実装により定義される。

スクリプトから受信しなければならないデータの、 内部タイマ時間をサーバは実装してもよい。 そのようなタイムアウトや、スクリプトから内部タイムアウト時間にデータを受信する、 サーバの実装である場合、スクリプトプロセスを終了してもよく、 「504 Gateway Timed Out」や「500 Internal Server Error」レスポンスのいずれかにより、 クライアントリクエストを中断すべきである。

7.1. 非解析ヘッダ出力(Non-Parsed Header Output)

NPH出力形式を使用するスクリプトは、 HTTP仕様書[3,8]の第6章で定義された様に、 完全なHTTPレスポンスメッセージを返す必要がある。 適切なレスポンス用の形式を決定する為に、 NPHスクリプトはSERVER_PROTOCOL変数を使用する必要がある。

明確な転送バッファでなく、最小の内部バッファを用い、 クライアントへ直接スクリプト出力が送られるよう保証する事を、 サーバは試みるべきである

7.2. 解析ヘッダ出力(Parsed Header Output)

解析ヘッダ出力形式を使用するスクリプトは、 以下の様にサーバへCGIレスポンスメッセージを供給する必要がある

    CGI-Response   = *optional-field CGI-Field *optional-field NL [ Message-Body ]
    optional-field = ( CGI-Field | HTTP-Field )
    CGI-Field      = Content-type
                   | Location
                   | Status
                   | extension-header

レスポンスは、空行により区切られたヘッダとボディから成る。 ボディはNULLでもよい。 リクエストメソッドがHTTPの場合、ヘッダフィールドは、 サーバにより翻訳されたCGIヘッダフィールドか、 クライアントへ返すレスポンス内に含まれた、HTTPヘッダフィールドのどちらかである。 少なくとも1つのCGI-Fieldは供給される必要があるが、 CGIフィールド名はレスポンス内で1回以上使用されるかもしれない。 ボディが供給される場合、 スクリプトにより「Content-type」ヘッダフィールドが供給される必要があり、 さもなければ、スクリプトは「Location」又は「Status」ヘッダフィールドを 送る必要があるLocation CGI-Fieldが返される場合、スクリプトはHTTP-Fieldを全く供給してはならない

CGI-Response内の各ヘッダフィールドは、1行で指定される必要がある。 CGI/1.1は、継続行をサポートしない。

7.2.1. CGIヘッダフィールド(CGI header fields)

CGIヘッダフィールドは、以下の様な基本的文法がある。

    generic-field  = field-name ":" [ field-value ] NL
    field-name     = token
    field-value    = *( field-content | LWSP )
    field-content  = *( token | tspecial | quoted-string )

field-nameは大文字小文字を区別しない。 NULLフィールド値は、送られないヘッダフィールドと等価である。

7.2.1.1. Content-Type

クライアントへ変更なしに送られる、 エンテティボディのInternet Media Type[9]。

    Content-Type = "Content-Type" ":" media-type NL

これは実際には、CGI-FieldよりもHTTP-Fieldであるが、 ヘッダフィールドセットの「必要とされたものの一つ」として、 CGI討論内で重要とされた為、ここに列記された。

7.2.1.2. Location

これは、実際のドキュメントよりもむしろ、 ドキュメントへの参照を返しているスクリプトが、サーバへの指定に使用される。

    Location         = "Location" ":"
                       ( fragment-URI | rel-URL-abs-path ) NL
    fragment-URI     = URI [ # fragmentid ]
    URI              = scheme ":" *qchar
    fragmentid       = *qchar
    rel-URL-abs-path = "/" [ hpath ] [ "?" query-string ]
    hpath            = fpsegment *( "/" psegment )
    fpsegment        = 1*hchar
    psegment         = *hchar
    hchar            = alpha | digit | safe | extra
                       | ":" | "@" | "& | "="

Location値は、RFC 1630[1]内で定義された随意断片による絶対URI、 又は、サーバのURI空間内の絶対パス(すなわち、スキームとネットワーク関連フィールドを省略する)と、 随意クエリー文字列のどちらかである。

スクリプトにより絶対URIが返されるならば、 明示的にStatusレスポンスヘッダフィールドがスクリプトによって供給されない限り、 「302 redirect」HTTPレスポンスメッセージを、サーバは生成する必要がある。 絶対URIを返すスクリプトは、メッセージボディを供給する事を選択する方がよい。 ユーザエージェントへのレスポンスが、レスポンスプロトコルバージョンに従う事を保証する為に、 サーバは適切な変更をスクリプトの出力に行う必要がある。 Location値がパスである場合、 URLを含むリクエストへのレスポンスが生成されるように、サーバはレスポンスを生成する必要がある

    scheme "://" SERVER_NAME ":" SERVER_PORT rel-URL-abs-path

注意: リクエストがメッセージボディを伴い(POSTリクエスト等の様に)、 スクリプトがLocationフィールドによりリクエストをリダイレクトする場合、 メッセージボディは利用されず、リダイレクト先のリソースへとなるかもしれない。

7.2.1.3. Status

Status」ヘッダフィールドは、 レスポンスメッセージ内でサーバが使用する必要があるステータスコードを、 サーバへ指示する為に使用される。

    Status        = "Status" ":" digit digit digit SP reason-phrase NL
    reason-phrase = *<CTLとNLを除くCHAR>

正当なステータスコードは、HTTP/1.0仕様書[3]の第6.1.1章に列記される。 SERVER_PROTOCOLが「HTTP/1.1」である場合、 HTTP/1.1仕様書[8]内で定義されたステータスコードが使用されるかもしれない。 スクリプトが「Status」ヘッダフィールドを返さない場合、 サーバにより「200 OK」と仮定されるべきである

特有のエラーや、「404 Not Found」エラー等のサーバにより直面した状況を扱う事に、 スクリプトが使用される場合、 クライアントへエラー状況を伝える為に、 スクリプトは「Status」CGIヘッダフィールドを使用すべきである例えば、言及された例において、サーバへ返されるヘッダデータ内に、 「Status: 404 Not Found」を含むべきである

7.2.1.4. 拡張ヘッダフィールド(Extension header fields)

これやHTTP仕様書内で定義されていないCGIレスポンスヘッダ付加フィールドを、 スクリプトは含んでもよい。 これらは、「拡張」フィールドと呼ばれ、 第7.2.1章で定義された様に、generic-fieldの文法を持つ。 拡張フィールドの名前は、これや他の仕様書で定義されたフィールド名と衝突してはいけない。 すなわち、拡張フィールド名は、特異性を保証する為に「X-CGI-」で始まるべきである

7.2.2. HTTPヘッダフィールド(HTTP header fields)

SERVER_PROTOCOLの為の仕様書(HTTP/1.0[3]やHTTP/1.1[8])により 定義された他のヘッダフィールドを、スクリプトは返してもよい。 CGIヘッダとHTTPヘッダ形式や名前(第8章参照)との間の衝突を、 サーバは解決する必要がある

8. サーバの実装(Server Implementation)

スクリプトが機能するよう、首尾一貫した、正しいCGI/1.1環境を供給する為に、 HTTPサーバにより満足されなければならない要求事項を、この章は定義する。 主としてサーバ実装者の為のものであるが、 情報もを熟知している事は、スクリプト著者にとって有益である。

8.1. サーバの要求事項(Requirements for Servers)

CGI/1.1に順応であるとみなされる為には、 サーバは、ある基本的な基準を満たし、ある最小の機能を提供する必要がある。 これらの要求事項の詳細は、以降の章で記述される。

8.1.1. スクリプトURI(Script-URI)

スクリプトに参照付けるドキュメントにどのようなURLを使うか、 スクリプト著者が決定を可能にする、 標準的なメカニズム(以下で記述される)を、サーバはサポートする必要がある。 すなわち、メタ変数の特別な設定をする為に、具体的にどのようなURLを使うかである。 このメカニズムは以下の通りである。

CGIヘッダフィールド文法と、HTTPヘッダフィールド文法が異なる場合、 サーバは、ヘッダデータをCGIヘッダフィールド文法からHTTPヘッダフィールド文法へ変換する必要がある。 例えば、CGIスクリプトにより使用されるnewline用の文字シーケンス(UnixのASCII NLの様な)は、 HTTPにより使用されるもの(LFが後ろに付いたASCII CR)と同じではないかもしれない。 スクリプトによって返されるヘッダフィールドと、サーバ自身が送るであろうヘッダフィールドとの、 あらゆる衝突も同じくサーバは解決する必要がある

8.1.2. 要求されるメッセージボディの処理(Request Message-body Handling)

これらは、CGI/1.1リソースに従ったメッセージボディのサーバ処理の為の要求事項である。

  1. サーバがCGIスクリプトへ供給するメッセージボディは、 あらゆる転送エンコーディングを取り除いた状態にする必要がある
  2. サーバは、全ての転送デコードをした後、メッセージボディの長さを反映する、 CONTENT_LENGTHメタ変数の値を得て、供給する必要がある。
  3. サーバは、メッセージボディのcontent-encodingsを元のままにしておく必要がある

8.1.3. 要求されるメタ変数(Required Metavariables)

第8.3章で定義された様に、ある程度の情報とメタ変数を、 サーバはスクリプトへ供給する必要がある。

8.1.4. 要求されるレスポンス(Response Compliance)

ユーザエージェントへ送られたレスポンスが、 有効なプロトコルレベルの全ての要求事項を満たす事を、サーバは保証する必要がある。 これは、スクリプトにより供給されたあらゆるヘッダフィールド、メッセージボディを、 変更、削除、追加させる事を伴うだろう。

8.2. サーバの推奨事項(Recommendations for Servers)

エンコードされていない「=」文字を全く含まず、コマンドライン引数が明確な方法で生成され得るなら、 サーバは、コマンドライン引数として、スクリプトURIの「query」構成要素を、 スクリプトへ供給するべきである。 (第5章参照)

Authorization」フィールドがリクエストヘッダの一部として供給されたなら、 「auth-scheme」トークンの値を、 サーバはAUTH_TYPEメタ変数にセットするべきである。 (第6.1.1章参照)

妥当なところでは、サーバは、呼び出される前に設置されたスクリプトのディレクトリを、 カレント作業ディレクトリにセットするべきである

サーバは、PATH_INFOやSCRIPT_NAMEにデコードされた、エンコード「/」により生じる全てのリクエストは、 スクリプトに情報の損失を表現する為に、「404 Not Found」エラーと共に却下する方がよい

サーバとCGIスクリプトは、(クライアントURLやPATH_INFOデータ、それぞれ) URLパスの処理と同じである必要はないが、 サーバ著者は一貫性を課す事を要求してもよい。 従って、サーバの実装は、以下の場合にそのふるまいを定義するべきである

  1. 許可された文字における、あらゆる制限の定義。 特に、ASCII NULが許可されるかどうか。
  2. 許可されたパス区切りにおける、あらゆる制限の定義。 特に、終端でないNULL区切りが許可されるかどうか。
  3. 「.」や「..」パス区切りのふるまいの定義。 すなわち、禁止されるのか、通常のパス区切りとして扱われるのか、 それとも、相対URL仕様[7]に従って翻訳されるのかどうか。
  4. パスや検索文字列長における制限や、 サーバが解析するであろうヘッダデータの値における制限を含む、 実装のあらゆる制限。

サーバは、クライアントURIや、 他のデータからの方法において、スクリプトURIを生成してもよい (しかし、ふるまいは記述されるべきである)。

非解析ヘッダ(NPH)スクリプト(第7.1章参照)の為に、 サーバは、スクリプト入力が、最小のバッファにより直接クライアントから来るよう、 保証する事を試みるべきである。 データがクライアントにより供給される、全てのスクリプトの為。

8.3. メタ変数の概要(Summary of MetaVariables)

サーバは、以下のメタ変数をスクリプトへ供給する必要がある。 例外や意味論は、個々の記述を参照のこと。

    CONTENT_LENGTH (第6.1.2章)
    CONTENT_TYPE (第6.1.3章)
    GATEWAY_INTERFACE (第6.1.4章)
    PATH_INFO (第6.1.6章)
    QUERY_STRING (第6.1.8章)
    REMOTE_ADDR (第6.1.9章)
    REQUEST_METHOD (第6.1.13章)
    SCRIPT_NAME (第6.1.14章)
    SERVER_NAME (第6.1.15章)
    SERVER_PORT (第6.1.16章)
    SERVER_PROTOCOL (第6.1.17章)
    SERVER_SOFTWARE (第6.1.18章)

サーバは、以下のメタ変数をスクリプトの為に定義するべきである。 例外や意味論は、個々の記述を参照のこと。

    AUTH_TYPE (第6.1.1章)
    REMOTE_HOST (第6.1.10章)

更に、サーバは、アクセス制御に関連したものを除き、 HTTPリクエストヘッダに存在する全てのフィールド用に、 メタ変数を供給するべきである。 サーバは、判断により、アクセス制御フィールド用のメタ変数を供給してもよい

サーバは、以下のメタ変数を定義する方がよい。 例外や意味論は、個々の記述を参照のこと。

    PATH_TRANSLATED (第6.1.7章)
    REMOTE_IDENT (第6.1.11章)
    REMOTE_USER (第6.1.12章)

サーバは、判断により、定義されたヘッダフィールド名と名前が衝突しない限り、 実装特有の拡張メタ変数を追加定義してもよい。 実装特有のメタ変数名は、そのような衝突を回避する為に、「X_」を接頭辞とするべきである (例えば、「X_DBA」)。

9. スクリプトの実装(Script Implementation)

この章は、CGI/1.1環境において機能する事を考慮している、 スクリプトの為の要求事項と推奨事項を定義する。 主としてスクリプト著者を考慮しているが、 サーバ実装者は、これらの問題も熟知しているべきである。

9.1. スクリプトの要求事項(Requirements for Scripts)

サーバと通信するために解析ヘッダ形式を使うスクリプトは、 レスポンスヘッダをサーバへ提供する必要がある。 (第7章参照)

サーバと通信するためにNPH形式を使うスクリプトは、 完全なHTTPレスポンスを提供する必要があり、 適切な形式を決定するために、SERVER_PROTOCOLメタ変数の値を使用する必要がある。 (第7.1章参照)

スクリプトは、適切なレスポンスを提供するために、 REQUEST_METHODメタ変数の値を確認する必要がある。 (第6.1.13章参照)

スクリプトは、メタ変数内でURLエンコードされた値が処理されるよう、 準備する必要がある。 更に、それらは、URLエンコードされたものにおいて、 空白文字を表現する「+」や「%20」の両方を認識する必要がある。 (第3.1章参照)

スクリプトは、GATEWAY_INTERFACEメタ変数値の、 メジャーとマイナーバージョン番号における、先頭のゼロを無視する必要がある。 (第6.1.4章参照)

メッセージボディを含むリクエストを処理している時、 スクリプトは、入力ストリームからCONTENT_LENGTHバイト以上読み込んではいけない。 (第6.1.2章第6.2章参照)

9.2. スクリプトの推奨事項(Recommendations for Scripts)

サーバは、警告せずにいつでもスクリプトの実行を中断、終了してもよい。 従って、スクリプトは異常終了を扱う準備をするべきである

スクリプトは、サポートされていないメソッドを使用したリクエストを、 「405 Method Not Allowed」エラーで拒否する必要がある。 スクリプトがPATH_INFOデータを処理するつもりでないなら、 PATH_INFOがNULLでない場合、「404 Not Found」でリクエストを拒否するべきである

スクリプトがフォームの出力を処理している場合、 CONTENT_TYPEが「application/x-www-form-urlencoded」[2]や、 全ての予期される他のメディアタイプであるか確認するべきである

PATH_INFO、PATH_TRANSLATED、SCRIPT_NAMEを解析するスクリプトは、 無効なパス区切り(「//」)や、特別なパス区切り(「.」や「..」)に注意するべきである。 それらは、OSシステムコールで使用する前に、パスから除去されるか、 「404 Not Found」でリクエストが拒否されるべきである

スクリプトが、使用される特定のサーバの知識なしで、 リクエストが開始されたクライアントURIを決定する事が不可能である為、 スクリプトは、ドキュメントに「<BASE>」タグを入れずに、 相対URLリンクを含む「text/html」ドキュメントを返すべきではない

ヘッダフィールドを返しているとき、 スクリプトは、できる限り早く、 CGIヘッダフィールド(第7.2章参照)を送る努力をするべきであり、 そして、あらゆるHTTPヘッダフィールドの前に、それらを送るべきである。 これは、サーバのメモリ要求を減少させるのを、助けるかもしれない。

10. システムの仕様(System Specifications)

10.1. AmigaDOS

AmigaDOSオペレーティングシステムプラットフォーム上のCGIの実装は、 CGIスクリプトへリクエストメタデータを供給するメカニズムとして、 環境変数を使用すべきである。

環境変数(Environment variables)

これらは、DOSライブラリルーチンGetVarによりアクセスされる。 引数フラグは0にすべきである。 大文字小文字は区別されないが、 大文字小文字を区別するシステムとの互換性の為に、大文字が推奨される。

カレント作業ディレクトリ(The current working directory)

スクリプト用のカレント作業ディレクトリは、スクリプトを含むディレクトリがセットされる。

文字セット(Character set)

環境変数名とヘッダフィールド名の定義に、US-ASCII文字セットが使用される。 newline(NL)シーケンスは、LFである。 サーバはnewlineとして、CR LFも認めるべきである。

10.2. Unix

UNIXオペレーティングシステムプラットフォーム上のCGIの実装は、 CGIスクリプトへリクエストメタデータを供給するメカニズムとして、 環境変数を使用すべきである。

Unix互換オペレーティングシステム用に、以下が定義される。

環境変数(Environment variables)

これらは、Cライブラリルーチンgetenvによりアクセスされる。

コマンドライン(The command line)

これは、main()関数に、argc、argv引数を使用してアクセスされる。 これは、バックスラッシュによってエスケープされた、 Bourne shellにおける「有効な」全ての文字である。 QUERY_STRINGメタ変数の値が、エンコードされていないイコール記号「=」を含む場合、 コマンドラインは、スクリプトにより使用されるべきではない

カレント作業ディレクトリ(The current working directory)

スクリプト用のカレント作業ディレクトリは、 スクリプトを含むディレクトリがセットされるべきである。

文字セット(Character set)

環境変数名とヘッダフィールド名の定義に、US-ASCII文字セットが使用される。 newline(NL)シーケンスは、LFである。 サーバはnewlineとして、CR LFも認めるべきである。

11. セキュリティへの配慮(Security Considerations)

11.1. 安全なメソッド(Safe Methods)

HTTP仕様書[3,8]のセキュリティへの配慮内で議論されたように、 慣習は、GETとHEADメソッドは「安全」であるだろうと認められている。 それらは、副作用を引き起こすべきではなく、リソース検索の意味のみ持つ。

CGIスクリプトは、リクエストのプロトコルバージョンレベルと、 サーバに代わりスクリプトが生成したあらゆる副作用を考慮して、 あらゆるHTTPセキュリティへの配慮[3,8]を実施する責任がある。 これらの中で最も重要な事は、安全への配慮とべき等メソッドである。 べき等リクエストは、任意の回数繰り返され、同じ副作用が一つのリクエストを生成するだろう。

11.2. 機密情報を含むHTTPヘッダフィールド(HTTP Header Fields Containing Sensitive Information)

サーバは明示的に行わない限り、スクリプトに与えるべきでない機密情報を、 いくつかのHTTPヘッダフィールドは運ぶだろう。 例えば、サーバが「Basic」認証スキームを使用するスクリプトを保護する場合、 クライアントはユーザ名とパスワードを含む、「Authorization」ヘッダフィールドを送るだろう。 スクリプトよりむしろ、サーバが、この情報を許可する場合、 注意深く考慮せず、HTTP_AUTHORIZATIONメタ変数を経由して、 パスワードをスクリプトに与えるべきではない。 同じくこれは、Proxy-Authorizationヘッダフィールドと、 対応するHTTP_PROXY_AUTHORIZATIONメタ変数にも当てはまる。

11.3. スクリプトのサーバへの妨害(Script Interference with the Server)

CGIの最も一般的な実装は、サーバプロセスと同じユーザとグループを使用する、 チャイルドプロセスとしてスクリプトを呼び出す事である。 従って、スクリプトはサーバプロセスやその構成、ドキュメントを妨害し得ない事が、 保証されるべきである。

スクリプトが、サーバソフトウェア内にて、(コンパイル時、実行時のどちらかで) リンクされた関数呼び出しによって実行される場合、 サーバのコアメモリを保護するか、又は、不正なコードが実行されない事を保証する様に、 事前に対策をすべきである。

11.4. データの長さとバッファへの配慮(Data Length and Buffering Considerations)

この仕様は、スクリプトに与えられた、メッセージボディの長さに制限を置かない。 一度に全てのものを含むのに十分なサイズのバッファが、静的に割り当てられると、 スクリプトは仮定すべきでない。 慎重にオーバーフローチェックする事なく固定長バッファを使用する事は、 攻撃者にオペレーティングシステムを、不正に「スタック破壊(stack-smashing)」や、 「スタックオーバーフロー(stack-overflow)」攻撃されやすくなるだろう。 スクリプトは、大きな内容物をディスクや、他のバッファリングメディアにスプールするだろうが、 大きな内容物が相次いで来ると、サービス拒否状態となるだろう。 メッセージボディのCONTENT_LENGTHが、許可されたリソースを考慮して、それより大きい場合、 スクリプトは、プロトコルバージョンに適したエラーステータスで、応答するべきである。 潜在的に、適用ステータスコードは、 「503 Service Unavailable」(HTTP/1.0とHTTP/1.1)、 「413 Request Entity Too Large」(HTTP/1.1)、 「414 Request-URI Too Long」(HTTP/1.1)である。

11.5. 状態を保存しない処理(Stateless Processing)

多重リクエストが一つのWeb処理概念を構成するときさえも、 Webの状態を保存しない性質は、他のあらゆるものと関係なく、 それぞれのスクリプトの実行と、リソースの検索を行う。 このため、リクエストを送っているユーザエージェントの内容について、 スクリプトは仮定を全くすべきでない。 特に、他のアプリケーション、コマンド、オペレーティングシステムサービスへの入力のような、 機密目的の為に使用される事を許可する前に、フォーム内と内容物内の両方において、 スクリプトはクライアントから手に入れたデータを調査し、それらが有効である事を確認するべきである。 システムコール引数、データベース書き込み、動的ソースコード評価、構築や他の安全なプロセスへの入力が、 これらの使用に含まれるが、これらに限定されない。 ユーザエラー、理論的なエラー、故意な攻撃の結果、無効となるかどうかに関係なく、 無効な入力からアプリケーションが保護される事は、重要である。

多重リクエスト処理に関係したスクリプトの著者は、保存情報を有効とする事に、 特に慎重になるべきである。 有害な影響は、安全だと仮定した別の方法で送った、一部の危険な値の置換に起因するだろう。 クライアントにより制御されない処理の前の段階で、データが変更されるとき、 このタイプの破壊が発生する。 (例えば、隠しHTML form要素、クッキー、埋め込まれたURL。)

12. 謝辞(Acknowledgements)

この著作は、David R. Robinsonにより1997年に公開されたdraftが元になった。 尚、www-talkメイリングリスト上の議論により生まれた、 オリジナルのCGIインタフェイスが交互に元になっている。 特に、このインタフェイスの初期バージョンの定義と実装において、 Rob McCool、John Franks、Ari Luotonen、George Phillips、Tony Sandersの努力には、 大変感謝している。

このドキュメントでは、 Mike Meyer、David Morris、Jeremy Madea、Patrick McManus、Adam Donahue、 Ross Patterson、Harald Alvestrandによるコメントと提案も、非常に利益となった。

13. 参考文献(References)

[1]
Berners-Lee, T., 'Universal Resource Identifiers in WWW: A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the World-Wide Web', RFC 1630, CERN, June 1994.
[2]
Berners-Lee, T. and Connolly, D., 'Hypertext Markup Language - 2.0', RFC 1866, MIT/W3C, November 1995.
[3]
Berners-Lee, T., Fielding, R. T. and Frystyk, H., 'Hypertext Transfer Protocol -- HTTP/1.0', RFC 1945, MIT/LCS, UC Irvine, May 1996.
[4]
Berners-Lee, T., Fielding, R., and Masinter, L., Editors, 'Uniform Resource Identifiers (URI): Generic Syntax', RFC 2396, MIT, U.C. Irvine, Xerox Corporation, August 1996.
[5]
Braden, R., Editor, 'Requirements for Internet Hosts -- Application and Support', STD 3, RFC 1123, IETF, October 1989.
[6]
Crocker, D.H., 'Standard for the Format of ARPA Internet Text Messages', STD 11, RFC 822, University of Delaware, August 1982.
[7]
Fielding, R., 'Relative Uniform Resource Locators', RFC 1808, UC Irvine, June 1995.
[8]
Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and Berners-Lee, T., 'Hypertext Transfer Protocol -- HTTP/1.1', RFC 2068, UC Irvine, DEC, MIT/LCS, January 1997.
[9]
Freed, N. and Borenstein N., 'Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types', RFC 2046, Innosoft, First Virtual, November 1996.
[10]
Mockapetris, P., 'Domain Names - Concepts and Facilities', STD 13, RFC 1034, ISI, November 1987.
[11]
St. Johns, M., 'Identification Protocol', RFC 1431, US Department of Defense, February 1993.
[12]
'Coded Character Set -- 7-bit American Standard Code for Information Interchange', ANSI X3.4-1986.
[13]
Hinden, R. and Deering, S., 'IP Version 6 Addressing Architecture', RFC 2373, Nokia, Cisco Systems, July 1998.

14. 著者のアドレス(Authors' Addresses)

Ken A L Coar
MeepZor Consulting
7824 Mayfaire Crest Lane, Suite 202
Raleigh, NC 27615-4875
U.S.A.
Tel: +1 (919) 254.4237
Fax: +1 (919) 254.5250
Email: Ken.Coar@Golux.Com

David Robinson
E*TRADE UK Ltd
Mount Pleasant House
2 Mount Pleasant
Huntingdon Road
Cambridge CB3 0RN
UK
Tel: +44 (1223) 566926
Fax: +44 (1223) 506288
Email: drtr@etrade.co.uk


<< index
2001/06/12 12:54:41 AM (JST)
web site: no title
Copyright © 1997-2001, Norio HATTORI (服部 憲雄)
mail to: nr-tori@rio.odn.ne.jp
Apache/1.3.6 (Unix) Server at www.grn.mmtr.or.jp Port 80