|
|
|
@ -3,28 +3,27 @@ package org.koitharu.kotatsu.core.network
|
|
|
|
import okhttp3.Interceptor
|
|
|
|
import okhttp3.Interceptor
|
|
|
|
import okhttp3.Response
|
|
|
|
import okhttp3.Response
|
|
|
|
import okhttp3.internal.closeQuietly
|
|
|
|
import okhttp3.internal.closeQuietly
|
|
|
|
import org.koitharu.kotatsu.core.exceptions.TooManyRequestExceptions
|
|
|
|
import org.koitharu.kotatsu.parsers.exception.TooManyRequestExceptions
|
|
|
|
import java.time.Instant
|
|
|
|
|
|
|
|
import java.time.ZonedDateTime
|
|
|
|
import java.time.ZonedDateTime
|
|
|
|
import java.time.format.DateTimeFormatter
|
|
|
|
import java.time.format.DateTimeFormatter
|
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit
|
|
|
|
|
|
|
|
|
|
|
|
class RateLimitInterceptor : Interceptor {
|
|
|
|
class RateLimitInterceptor : Interceptor {
|
|
|
|
override fun intercept(chain: Interceptor.Chain): Response {
|
|
|
|
override fun intercept(chain: Interceptor.Chain): Response {
|
|
|
|
val response = chain.proceed(chain.request())
|
|
|
|
val response = chain.proceed(chain.request())
|
|
|
|
if (response.code == 429) {
|
|
|
|
if (response.code == 429) {
|
|
|
|
val retryDate = response.header(CommonHeaders.RETRY_AFTER)?.parseRetryDate()
|
|
|
|
|
|
|
|
val request = response.request
|
|
|
|
val request = response.request
|
|
|
|
response.closeQuietly()
|
|
|
|
response.closeQuietly()
|
|
|
|
throw TooManyRequestExceptions(
|
|
|
|
throw TooManyRequestExceptions(
|
|
|
|
url = request.url.toString(),
|
|
|
|
url = request.url.toString(),
|
|
|
|
retryAt = retryDate,
|
|
|
|
retryAfter = response.header(CommonHeaders.RETRY_AFTER)?.parseRetryAfter() ?: 0L,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return response
|
|
|
|
return response
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun String.parseRetryDate(): Instant? {
|
|
|
|
private fun String.parseRetryAfter(): Long {
|
|
|
|
return toLongOrNull()?.let { Instant.now().plusSeconds(it) }
|
|
|
|
return toLongOrNull()?.let { TimeUnit.SECONDS.toMillis(it) }
|
|
|
|
?: ZonedDateTime.parse(this, DateTimeFormatter.RFC_1123_DATE_TIME).toInstant()
|
|
|
|
?: ZonedDateTime.parse(this, DateTimeFormatter.RFC_1123_DATE_TIME).toInstant().toEpochMilli()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|