我有一个使用以下库的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在centOS 7上用nginx -V确认。 为反向代理启用了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
从任何现代浏览器浏览API URL会导致SSL日志和HTTP / 2 chrome加载项中显示HTTP / 2连接。假设在nginx / OpenSSL中正确配置了HTTP / 2.
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套接字工厂,以便在< = Android 4.4.4上启用TLS 1.2。
TLSv1.2确实在4.4.4+上使用这个自定义套接字工厂,但是我也试过在5.0+上运行,有或没有自定义套接字工厂,没有HTTP / 2运气。
HTTP / 2在kit-kat,棒棒糖和marshmallow上失败,但适用于“N”开发者预览(a.k.a. New York Cheesecake)。不会抛出任何错误,只是连接为HTTP / 1.1。我无法找到任何与OKhttp和HTTP / 2相关的文章,大多数帮助问题/帖子只是说使用ALPN,但没有资源来详细说明用法。关于HTTP / 2使用和部署实践的OkHTTP文档并不清楚,但主页说它支持它。任何帮助或专家指导将不胜感激,即使只是在正确的方向推动将是一个巨大的帮助。如果我错过了可能有助于此过程的任何事情,请告诉我,提前感谢!
更新1:我发现了一个与此相关的SO问题,其中一个非常含糊的答案:[SO link] How to use http/2 with Okhttp on Android devices?,其中的评论提出了使用jetty的建议,但仅限于桌面用法,而不是Android用法。
更新2:本文显示ALPN已启用Android 4.4:https://github.com/http2/http2-spec/wiki/ALPN-Status
更新3:能够使用+5.0连接HTTP / 2,而不是4.4.4。我不需要低于4.4.4,因为内部目标设备是http / 2的关注点,它们运行4.4.4。我能够更新应用程序以使用Google Play服务安全协议作为OKHttp套接字连接,但我们使用的4.4.4设备未启用Google,因此我无法在这些设备上使用PlayServices安全套接字。
答案 0 :(得分:0)
根据swankjesse,
后续步骤: 不要在Android 4.4及更早版本上使用ALPN;它在那里打破了。 恢复以前稳定的Android版本的NPN。