У меня есть приложение для Android (4.4.4+), в котором используются следующие библиотеки:
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
compile 'com.squareup.okio:okio:1.7.0'
У меня есть nginx (версия 1.9.14), скомпилированный с OpenSSL (исходный код версии 1.0.2g), использование openSSL подтверждено с помощью nginx -V на CentOS 7. Конфигурация nginx http2 включена для обратного прокси:
server {
listen 443 ssl http2;
ssl on;
server_name mobile.site.com;
ssl_certificate /etc/pki/tls/certs/start_cert.pem;
ssl_certificate_key /etc/pki/tls/certs/start_cert.key;
proxy_cache one;
underscores_in_headers on;
access_log /var/log/nginx/ssl.log ssl_custom;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_pass https://10.10.1.31:443;
}
}
Запуск команды на сервере:
echo | openssl s_client -alpn h2 -connect
Возврат:
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3718 bytes and written 442 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
ALPN protocol: h2
При просмотре URL-адреса API из любого современного браузера в журналах SSL и в надстройке HTTP / 2 Chrome отображается соединение HTTP / 2. Предполагая, что HTTP / 2 правильно настроен в nginx / OpenSSL.
Клиенты Android OKHttp отказываются от HTTP / 2:
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();
okHttpClient = new OkHttpClient.Builder()
.followSslRedirects(true)
.protocols(Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
.connectionSpecs(Collections.singletonList(spec))
.sslSocketFactory(new TLSSocketFactory((SSLSocketFactory) TLSSocketFactory.getDefault()))
.retryOnConnectionFailure(true)
.connectTimeout(25, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(30, 120, TimeUnit.SECONDS))
.addInterceptor(new AddCookiesInterceptor())
.addInterceptor(new ReceivedCookiesInterceptor())
.build();
Я написал настраиваемую фабрику сокетов TLS, позволяющую использовать TLS 1.2 на ‹= Android 4.4.4.
TLSv1.2 действительно работает на 4.4.4+ с этой настраиваемой фабрикой сокетов, но я также пробовал работать на 5.0+ с настраиваемой фабрикой сокетов и без нее, не повезло с HTTP / 2.
HTTP / 2 не работает на kit-kat, lollipop и marshmallow, но работает в предварительной версии для разработчиков N (также известной как New York Cheesecake). Никаких ошибок не возникает, просто всегда подключается как HTTP / 1.1. У меня возникают проблемы с поиском статей, относящихся к OKhttp и HTTP / 2, в большинстве справочных вопросов / сообщений просто говорится об использовании ALPN, но нет ресурсов, чтобы подробно рассказать об использовании. В документации OkHTTP нет ясности в отношении использования и практики развертывания HTTP / 2, но на главной странице говорится, что он поддерживает его. Мы будем очень благодарны за любую помощь или руководство, даже просто толчок в правильном направлении будет огромным подспорьем. Пожалуйста, дайте мне знать, если я пропустил что-нибудь, что может помочь в процессе, заранее спасибо!
Обновление 1. Я нашел один из связанных с этим вопросов SO с очень расплывчатым ответом: [SO link] https://stackoverflow.com/questions/31850249/how-to-use-http-2-with-okhttp-on-android-devices?Rq=1 с комментарием, в котором предлагается использовать причал, но только в отношении рабочего стола использование, а не использование Android.
Обновление 2: в этой статье показано, что ALPN включен в Android 4.4: https://github.com/http2/http2-spec/wiki/ALPN-Status
Обновление 3: удалось подключить HTTP / 2 с использованием +5.0, но не 4.4.4. Мне не нужно опускаться ниже 4.4.4, так как внутренние целевые устройства являются проблемой для http / 2, и они работают с 4.4.4. Мне удалось обновить приложение, чтобы использовать протокол безопасности Google Play Services в качестве подключения сокета OKHttp, но используемые нами устройства 4.4.4 не поддерживают Google, поэтому я не могу использовать на них защитные сокеты PlayServices.