■iアプリとContent-Length
まずHTTPの仕様についてですが、HTTP/1.0の通信ではヘッダのContent-Lengthでボディ部分の長さを表します。あるいは接続が切れたらボディの終わりとわかります。それに加えてHTTP/1.1では、chunked形式というボディをいくつかのブロックに分けそれぞれのブロックの先頭に長さを付けて通信する方法があります。さらに特に指定しなければKeep-Alive接続といって次のリクエストに備えてHTTP接続が持続されます。なおCGIプログラムを書く場合、普通はプログラム中で長さを計算する必要は無くHTTPサーバが長さを計算して出力してくれます。
さて、HTTPサーバの振舞いとしては、HTTP/1.1でリクエストが来たらchunked形式でレスポンスを返しても問題無さそうですが、iアプリの仕様は、FOMA携帯はHTTP/1.1で通信し、HTTP通信のレスポンスにContent-Lengthが必要となっているため、FOMAのiアプリではうまく噛み合わない可能性があります。
そうはいうものの多くの機種はchunked形式やKeep-Aliveに対応しているのか、上記の問題はあまり話題になっていないようです。しかし私の手元にあるNM706iでは通信するiアプリがうまく動きません。iMonaも動きませんでした。調べたところ、HTTP/1.1のリクエストを出してchunked形式のレスポンスを受け取って読めないでいるようです。でも原因を特定できたのでiMonaを動かす目処が立ちました。
■Content-Lengthの出し方
HTTPサーバによっては設定項目としてchunked形式の有効/無効があったりします。私の使っているサーバにそういう設定はありませんが、CGIプログラムの中で長さを自分で計算してContent-Lengthをヘッダ部分に出力すれば、HTTP/1.1のリクエストにchunkedでない形式でレスポンスを返してくれます。
■iMonaの中間鯖CGIの修正
標準出力にprint文などで出力するはずの文字をどんどん連結しておいて文字数が確定してからまとめてprint、と書き換えればいいですが、iMonaのスクリプトは結構複雑なのでselectでデフォルトの出力を一時ファイルに向けて一時ファイルから文字数を調べることにしました。この場合forkして子プロセスの標準出力を切り替えるようにしないとHTTP通信が切れてしまいます。実際にどう書いたかはソースを見てください(2.cgi)。
同様の対策をすればNM705i/NM706iでも通信するiアプリがいろいろ動くようになると思いますので、各種iアプリのソースや関連スクリプトをお持ちの皆様、どうぞよろしくお願いします。