okhttp: HTTP2 POST - java.io.IOException: stream was reset: REFUSED_STREAM

Hi, we are using okhttp v3.2.0 and, in the attempt to migrate to http2, we compiled nginx v1.9.15 (latest as of today) against libssl 1.0.2g (ALPN support). Any client platform other than okhttp works as expected.

As far as okhttp is concerned, it looks like GET requests are correctly served by nginx, although the app fails with the following error while submitting any POST request:

04-22 15:10:15.934 18768-19313/com.pymmt.pymmt E/HttpImpl: NativeLogger Exception during http request
                                                          java.io.IOException: stream was reset: REFUSED_STREAM
                                                              at okhttp3.internal.framed.FramedStream.getResponseHeaders(FramedStream.java:145)
                                                              at okhttp3.internal.http.Http2xStream.readResponseHeaders(Http2xStream.java:149)
                                                              at okhttp3.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:723)
                                                              at okhttp3.internal.http.HttpEngine.access$200(HttpEngine.java:81)
                                                              at okhttp3.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:708)
                                                              at okhttp3.internal.http.HttpEngine.readResponse(HttpEngine.java:563)
                                                              at okhttp3.RealCall.getResponse(RealCall.java:241)
                                                              at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
                                                              at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
                                                              at okhttp3.RealCall.access$100(RealCall.java:30)
                                                              at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
                                                              at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
                                                              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                                              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                                              at java.lang.Thread.run(Thread.java:818)

Nginx in debug mode complains about the client prematurely closing the stream:

2016/04/22 15:10:16 [debug] 7894#7894: *369 process http2 frame type:3 f:0 l:4 sid:5
2016/04/22 15:10:16 [debug] 7894#7894: *369 http2 RST_STREAM frame, sid:5 status:8
2016/04/22 15:10:16 [info] 7894#7894: *369 client canceled stream 5, client: 5.168.111.94, server: pymmt.com, request: "POST /generic/api/v1/user/login/uniqueId HTTP/2.0", host: "py.pymmt.com"
2016/04/22 15:10:16 [debug] 7894#7894: *369 http run request: "/generic/api/v1/user/login/uniqueId?"
2016/04/22 15:10:16 [debug] 7894#7894: *369 http2 read client request body handler
2016/04/22 15:10:16 [info] 7894#7894: *369 client prematurely closed stream, client: 5.168.111.94, server: pymmt.com, request: "POST /generic/api/v1/user/login/uniqueId HTTP/2.0", host: "py.pymmt.com"4: *371 SSL buf copy: 27

The full nginx debug log of the request is available here: http://pastebin.com/LBms9emf

Currently, as suggested in other issues, we got the app to work by forcing it on HTTP1.1. Thanks in advance PL

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 6
  • Comments: 31 (10 by maintainers)

Most upvoted comments

Here’s the commit that introduced this, https://github.com/nginx/nginx/commit/536b5510d1051281bd9411723102333e6d1dbdf2

Seems strange, but I think it’s within the spec.

As a further heads-up, this patch is now available in mainline nginx branch 1.11, which as a positive side-effect makes connection-initiating POST requests over HTTP/2 in major browsers (Firefox, MS Edge, Safari 9.x and alternative browsers on iOS, etc.) work again.

@dave-r12 that’s great news.

For anyone interested, I posted this on the other issue:

A quick update: nginx attached a proposed patch on their issue tracker. I tested patch against OkHttp and it worked perfectly.

Maybe some traction from nginx? They just responded on the ticket:

I agree, while it’s not optimal from the latency point of view, such approach significantly simplifies the code. So it’s a fair price, that was paid at the current stage of HTTP/2 implementation. Introducing some kind of preread buffer will be the next step.