Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR #8129

Closed
jalr4ever opened this issue Dec 5, 2023 · 1 comment
Labels
bug Bug in existing code

Comments

@jalr4ever
Copy link

jalr4ever commented Dec 5, 2023

Environment

Client

openjdk version "1.8.0_352"
OpenJDK Runtime Environment (build 1.8.0_352-b08)
OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)
<dependency>
    <groupId>com.squareup.okio</groupId>
    <artifactId>okio</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.10.0</version>
</dependency>

Server

entry point proxy:

nginx version: openresty/1.21.4.1

backend server enviroment:

openjdk version "1.8.0_352"
OpenJDK Runtime Environment (build 1.8.0_352-b08)
OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)
Springboot 2.7.15
Starting Servlet engine: [Apache Tomcat/9.0.80]

Reproduce

In my scenario, I used okhttp3 as a large file upload HTTP client. Client code something like below:

byte[] buffer = new byte[4 * 1024 * 1024];
RequestBody requestBody = new RequestBody() {
    @Nullable
    @Override
    public MediaType contentType() {
        return MediaType.parse("application/octet-sampleStream");
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        int len;
        try {
            while ((len = sampleStream.read(buffer)) != -1) {
                sink.write(buffer, 0, len);
            }
        } catch (BusinessException e) {
            log.error(e.getMessage());
            throw new IOException();
        } finally {
            sink.flush();
            sink.close();
        }
    }
};

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
String timestamp = String.valueOf(System.currentTimeMillis());
String nonce = CommonUtil.newUuid();
String paramString = timestamp + nonce;
String signature = ApiSignUtil.generateSignature(paramString, decryptedSecretKey);
String authorization = accessKey + ":" + signature;
builder.addInterceptor(chain -> {
    Request.Builder requesetBuilder = chain.request().newBuilder()
            .addHeader("Referer", address)
            .addHeader("Authorization", authorization)
            .addHeader("Timestamp", timestamp)
            .addHeader("nonce", nonce);
    Request request = requesetBuilder.build();
    return chain.proceed(request);
});
Response response = builder
        .sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())
        .hostnameVerifier(new TrustAllHostnameVerifier())
        .callTimeout(0, TimeUnit.SECONDS)
        .readTimeout(0, TimeUnit.SECONDS)
        .writeTimeout(15, TimeUnit.MINUTES)
        .connectTimeout(15, TimeUnit.MINUTES)
        .build()
        .newCall(request)
        .execute();

Issue & Stracktrace:

When I upload a file as its size larger than 5GB, it happened error like this:

okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR
        at okhttp3.internal.http2.Http2Stream.checkOutNotClosed$okhttp(Http2Stream.kt:646)
        at okhttp3.internal.http2.Http2Stream$FramingSink.flush(Http2Stream.kt:576)
        at okio.ForwardingSink.flush(ForwardingSink.kt:32)
        at okhttp3.internal.connection.Exchange$RequestBodySink.flush(Exchange.kt:228)
        at okio.RealBufferedSink.flush(RealBufferedSink.kt:270)
        at com.jalr.handler.TableSampleDataUploadHandler$1.writeTo(TableSampleDataUploadHandler.java:205)
        at com.jalr.common.util.CommonOkHttpClientUtil.lambda$getInnerOkhttpClientBuilder$0(CommonOkHttpClientUtil.java:104)
        at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)

At the same time, the server entry point nginx proxy returns HTTP 408 code for this error.

What I have attempted?

I tried to change the client protocol to HTTP 1.1 by .protocols() in okhttp3 builder, but this issue still occurred occasionally, somehow it's way less likely for the problem to happen now.

What's the reason for this issue? Is there any other way I can fix this issue?

@jalr4ever jalr4ever added the bug Bug in existing code label Dec 5, 2023
@yschimke
Copy link
Collaborator

Try with 4.12 in case some recent fixes affect this. Without a repro against that server, it will be hard to diagnose.

But I suspect that the server or proxy is telling you it doesn't like such a big request. If you can complete this with curl or another client, it would help see if it's definitely working.

Closing for now as no action to take. Please make a repro or give us more debug info to go on.

You can see more detail with HTTP2 frame logging - https://square.github.io/okhttp/contribute/debug_logging/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug in existing code
Projects
None yet
Development

No branches or pull requests

2 participants