square / okhttp

Square’s meticulous HTTP client for the JVM, Android, and GraalVM.
https://square.github.io/okhttp/
Apache License 2.0
45.69k stars 9.14k forks source link

okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR/ CANCEL #3955

Open sealiasheq opened 6 years ago

sealiasheq commented 6 years ago

I am connecting to web service with last version retrofit but get me bellow error :

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

My code is like bellow :

try {
                    // Create a trust manager that does not validate certificate chains
                    final TrustManager[] trustAllCerts = new TrustManager[]{
                            new X509TrustManager() {
                                @Override
                                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                                }

                                @Override
                                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                                }

                                @Override
                                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                    return new java.security.cert.X509Certificate[]{};
                                }
                            }
                    };

                    // Install the all-trusting trust manager
                    final SSLContext sslContext = SSLContext.getInstance("SSL");
                    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
                    // Create an ssl socket factory with our all-trusting manager
                    final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
                    OkHttpClient.Builder builder = new OkHttpClient.Builder();
                    builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
                    builder.hostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    });

                    OkHttpClient okHttpClient = builder.
                            build();
                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl("https://xxx")
                            .client(okHttpClient)
                            .addConverterFactory(GsonConverterFactory.create())
                            .addConverterFactory(ScalarsConverterFactory.create())
                            .build();
                    final PublicApi request = retrofit.create(PublicApi.class);
                    Call<GetStatusSaveContactListModel> call = request.sendContactLists("saveContactList", obj.toString());
                    call.enqueue(new Callback<GetStatusSaveContactListModel>() {
                        @Override
                        public void onResponse(@NonNull Call<GetStatusSaveContactListModel> call, @NonNull Response<GetStatusSaveContactListModel> response) {
                        }

                        @Override
                        public void onFailure(@NonNull Call<GetStatusSaveContactListModel> call, Throwable t) {
                        }
                    });

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }

And

@POST("/web_service/mobile/rest")
Call<GetStatusSaveContactListModel> sendContactLists(@Query("function") String function,
                                                     @Query("data") String data);

And

implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
yschimke commented 1 year ago

I suspect might be related to https://github.com/square/okhttp/pull/7801, would suggest retesting on OkHttp 5.0.0-alpha12 (not available yet).

ilgizsa commented 6 months ago

I have same issue OkHttp 5.0.0-alpha3, RxJava2 I have 100% reproducibility. We need Charles, we need to put a breakpoint in Charles on the request When the timeout expires, there will be an error in the logcat, but the request will be repeated endlessly judging by Charles’ session Therefore, the version of Nginx does not matter If you remove the breakpoint, the request will be completed, but the result will not be processed in RxJava. Adding OkHttpClient.Builder.retryOnConnectionFailure(false) helped me, the error remains StreamResetException, but there is no longer an endless retray of requests. And don’t care about StreamResetException since it is instance of IOException

okhttp3.internal.http2.StreamResetException: stream was reset: INTERNAL_ERROR
 at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:148)
 at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:97)
 at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110)
 at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at com.finstar.pesoredee.http.curl.CurlInterceptor.intercept(CurlInterceptor.kt:36)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.AuthInterceptor.intercept(HttpClient.kt:119)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.HeadersInterceptor.intercept(HeadersInterceptor.kt:38)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:96)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.HostInterceptor.intercept(HttpClient.kt:96)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:202)
 at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:518)
