OkHttp Android stream was reset: HTTP_1_1_REQUIRED
Asked Answered
F

2

9

We are developing an Android application that should use Http/2 to connect to our Azure App Service. On the Azure App Service we have Http/2 enabled by using the steps in the following blog post: https://blogs.msdn.microsoft.com/appserviceteam/2018/04/13/announcing-http2-support-in-azure-app-service/

Our requests are secured with Mutual SSL, so that the application has to send it's client certificate.

When we try to execute a call to our app service with OkHttp, we always get the following error and stacktrace. When we try to do a call to the twitter api with the same Android code, this is working.

Does anybody have an idea on how to fix this?

We are using OkHttp version 3.10.0.

Stacktrace:

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

add this line in builder

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

like this

 private OkHttpClient client = new OkHttpClient.Builder()
            .protocols(Util.immutableList(Protocol.HTTP_1_1))
            .build();
Reverent answered 21/1, 2020 at 15:58 Comment(0)
K
2

HTTP/2 does not really support client certificates at this time - especially when such connections only apply to some of the resources on the server. There is a proposal to allow this, but it is not yet standardised and, AFAIK, not yet supported by any implementation.

Until this is supported, the correct response is to suggest a downgrade to HTTP/1.1 with a HTTP_1_1_REQUIRED error code and the client should retry with HTTP/1.1.

Other implementations do this as well as Azure.

Kenogenesis answered 10/6, 2018 at 13:6 Comment(2)
This is odd. Because when I connect to my Azure endpoint with client certificate using the Edge browser. It is correctly returning a response and I see that HTTP/2 is used with the network monitor... This would mean it supports client certificate.Foresee
Extra information: the client certificates do apply to every resource on the server. Not only to specific endpoints.Foresee

© 2022 - 2024 — McMap. All rights reserved.