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 に変換されたことにより、十分なデータが受け取れずプログラムがハングアップする事例があります。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説