Remove all custom rate limit interceptors (#13394)
This commit is contained in:
parent
2f3b472986
commit
024b8c6667
|
@ -6,12 +6,8 @@ ext {
|
||||||
extName = 'MangaDex'
|
extName = 'MangaDex'
|
||||||
pkgNameSuffix = 'all.mangadex'
|
pkgNameSuffix = 'all.mangadex'
|
||||||
extClass = '.MangaDexFactory'
|
extClass = '.MangaDexFactory'
|
||||||
extVersionCode = 166
|
extVersionCode = 167
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
apply from: "$rootDir/common.gradle"
|
||||||
compileOnly(libs.okhttp)
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.extension.all.mangadex.dto.MangaListDto
|
||||||
import eu.kanade.tachiyomi.extension.all.mangadex.dto.RelationshipDto
|
import eu.kanade.tachiyomi.extension.all.mangadex.dto.RelationshipDto
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.MangasPage
|
import eu.kanade.tachiyomi.source.model.MangasPage
|
||||||
|
@ -59,9 +60,8 @@ abstract class MangaDex(final override val lang: String, private val dexLang: St
|
||||||
.add("User-Agent", "Tachiyomi " + System.getProperty("http.agent"))
|
.add("User-Agent", "Tachiyomi " + System.getProperty("http.agent"))
|
||||||
|
|
||||||
override val client = network.client.newBuilder()
|
override val client = network.client.newBuilder()
|
||||||
.addNetworkInterceptor(mdRateLimitInterceptor)
|
.rateLimit(3)
|
||||||
.addInterceptor(coverInterceptor)
|
.addInterceptor(MdAtHomeReportInterceptor(network.client, headers))
|
||||||
.addInterceptor(MdAtHomeReportInterceptor(network.client, headersBuilder().build()))
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// POPULAR Manga Section
|
// POPULAR Manga Section
|
||||||
|
|
|
@ -13,18 +13,6 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
/**
|
|
||||||
* Rate limit requests ignore covers though
|
|
||||||
*/
|
|
||||||
private val coverRegex = Regex("""/images/.*\.jpg""")
|
|
||||||
private val baseInterceptor = RateLimitInterceptor(3)
|
|
||||||
val mdRateLimitInterceptor = Interceptor { chain ->
|
|
||||||
return@Interceptor when (chain.request().url.toString().contains(coverRegex)) {
|
|
||||||
true -> chain.proceed(chain.request())
|
|
||||||
false -> baseInterceptor.intercept(chain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interceptor to post to md@home for MangaDex Stats
|
* Interceptor to post to md@home for MangaDex Stats
|
||||||
*/
|
*/
|
||||||
|
@ -74,21 +62,3 @@ class MdAtHomeReportInterceptor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val coverInterceptor = Interceptor { chain ->
|
|
||||||
val originalRequest = chain.request()
|
|
||||||
return@Interceptor chain.proceed(chain.request()).let { response ->
|
|
||||||
if (response.code == 404 && originalRequest.url.toString()
|
|
||||||
.contains(coverRegex)
|
|
||||||
) {
|
|
||||||
response.close()
|
|
||||||
chain.proceed(
|
|
||||||
originalRequest.newBuilder().url(
|
|
||||||
originalRequest.url.toString().substringBeforeLast(".") + ".thumb.jpg"
|
|
||||||
).build()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.all.mangadex
|
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.Response
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An OkHttp interceptor that handles rate limiting.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* permits = 5, period = 1, unit = seconds => 5 requests per second
|
|
||||||
* permits = 10, period = 2, unit = minutes => 10 requests per 2 minutes
|
|
||||||
*
|
|
||||||
* @param permits {Int} Number of requests allowed within a period of units.
|
|
||||||
* @param period {Long} The limiting duration. Defaults to 1.
|
|
||||||
* @param unit {TimeUnit} The unit of time for the period. Defaults to seconds.
|
|
||||||
*/
|
|
||||||
class RateLimitInterceptor(
|
|
||||||
private val permits: Int,
|
|
||||||
private val period: Long = 1,
|
|
||||||
private val unit: TimeUnit = TimeUnit.SECONDS
|
|
||||||
) : Interceptor {
|
|
||||||
|
|
||||||
private val requestQueue = ArrayList<Long>(permits)
|
|
||||||
private val rateLimitMillis = unit.toMillis(period)
|
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
|
||||||
synchronized(requestQueue) {
|
|
||||||
val now = SystemClock.elapsedRealtime()
|
|
||||||
val waitTime = if (requestQueue.size < permits) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
val oldestReq = requestQueue[0]
|
|
||||||
val newestReq = requestQueue[permits - 1]
|
|
||||||
|
|
||||||
if (newestReq - oldestReq > rateLimitMillis) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
oldestReq + rateLimitMillis - now // Remaining time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestQueue.size == permits) {
|
|
||||||
requestQueue.removeAt(0)
|
|
||||||
}
|
|
||||||
if (waitTime > 0) {
|
|
||||||
requestQueue.add(now + waitTime)
|
|
||||||
Thread.sleep(waitTime) // Sleep inside synchronized to pause queued requests
|
|
||||||
} else {
|
|
||||||
requestQueue.add(now)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chain.proceed(chain.request())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = 'BoyLove'
|
extName = 'BoyLove'
|
||||||
pkgNameSuffix = 'zh.boylove'
|
pkgNameSuffix = 'zh.boylove'
|
||||||
extClass = '.BoyLove'
|
extClass = '.BoyLove'
|
||||||
extVersionCode = 1
|
extVersionCode = 2
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import androidx.preference.ListPreference
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.Filter
|
import eu.kanade.tachiyomi.source.model.Filter
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
|
@ -41,7 +42,7 @@ class BoyLove : HttpSource(), ConfigurableSource {
|
||||||
.coerceIn(0, MIRRORS.size - 1).let { MIRRORS[it] }
|
.coerceIn(0, MIRRORS.size - 1).let { MIRRORS[it] }
|
||||||
|
|
||||||
override val client = network.client.newBuilder()
|
override val client = network.client.newBuilder()
|
||||||
.addInterceptor(NonblockingRateLimiter(2))
|
.rateLimit(2)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request =
|
override fun popularMangaRequest(page: Int): Request =
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.zh.boylove
|
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.Response
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
// See https://github.com/tachiyomiorg/tachiyomi/pull/7389
|
|
||||||
internal class NonblockingRateLimiter(
|
|
||||||
private val permits: Int,
|
|
||||||
period: Long = 1,
|
|
||||||
unit: TimeUnit = TimeUnit.SECONDS,
|
|
||||||
) : Interceptor {
|
|
||||||
|
|
||||||
private val requestQueue = ArrayList<Long>(permits)
|
|
||||||
private val rateLimitMillis = unit.toMillis(period)
|
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
|
||||||
// Ignore canceled calls, otherwise they would jam the queue
|
|
||||||
if (chain.call().isCanceled()) {
|
|
||||||
throw IOException()
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(requestQueue) {
|
|
||||||
val now = SystemClock.elapsedRealtime()
|
|
||||||
val waitTime = if (requestQueue.size < permits) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
val oldestReq = requestQueue[0]
|
|
||||||
val newestReq = requestQueue[permits - 1]
|
|
||||||
|
|
||||||
if (newestReq - oldestReq > rateLimitMillis) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
oldestReq + rateLimitMillis - now // Remaining time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final check
|
|
||||||
if (chain.call().isCanceled()) {
|
|
||||||
throw IOException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestQueue.size == permits) {
|
|
||||||
requestQueue.removeAt(0)
|
|
||||||
}
|
|
||||||
if (waitTime > 0) {
|
|
||||||
requestQueue.add(now + waitTime)
|
|
||||||
Thread.sleep(waitTime) // Sleep inside synchronized to pause queued requests
|
|
||||||
} else {
|
|
||||||
requestQueue.add(now)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chain.proceed(chain.request())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ ext {
|
||||||
extName = '6Manhua'
|
extName = '6Manhua'
|
||||||
pkgNameSuffix = 'zh.sixmh'
|
pkgNameSuffix = 'zh.sixmh'
|
||||||
extClass = '.SixMH'
|
extClass = '.SixMH'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
package eu.kanade.tachiyomi.extension.zh.sixmh
|
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.Response
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
// See https://github.com/tachiyomiorg/tachiyomi/pull/7389
|
|
||||||
internal class NonblockingRateLimiter(
|
|
||||||
private val permits: Int,
|
|
||||||
period: Long = 1,
|
|
||||||
unit: TimeUnit = TimeUnit.SECONDS,
|
|
||||||
) : Interceptor {
|
|
||||||
|
|
||||||
private val requestQueue = ArrayList<Long>(permits)
|
|
||||||
private val rateLimitMillis = unit.toMillis(period)
|
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
|
||||||
// Ignore canceled calls, otherwise they would jam the queue
|
|
||||||
if (chain.call().isCanceled()) {
|
|
||||||
throw IOException()
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized(requestQueue) {
|
|
||||||
val now = SystemClock.elapsedRealtime()
|
|
||||||
val waitTime = if (requestQueue.size < permits) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
val oldestReq = requestQueue[0]
|
|
||||||
val newestReq = requestQueue[permits - 1]
|
|
||||||
|
|
||||||
if (newestReq - oldestReq > rateLimitMillis) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
oldestReq + rateLimitMillis - now // Remaining time
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final check
|
|
||||||
if (chain.call().isCanceled()) {
|
|
||||||
throw IOException()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestQueue.size == permits) {
|
|
||||||
requestQueue.removeAt(0)
|
|
||||||
}
|
|
||||||
if (waitTime > 0) {
|
|
||||||
requestQueue.add(now + waitTime)
|
|
||||||
Thread.sleep(waitTime) // Sleep inside synchronized to pause queued requests
|
|
||||||
} else {
|
|
||||||
requestQueue.add(now)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chain.proceed(chain.request())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import com.github.stevenyomi.unpacker.Unpacker
|
||||||
import eu.kanade.tachiyomi.AppInfo
|
import eu.kanade.tachiyomi.AppInfo
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
@ -33,7 +34,7 @@ class SixMH : ParsedHttpSource() {
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
override val client = network.client.newBuilder()
|
override val client = network.client.newBuilder()
|
||||||
.addInterceptor(NonblockingRateLimiter(2))
|
.rateLimit(2)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int) = GET("$PC_URL/rank/1-$page.html", headers)
|
override fun popularMangaRequest(page: Int) = GET("$PC_URL/rank/1-$page.html", headers)
|
||||||
|
|
Loading…
Reference in New Issue