[505] [[CGI]] の[DFN[[RUBYB[[[応答]]]@en[response]]]]は、 [[HTTP]] 
の[[応答]]の元となるデータを[[CGIスクリプト]]から[[鯖]]へと伝達するものです。
構文的にも意味的にもほとんど[[HTTP応答]]と同じですが、
若干の違いもあります。

* 仕様書
[REFS[
- [5] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] 
-- [2] <http://tools.ietf.org/html/rfc3875#section-4.3.3>
-- [6] '''<http://tools.ietf.org/html/rfc3875#section-6>'''
-- [322] <http://tools.ietf.org/html/rfc3875#section-8.2>
]REFS]

* 構文

[11] [[CGI応答]]は、
- 1つ以上の[[頭欄]]
- [CODE(ABNF)[[[NL]]]]
- [[応答本体]] (省略可能)

... の3つの部分により構成されます。あるいは [[CGI応答]]は次の3種類に分類できます。 [RC[>>6]]
- [[文書応答]]
- [[局所リダイレクト応答]]
- [[クライアントリダイレクト応答]]

* CGI の頭欄

[304] [[CGI応答]]における[[頭欄]]は、
- [305] [[鯖]]によって解釈される[[CGI欄]]
- [306] [[プロトコル]]に依存する[[頭欄]]
-- [307] [[HTTP頭欄]]、[[SIP頭欄]]など

... の2種類に分けられます。詳しくは[[CGI欄]]の項をご覧ください。

** 構文

[308] [[頭欄]]の構文は次のように定義されています [SRC[>>6]]。
[PRE(ABNF code)[
      generic-field   = field-name ":" [ field-value ] NL
      field-name      = token
      field-value     = *( field-content | LWSP )
      field-content   = *( token | separator | quoted-string )
]PRE]

[309] [CODE(ABNF)@en[[[field-name]]]] は[[大文字・小文字不区別]]です。 [SRC[>>6]]

[310] [[NULL]] ([[空文字列]]) とその[[頭欄]]を指定しないことは等価です。 [SRC[>>6]]

;; [311] [[HTTP]] では[[空文字列]]であっても存在する場合と存在しない場合で意味が異なる[[頭欄]]があります。
仕様上 [[CGI]] ではそれが等価とみなされてしまいます。

[312] [[CGI]] では[[折り畳み]]を使うことはできず、[[頭欄]]はそれぞれ一行で表さなければ[['''なりません''']]
[SRC[>>6]]。

;; [313] 構文上、 [CODE(ABNF)@en[[[LWSP]]]] に改行が含まれるので、それよりも強い制約があることになります。
(というか [[NL]] を [[LWSP]] として使ってしまうと解釈が一意でなくなってしまいますが・・・。)

[314] [CODE(URI)[[[:]]]] の後や、 [CODE(ABNF)@en[[[field-value]]]] 内の[[字句]]の間には[[空白]]を挿入できます。
[SRC[>>6]]

;; [315] この[[空白]]は [[LWSP]] のことを指しているのでしょうか。またこのような字句化は
[CODE(HTTP)@en[[[Location:]]]] 欄の構文と矛盾しているようですが、良いのでしょうか・・・。
と思いましたが [[CGI]] [[RFC]] で規定される3つの [[CGI欄]]にはこの一般構文は適用されないようです・・・。
しかし [[HTTP]] のいろいろな[[頭欄]]がこの字句化とは矛盾しますね。 
(結果として構文的に表現可能ではあるのでしょうが・・・。)

[321] [[CGI欄]]はそれ以外よりも先に出力するべきです。その方が[[鯖]]の[[メモリー]]管理上都合がいいことがあります。
[SRC[>>322]]

** プロトコル依存の頭欄

[316] [[CGIスクリプト]]は適宜プロトコル依存の[[頭欄]] ([[HTTP頭欄]]など) を返すことができます。
[[鯖]]は[[クライアント]]との[[プロトコル]]の規定その他に応じて適宜それを変形しなければ[['''なりません''']]
[SRC[>>6]]。

