From 6d880c938a32cf0723d37fcd708bc69f42be8af9 Mon Sep 17 00:00:00 2001 From: Alessandro Jean <14254807+alessandrojean@users.noreply.github.com> Date: Fri, 4 Nov 2022 23:54:52 -0300 Subject: [PATCH] Retry the MAL request if the token is expired (#8437) Retry the MAL request if the token expired. --- .../myanimelist/MyAnimeListInterceptor.kt | 58 +++++++++++++------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt index da1768178d..16313520c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListInterceptor.kt @@ -20,23 +20,9 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var t } // Refresh access token if expired if (oauth != null && oauth!!.isExpired()) { - val newOauth = runCatching { - val oauthResponse = chain.proceed(MyAnimeListApi.refreshTokenRequest(oauth!!)) - - if (oauthResponse.isSuccessful) { - oauthResponse.parseAs() - } else { - oauthResponse.close() - null - } - } - - if (newOauth.getOrNull() == null) { - throw IOException("Failed to refresh the access token") - } - - setAuth(newOauth.getOrNull()) + setAuth(refreshToken(chain)) } + if (oauth == null) { throw IOException("No authentication token") } @@ -46,7 +32,26 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var t .addHeader("Authorization", "Bearer ${oauth!!.access_token}") .build() - return chain.proceed(authRequest) + val response = chain.proceed(authRequest) + val tokenIsExpired = response.headers["www-authenticate"] + ?.contains("The access token expired") ?: false + + // Retry the request once with a new token in case it was not already refreshed + // by the is expired check before. + if (response.code == 401 && tokenIsExpired) { + response.close() + + val newToken = refreshToken(chain) + setAuth(newToken) + + val newRequest = originalRequest.newBuilder() + .addHeader("Authorization", "Bearer ${newToken.access_token}") + .build() + + return chain.proceed(newRequest) + } + + return response } /** @@ -58,4 +63,23 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList, private var t this.oauth = oauth myanimelist.saveOAuth(oauth) } + + private fun refreshToken(chain: Interceptor.Chain): OAuth { + val newOauth = runCatching { + val oauthResponse = chain.proceed(MyAnimeListApi.refreshTokenRequest(oauth!!)) + + if (oauthResponse.isSuccessful) { + oauthResponse.parseAs() + } else { + oauthResponse.close() + null + } + } + + if (newOauth.getOrNull() == null) { + throw IOException("Failed to refresh the access token") + } + + return newOauth.getOrNull()!! + } }