OkHttp Android 流已重置:HTTP_1_1_REQUIRED

Posted

技术标签:

【中文标题】OkHttp Android 流已重置:HTTP_1_1_REQUIRED【英文标题】:OkHttp Android stream was reset: HTTP_1_1_REQUIRED 【发布时间】:2018-11-19 10:57:27 【问题描述】:

我们正在开发一个应使用 Http/2 连接到我们的 Azure 应用服务的 android 应用程序。 在 Azure 应用服务上,我们使用以下博文中的步骤启用了 Http/2:https://blogs.msdn.microsoft.com/appserviceteam/2018/04/13/announcing-http2-support-in-azure-app-service/

我们的请求通过 Mutual SSL 保护,因此应用程序必须发送它的客户端证书。

当我们尝试使用 OkHttp 调用我们的应用服务时,我们总是会收到以下错误和堆栈跟踪。当我们尝试使用相同的 Android 代码调用 twitter api 时,这是可行的。

有人知道如何解决这个问题吗?

我们使用的是 OkHttp 版本 3.10.0。

堆栈跟踪:

 06-08 15:54:00.173 31318-31351/be.wgkovl.evdt W/be.wgkovl.evdt.utils.BaseService:流已重置:HTTP_1_1_REQUIREDokhttp3.internal.http2.StreamResetException:流已重置:HTTP_1_1_REQUIRED
                在 okhttp3.internal.http2.Http2Stream.takeResponseHeaders(Http2Stream.java:153) ~[na:0.0]
                在 okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:125) ~[na:0.0]
                在 okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
                在 okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[na:0.0]
                在 okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[na:0.0]
                在 okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
                在 okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[na:0.0]
                在 okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[na:0.0]
                在 okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200) ~[na:0.0]
                在 okhttp3.RealCall.execute(RealCall.java:77) ~[na:0.0]
                在 be.wgkovl.evdt.utils.BaseService.executeRequest(BaseService.java:277) ~[na:0.0]
                在 be.wgkovl.evdt.service.UserManagementService$1.doInBackground(UserManagementService.java:123) ~[na:0.0]
                在 be.wgkovl.evdt.service.UserManagementService$1.doInBackground(UserManagementService.java:101) ~[na:0.0]
                在 android.os.AsyncTask$2.call(AsyncTask.java:295) ~[na:0.0]
                在 java.util.concurrent.FutureTask.run(FutureTask.java:237) ~[na:0.0]
                在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) ~[na:0.0]
                在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) ~[na:0.0]
                在 java.lang.Thread.run(Thread.java:818) ~[na:0.0]

【问题讨论】:

【参考方案1】:

在构建器中添加这一行

.protocols(Util.immutableList(Protocol.HTTP_1_1))

喜欢这个

 private OkHttpClient client = new OkHttpClient.Builder()
            .protocols(Util.immutableList(Protocol.HTTP_1_1))
            .build();

【讨论】:

【参考方案2】:

HTTP/2 目前并不真正支持客户端证书——尤其是当此类连接仅适用于服务器上的某些资源时。有a proposal to allow this,但它还没有标准化,而且,AFAIK,还没有任何实现支持。

在支持此功能之前,the correct response is to suggest a downgrade to HTTP/1.1 带有 HTTP_1_1_REQUIRED 错误代码,客户端应使用 HTTP/1.1 重试。

Other implementations 和 Azure 一样。

【讨论】:

这很奇怪。因为当我使用 Edge 浏览器通过客户端证书连接到我的 Azure 端点时。它正确返回响应,我看到 HTTP/2 与网络监视器一起使用...这意味着它支持客户端证书。 额外信息:客户端证书确实适用于服务器上的每个资源。不仅针对特定端点。

以上是关于OkHttp Android 流已重置:HTTP_1_1_REQUIRED的主要内容,如果未能解决你的问题,请参考以下文章

url编码okhttp3 android删除%20

如何在 Android 设备上使用 http/2 和 Okhttp?

Android 上的 okhttp 出现错误,预期为 null,但 okhttp3.internal.http1.Http1Codec

OKHttp Android没有通过http2 alpn连接到nginx

Android笔记-使用okhttp3库发送http请求

与 OkHttp 连接的 Android http 不工作