- [317] [[Unix]] 環境での [[LF]] は [[HTTP]] の [[CRLF]] に置き換えなければなりません
- [318] [[クライアント]]との通信に支障が出る[[頭欄]]を除去して構いません
- [319] [[CGIスクリプト]]が返した[[頭欄]]と通常[[鯖]]が返す[[頭欄]]で不整合があれば、それを解消するような変更を施す[['''べきです''']] [SRC[>>6]]

* 文書応答

[12] [DFN[[RUBYB[文書応答]@en[document response]]]]は、[[クライアント]]に対して[[文書]]を返すものです。 [SRC[>>6]]
- [13] [CODE(HTTP)@en[[[Content-Type:]]]] 欄は[['''必須''']]です
- [14] [CODE(HTTP)@en[[[Status:]]]] 欄を指定することができます
- [15] その他の[[頭欄]]を指定することができます
- [16] [[応答本体]]を指定することができます

[17] [[鯖]]は[[CGI応答]]を適宜変形して[[クライアント]]との[[プロトコル]]に適合するようにしなければ[['''なりません''']]。
[SRC[>>6]]

;; [18] そうできないときにどうしなければならないかは明記されていません。通常は適合といっても完璧に適合するかどうか[[鯖]]が検査するのではなく、
実用上十分な程度の要件を満たすよう整形や[[転送符号化]]等を適用するくらいです。

[324] [[Apache2]] では [CODE(HTTP)@en[[[Content-Type:]]]] は省略可能なようです。

* 局所リダイレクト応答

[19] [DFN[[RUBYB[局所リダイレクト応答]@en[local redirect response]]]]は、[[CGIスクリプト]]が指定した [[path]]
に対するアクセスであったものとして再度[[鯖]]によって処理しなおすことを指示するものです。 [SRC[>>6]]
- [20] [CODE(HTTP)@en[[[Location:]]]] 欄は必須であり、 [[path]] からはじまる構文でなければなりません
- [21] それ以外の[[頭欄]]や[[応答本体]]を指定しては[['''なりません''']]

[22] [[鯖]]は
[PRE[
      scheme "://" server-name ":" server-port local-pathquery
]PRE]
... という [[URL]] ([CODE[local-pathquery]] が [CODE(HTTP)@en[[[Location:]]]] 欄で指定された値)
に[[要求]]があったものとして処理しなおさなければ[['''なりません''']]。 [SRC[>>6]]

;; [23] [[リダイレクト・ループ]]に対する処理をどうするべきか明確にされていません。

;; [24] >>21 が守られていない場合にどうなるのかも明確にされていません。

[501] [[Apache2]] では [[HTTP]] の[[頭欄]]が指定されていると、それが[[リダイレクト]]先の [[HTTP]]
[[応答頭欄]]に加えて[[応答]]に含まれます。複数段[[リダイレクト]]されているとそれらがすべて順に
(後のものほど後に) 付加されていきます。

[328] [[Apache2]] では >>23 は [[500]] エラーとなります。 >>501 はこのエラーの場合も含めて適用されます。

* クライアント・リダイレクト応答

[25] [DFN[[RUBYB[クライアント・リダイレクト応答]@en[client redirect response]]]]は[[クライアント]]に対して[[リダイレクト]]を指示するものです。[[文書]]付きと[[文書]]無しの2種類があります。
それぞれの要件は次の通りです [SRC[>>6]]。

- [26] [CODE(HTTP)@en[[[Location:]]]] 欄は必須であり、[[絶対URL]]でなければなりません
- [27] 文書無しの場合、
-- [28] [CODE(HTTP)@en[[[Status]]]], [CODE(HTTP)@en[[[Content-Type]]]], [CODE(HTTP)@en[[[Location]]]]
''以外''の[[CGI頭欄]]を使って構いません
-- [30] [[CGI頭欄]]以外の[[頭欄]]を使ってはなりません
-- [29] [[応答本体]]を使ってはなりません
- [31] 文書付きの場合
-- [32] [CODE(HTTP)@en[[[Status]]]], [CODE(HTTP)@en[[[Content-Type]]]], [CODE(HTTP)@en[[[Location]]]]
のすべてを指定しなければなりません
-- [36] [CODE(HTTP)@en[[[Status]]]] は[[クライアント]]による[[リダイレクト]]を指示するものでなければ[['''なりません''']]
-- [33] 他の[[頭欄]]を指定して構いません
-- [34] [[応答本体]]を使って構いません

