ムッシューの日記

2人の子供とのお出かけネタから趣味の釣りネタなど

AndroidアプリのHTTPS通信で408エラーとなったときの対処


AndroidアプリでHTTPS通信をするアプリを作ったのですが、サーバでHTTPの408エラーとなる事象が発生、解決までのメモ。

【解析】

wiresharkで解析したところ以下のような通信のやり取りになっていました。

sslエラーの流れ

  1. AndroidアプリがTLSv1でサーバに接続
  2. Androidアプリがデータを送信する
  3. サーバからレスポンスが返らず、1分後サーバがタイムアウトしリセットを返す(408エラー)
  4. AndroidアプリがTSLv1での通信失敗を検知し、SSLv3でリトライする
  5. サーバはSSLv3を許可していないため、ハンドシェイクエラーを返す

【原因】

HTTP要求時のContent-Lengthが正しくなかった

String型の変数(以下dataとする)をPOSTのメッセージにしたのですが、Content-Lengthにはdata.lengthを指定していた。

この場合マルチバイト文字は1文字としてカウントされてしまうが、HTTPの仕様上Content-Lengthにはバイト数の指定が必要でした。そのため、不正なContent-Length値になっていたことが応答が返らない原因でした。

Content-Lengthを以下のように修正することで解決しました。

data.getBytes(Charset.forName("UTF-8")).length);

【備考】

タイムアウト後にAndroidアプリがSSLv3でリトライすることも混乱の原因でした。

以下のようなコードでSSLContextのインスタンスを取得するときに指定したアルゴリズム(以下の場合はTLS)は、「他のバージョンをサポートする場合もある」と記載があったのでおそらくTLSv1と同様のSSLv3がリトライで使われたのかと想定されます。紛らわしい。


SSLContext sslCon = SSLContext.getInstance("TLS");


次へ 投稿

前へ 投稿

© 2017 ムッシューの日記

テーマの著者 Anders Norén