iOS/AndroidアプリからのPOST通信が不可思議な壊れ方をする件

3
武田 憲太郎 @KentarouTakeda

【拡散希望】iOS/AndroidアプリからのHTTP通信(POST)で稀に不可思議なデータが来てサーバが処理できないことがある。原因は解ったもの何を直せば良いのか全く解らないので備忘録がてらここに、といいつつ、誰かが拾ってくれてアドバイス頂けるのを何気に期待してたりします。

2012-10-25 13:12:26
武田 憲太郎 @KentarouTakeda

現時点では3G回線のみで発生を確認。Wi-Fiでは多分発生しない又は発生確率は極めて低い。ちなみに過去にauのBREWアプリのクライアントで同じ現象に遭遇した事例あり。auのBREWのみでドコモ/SBのJavaでは発生しない。こちらは後述。

2012-10-25 13:12:34
武田 憲太郎 @KentarouTakeda

不具合の詳細。メソッドはPOST、Content-LengthもContent-Typeも入力されており、少なくともWebサーバリクエストを正しく解釈している。にも関わらずプログラム(今回はphp)から見るとメッセージボディが空。

2012-10-25 13:12:41
武田 憲太郎 @KentarouTakeda

一般的なPOSTの挙動。リクエストヘッダの入力を終えメッセージボディ入力が開始された後、WebサーバはContent-Length長だけ入力を待ちそれを超えたらWebサーバ側から接続を切る。この場合Content-Lengthと実際のボディ長は必ず一致する。

2012-10-25 13:13:16
武田 憲太郎 @KentarouTakeda

telnetを用いた実験結果。メッセージボディがContent-Length長に達する前にクライアント側から接続を切った場合(又はボディ入力中にTimeoutに達した場合)は、途中までしか入力されていない半端なメッセージボディをプログラムが受け取る。この挙動自体は問題ない。

2012-10-25 13:13:39
武田 憲太郎 @KentarouTakeda

しかし、実際の環境(つまりクライアントがiOS/Androidアプリ)の場合、想定外の切断を受ける場合その場所が毎回決まっている。「リクエストヘッダ終端の空行を入力、メッセージボディは全くの未入力」というタイミングの切断に限られる。

2012-10-25 13:13:49
武田 憲太郎 @KentarouTakeda

「通信環境が不安定であったため想定外の箇所で切断される」であれば切断箇所も不定であるはず。つまり、ヘッダ入力中の切断(Webサーバの段階で400エラー)やボディ入力途中の切断(中途半端にボディを受け取る)もログに残るはず。しかし実際には一切残っていない。

2012-10-25 13:14:05
武田 憲太郎 @KentarouTakeda

となると当然クライアント側のバグを疑わざるを得ない。とはいえOS問わずiOS/Android双方で発生、また前述のとおり(今回とは全く関係ないが)auのBrewアプリでも過去に全く同じ状況に遭遇したことを考えると一概には言えない。

2012-10-25 13:14:15
武田 憲太郎 @KentarouTakeda

ちなみに「スマートフォンで発生」「フィーチャーフォンでは未発生」「しかしauのBrewアプリでは発生」は理由は想像が付く。Airとサーバとの間にProxyを挟んでいるか否かの違い。auのガラケーでもBrewはプロクシを挟まない。

2012-10-25 13:14:24
武田 憲太郎 @KentarouTakeda

SMTPのような対話的なプロトコル(クライアント側のコマンドに対してサーバ側の応答を待ってから次のコマンドを入力する)の場合、上り好調で下り不調という状態でクライアントがサーバの応答を受け取れずタイムアウト、など考えられるがHTTPではそれは有り得ない。

2012-10-25 13:14:38
武田 憲太郎 @KentarouTakeda

つまり、3Gの電波状況に起因した切断であってもガラケーの場合それはあくまでAir⇔Proxyの話であってこの段階でエラー扱いされてくれる。Proxy⇔Originの間にはそもそもデータが流れない。つまり今回のエラーは、キャリアのProxyの段階で弾かれていると想像。

2012-10-25 13:14:31
武田 憲太郎 @KentarouTakeda

となると、切断が決まって「ヘッダ入力完了」「ボディ未入力」というタイミングに限られる理由は何なのか?当然ながらサーバ側では対応できないためクライアント側で対応することになるが、そもそも可能なのか?ここで手詰まり。

2012-10-25 13:14:46
武田 憲太郎 @KentarouTakeda

以上、誰かが拾ってくれることを期待した備忘録でした。

2012-10-25 13:14:52