From 9e3d29b7d71a1ee8ed8f0cfdbc44c9f07c958c56 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 11 Jul 2019 15:16:25 +0200 Subject: [PATCH] Create a TimeOutInterceptor to set specific timeout on some request: login and sync (Fixes #170) --- .../matrix/android/internal/auth/AuthAPI.kt | 3 + .../android/internal/di/NetworkModule.kt | 9 ++- .../internal/network/TimeOutInterceptor.kt | 56 +++++++++++++++++++ .../android/internal/session/sync/SyncAPI.kt | 5 ++ 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/TimeOutInterceptor.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt index 2ab64527..d795a3c4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthAPI.kt @@ -21,6 +21,7 @@ import im.vector.matrix.android.internal.auth.data.PasswordLoginParams import im.vector.matrix.android.internal.network.NetworkConstants import retrofit2.Call import retrofit2.http.Body +import retrofit2.http.Headers import retrofit2.http.POST /** @@ -30,9 +31,11 @@ internal interface AuthAPI { /** * Pass params to the server for the current login phase. + * Set all the timeouts to 1 minute * * @param loginParams the login parameters */ + @Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000") @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login") fun login(@Body loginParams: PasswordLoginParams): Call diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt index 2f9e8c69..4f3130c5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt @@ -21,16 +21,13 @@ import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides import im.vector.matrix.android.BuildConfig -import im.vector.matrix.android.internal.network.AccessTokenInterceptor -import im.vector.matrix.android.internal.network.UnitConverterFactory +import im.vector.matrix.android.internal.network.TimeOutInterceptor import im.vector.matrix.android.internal.network.UserAgentInterceptor import im.vector.matrix.android.internal.network.interceptors.CurlLoggingInterceptor import im.vector.matrix.android.internal.network.interceptors.FormattedJsonHttpLogger import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import okreplay.OkReplayInterceptor -import retrofit2.Retrofit -import retrofit2.converter.moshi.MoshiConverterFactory import java.util.concurrent.TimeUnit @Module @@ -68,15 +65,17 @@ internal object NetworkModule { @JvmStatic @Unauthenticated fun providesOkHttpClient(stethoInterceptor: StethoInterceptor, + timeoutInterceptor: TimeOutInterceptor, userAgentInterceptor: UserAgentInterceptor, httpLoggingInterceptor: HttpLoggingInterceptor, curlLoggingInterceptor: CurlLoggingInterceptor, okReplayInterceptor: OkReplayInterceptor): OkHttpClient { return OkHttpClient.Builder() - .connectTimeout(1, TimeUnit.MINUTES) + .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .addNetworkInterceptor(stethoInterceptor) + .addInterceptor(timeoutInterceptor) .addInterceptor(userAgentInterceptor) .addInterceptor(httpLoggingInterceptor) .apply { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/TimeOutInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/TimeOutInterceptor.kt new file mode 100644 index 00000000..eea437cb --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/TimeOutInterceptor.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.matrix.android.internal.network + +import okhttp3.Interceptor +import okhttp3.Response +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +/** + * Get the specific headers to apply specific timeout + * Inspired from https://github.com/square/retrofit/issues/2561 + */ +internal class TimeOutInterceptor @Inject constructor() : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + var request = chain.request() + + val connectTimeout = request.header(CONNECT_TIMEOUT)?.let { Integer.valueOf(it) } ?: chain.connectTimeoutMillis() + val readTimeout = request.header(READ_TIMEOUT)?.let { Integer.valueOf(it) } ?: chain.readTimeoutMillis() + val writeTimeout = request.header(WRITE_TIMEOUT)?.let { Integer.valueOf(it) } ?: chain.writeTimeoutMillis() + + val newRequestBuilder = request.newBuilder() + .removeHeader(CONNECT_TIMEOUT) + .removeHeader(READ_TIMEOUT) + .removeHeader(WRITE_TIMEOUT) + + request = newRequestBuilder.build() + + return chain + .withConnectTimeout(connectTimeout, TimeUnit.MILLISECONDS) + .withReadTimeout(readTimeout, TimeUnit.MILLISECONDS) + .withWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS) + .proceed(request) + } + + companion object { + // Custom header name + const val CONNECT_TIMEOUT = "CONNECT_TIMEOUT" + const val READ_TIMEOUT = "READ_TIMEOUT" + const val WRITE_TIMEOUT = "WRITE_TIMEOUT" + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncAPI.kt index 33fa99ec..669f556c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/SyncAPI.kt @@ -20,10 +20,15 @@ import im.vector.matrix.android.internal.network.NetworkConstants import im.vector.matrix.android.internal.session.sync.model.SyncResponse import retrofit2.Call import retrofit2.http.GET +import retrofit2.http.Headers import retrofit2.http.QueryMap internal interface SyncAPI { + /** + * Set all the timeouts to 1 minute + */ + @Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000") @GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "sync") fun sync(@QueryMap params: Map): Call