画像配信するAndroidアプリのWiFi接続で突然CloudFrontの画像が読み込めなくなった話

TL;DR

  • 画像配信を行うAndroidアプリで「画像が読み込めない」というお問い合わせとGoogle Playレビューが急に増えた
  • Androidアプリで使用していたOkHttp 2.x.xがHTTP/2に対応していないことがわかった
  • CloudFrontの設定にて、HTTP/2ではなくHTTP/1.1, HTTP/1.0で画像の配信を行うようにした
  • 根本解決としてはOkHttp 3.x.xを利用し、HTTP/2に対応したアプリをリリースした方が良い

疑問に思っていること

  • 同端末で同アプリを使用しているのに、なぜWiFiとキャリア回線でHTTP/2通信の有無が切り替わるのか
    • キャリア回線は再現性が低い
  • 3月17日(土)のタイミングで突然HTTP/2通信を行うようになったのは何の変化によるものなのか
  • 日中再現できていた端末が夜には再現できない状態になっていた

詳しい経緯

2018年3月17日(土) 午前3時頃から突然、画像配信を行うAndroidアプリにて「画像が読み込めない」というお問い合わせとGoogle Playレビューが増加した。
お問い合わせの数から、全てのAndroidユーザが対象というわけではなく、全体の5分ほどのユーザが対象であることがわかる。
原因の切り分けと調査を行った結果、auひかりのWiFi接続での再現率が高いことが判明した。
※auひかりでの再現率が高いだけで、他社WiFiやキャリア回線でも再現性があることにご注意。

OkHttp 2.x.xでログを出力できるように改修し、再現を試みたところ以下のような例外が出力されていることがわかった。

java.net.ProtocolException: Expected ':status' header not present
at com.squareup.okhttp.internal.http.Http2xStream.readHttp2HeadersList(Http2xStream.java:267)
at com.squareup.okhttp.internal.http.Http2xStream.readResponseHeaders(Http2xStream.java:149)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:737)
at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:87)
at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:722)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:576)
at com.squareup.okhttp.Call.getResponse(Call.java:287)
at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243)

なぜか特定の環境下でのみHTTP/2で通信を行っていることがわかったため、OkHttp 2.x.xにて、
明示的にHTTP/1.1を使って通信を行うようにしたところ現事象は改善した。

原因が明らかになったところで、アプリリリースまでの間、現行ユーザにアプリを使っていただくために
CloudFrontSupported HTTP Versions
HTTP/2, HTTP/1.1, HTTP/1.0からHTTP/1.1, HTTP/1.0に変更して一次対応を行った。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.