[35] [[鯖]]は文書無しの場合 [CODE(HTTP)@en[[[302]]]] [[応答]]を返さなければ[['''なりません''']]。
[SRC[>>6]]

[303] [[鯖]]は文書付きの場合[[CGI応答]]を適宜変形して[[クライアント]]との[[プロトコル]]に適合するようにしなければ[['''なりません''']]。
[SRC[>>6]]

[327] [[Apache2]] では [CODE(HTTP)@en[[[Status:]]]] が無く[[絶対path]]であれば >>19
により、それ以外ならこちらにより処理するようです。

[325] [[Apache2]] では (現実の [[Webブラウザー]]の実装がそうであるように) [CODE(HTTP)@en[[[Location:]]]]
の値が[[相対URL]]であっても構いません。

[326] [[Apache2]] では [CODE(HTTP)@en[[[Status:]]]] が無ければ >>27、あれば >>31 
と解釈されるようです。 >>27 の場合 [CODE(HTTP)@en[[[Content-Type:]]]] や[[応答本体]]があっても無視されます。

* 処理モデル

[7] [[CGIスクリプト]]は常に空でない[[応答]]を[[鯖]]に送り返さなければ[['''なりません''']]。 [SRC[>>6]]

[8] [[CGIスクリプト]]から[[鯖]]にデータを送る方法は[[システム定義]]です。
別途定義がない場合、「[[標準出力]]」[[ファイル記述子]]によってデータを送ることになります。
[SRC[>>6]]

[9] [[CGIスクリプト]]は[[応答]]を準備するに当たり [CODE(CGI)@en[[[REQUEST_METHOD]]]]
をチェックしなければ[['''なりません''']]。 [SRC[>>6]]

[10] [[鯖]]は[[タイムアウト]]を設定して[['''構いません''']]。その場合、[[タイムアウト]]になると[[スクリプト]]を終了させて[['''構いません''']]。
[SRC[>>6]]

[320] [DFN[[RUBYB[[[応答本体]]]@en[response-body]]]]は、零個以上の [[OCTET]]
の列です。これは[[クライアント]]へと返されることになります。[[鯖]]は
[[CGIスクリプト]]が提供したデータをすべて、 [[EOF]]
に到達するまで読まなければ[['''なりません''']]。
それをそのまま無変更で送信する[['''べきです''']]。
ただし、 [CODE(HTTP)@en[[[HEAD]]]] の場合、[[転送符号化]]、[[内容符号化]]、
[[charset]] の変換が必要な場合を除きます。 [SRC[>>6]]

[323] 実装によっては[[標準誤り出力]]が[[標準出力]]と共に[[CGI応答]]に使われてしまうことがあります。

[504] [[標準出力]]を閉じると [[HTTP応答]]も終了したものとして扱う実装が一般的ですが、
特にそう規定されているわけではなく、そうなっていない実装もあります。また、
[[標準出力]]が閉じられると [[CGIスクリプト]]を終了させる実装もあるようです。

* [CODE(CGI)@en[HEAD]] の場合

[1] [CODE(CGI)@en[[[HEAD]]]] [[メソッド]]の場合、 [[CGIスクリプト]]は[[応答本体]]を指定しては[['''なりません''']]。
[[鯖]]は指定されても捨てなければ[['''なりません''']]。 [SRC[>>2]]

;; [3] 多くの[[CGIスクリプト]]は [CODE(CGI)@en[[[HEAD]]]] [[メソッド]]に対応しておらず、
[CODE(CGI)@en[[[GET]]]] と同じものを返し、結果として >>1 の要件に違反しています。

* NPH スクリプトの場合

[4] [[NPHスクリプト]]は完全な [[HTTP]] [[応答メッセージ]]を返すことが求められています。
詳しくは[[NPH応答]]の項を参照してください。

* メモ

[502] [CITE[CGIの動作について]]
( ([TIME[2006-12-17 14:21:19 +09:00]] 版))
<http://chaichan.web.infoseek.co.jp/qa3000/qa3198.htm>

[503] [CITE@ja[close(STDOUT)するとCGIが終了する。 | OKWave]]
( ([TIME[2012-02-25 23:24:56 +09:00]] 版))
<http://okwave.jp/qa/q6476437.html>