CGI のバイナリーモードとテキストモード
Translation モード
C 言語のライブラリに Translation モード というのがあります。 これを意識しないと、思わぬバイト数のデータを送受信することになるので、CGI が正常に動きません。
- テキストモード
- LF (\n) を CR LF (\r\n) に変換
- CR LF (\r\n) を LF (\n) に変換
- バイナリモード
- CR LF (\r\n) ともにそのまま
具体例を見てみましょう。テキストモードのときは次のようになります。
これはデフォルトの状態です。 \n は LF (ラインフィード) ですが、printf にて文字列を出力するときに テキストモードでは LF は CR LF (0d 0a) に変換されます。また読み込むときは、 その逆で CR LF が LF にまとめられます。
一方、バイナリモード では LF は 0a のまま出力され、読み込むときも LF は 0a のままです。特に何も変換しません。
なぜ Translation モードを意識しなければならないか?
正しい HTTP レスポンスを送信するため
Translation モードを意識するのは、第一に正しい HTTP レスポンスを送信するためです。
例えば HTTP ヘッダに、Content-Length というデータ長を表すフィールドがあります。
"Hello\n" という文字列の Content-Length を計算するときに、Translation モードによってデータ長がかわります。 Hello の 5 文字はいつも同じですが、テキストモードのときは \n は 0d 0a に変換されるので、 2 バイト。バイナリモードのときは \n は 0a のままであるので 1 バイトです。
HTTP リクエストを正しく読み込むため
例えば POST データを読み込む際に、CONTENT_LENGTH 長のデータサイズを期待しますが、CR LF が LF に変換されたことにより、十分なデータが受け取れずプログラムがハングアップする事例があります。