ilgizsa commented 6 months ago
Example for reproduce: every 60 seconds request will be repeat if set breakpoint on request in Charles ``` class MainActivity : AppCompatActivity() { private lateinit var apiService: ApiService private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val okHttpClient = OkHttpClient .Builder() .cache(Cache(createCacheDir(), 10L * 1024 * 1024)) .connectTimeout(30L, TimeUnit.SECONDS) .readTimeout(60L, TimeUnit.SECONDS) .writeTimeout(60L, TimeUnit.SECONDS) // Every 60 seconds request will be repeat if set breakpoint on request in Charles .addNetworkInterceptor(HeadersInterceptor()) .addNetworkInterceptor( HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.HEADERS } ) .disableCertificateValidation() .build() val moshi = Moshi.Builder() .add(KotlinJsonAdapterFactory()) .build() val retrofit = Retrofit.Builder() .baseUrl(ApiService.baseUrl) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(MoshiConverterFactory.create(moshi)) .client(okHttpClient) .build() apiService = retrofit.create(ApiService::class.java) fetchIssues() } @SuppressLint("CheckResult") private fun fetchIssues() { apiService.getIssues(authorization = null) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribeBy( onSuccess = { Toast.makeText(this, "Success", Toast.LENGTH_LONG).show() Logger.DEFAULT.log("------Issues successfully loaded------") //Logger.DEFAULT.log("Issues was loaded:\n${it.joinToString(separator = "\n --- ", prefix = " --- ")}") }, onError = { Toast.makeText(this, "Error", Toast.LENGTH_LONG).show() it.printStackTrace() } ) } private fun createCacheDir(): File { val cacheDir = File(application.cacheDir, "network-cache") if ((!cacheDir.exists() || !cacheDir.isDirectory) && !cacheDir.mkdir()) { throw IllegalStateException("Unable to create network cache directory") } return cacheDir } class HeadersInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { return chain.proceed( chain .request() .newBuilder() .addHeader("Accept", "application/vnd.github+json") .addHeader("X-GitHub-Api-Version", "2022-11-28") .build() ) } } interface ApiService { companion object { const val baseUrl = "https://api.github.com" } @GET("repos/octocat/Hello-World/issues") fun getIssues( @Header("Authorization") authorization: String?, ): Single> } @JsonClass(generateAdapter = true) data class Issue( val id: Long, val url: String, val number: Long, val title: String, ) @SuppressLint("CustomX509TrustManager") private object TrustAllManager : X509TrustManager { override fun getAcceptedIssuers(): Array = arrayOf() override fun checkClientTrusted(chain: Array, authType: String) = Unit override fun checkServerTrusted(chain: Array, authType: String) = Unit } fun OkHttpClient.Builder.disableCertificateValidation(): OkHttpClient.Builder = arrayOf(TrustAllManager) .let { managers -> sslSocketFactory( SSLContext .getInstance("SSL") .apply { init(null, managers, java.security.SecureRandom()) } .socketFactory, managers.first() ) hostnameVerifier { _, _ -> true } } } ``` Dependencies ``` implementation(platform("com.squareup.okhttp3:okhttp-bom:5.0.0-alpha.3")) implementation("com.squareup.okhttp3:okhttp") implementation("com.squareup.okhttp3:logging-interceptor") implementation("io.reactivex.rxjava2:rxjava:2.2.21") implementation("io.reactivex.rxjava2:rxandroid:2.1.1") implementation("io.reactivex.rxjava2:rxkotlin:2.4.0") implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:adapter-rxjava2:2.9.0") implementation("com.squareup.retrofit2:converter-moshi:2.9.0") implementation("com.squareup.moshi:moshi-kotlin:1.14.0") implementation("com.squareup.moshi:moshi-adapters:1.14.0") ksp("com.squareup.moshi:moshi-kotlin-codegen:1.14.0") ```
hamidradical commented 5 months ago

Any progress? becuase my some user face this type of error while downloading large json data from stream api. It happens sometime and in some users' device.

i have no idea to reproduce it by my own and in my android device.

MADDY312 commented 2 months ago

any progress on this?

okhttp3.internal.http2.StreamResetException: stream was reset: INTERNAL_ERROR
 at okhttp3.internal.http2.Http2Stream.takeHeaders(Http2Stream.kt:148)
 at okhttp3.internal.http2.Http2ExchangeCodec.readResponseHeaders(Http2ExchangeCodec.kt:97)
 at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110)
 at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at com.finstar.pesoredee.http.curl.CurlInterceptor.intercept(CurlInterceptor.kt:36)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.AuthInterceptor.intercept(HttpClient.kt:119)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.HeadersInterceptor.intercept(HeadersInterceptor.kt:38)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:96)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at pesoredee.api.http.HostInterceptor.intercept(HttpClient.kt:96)
 at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
 at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:202)
 at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:518)