Create a TimeOutInterceptor to set specific timeout on some request: login and sync (Fixes #170)

This commit is contained in:
Benoit Marty 2019-07-11 15:16:25 +02:00
parent 77056aff94
commit 9e3d29b7d7
4 changed files with 68 additions and 5 deletions

View File

@ -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<Credentials>


View File

@ -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 {

View File

@ -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"
}
}

View File

@ -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<String, String>): Call<SyncResponse>