-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added 0ms.dev images proxy support #771
- Loading branch information
Showing
17 changed files
with
249 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 0 additions & 106 deletions
106
app/src/main/kotlin/org/koitharu/kotatsu/core/network/ImageProxyInterceptor.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
...src/main/kotlin/org/koitharu/kotatsu/core/network/imageproxy/BaseImageProxyInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.koitharu.kotatsu.core.network.imageproxy | ||
|
||
import android.util.Log | ||
import androidx.collection.ArraySet | ||
import coil.intercept.Interceptor | ||
import coil.network.HttpException | ||
import coil.request.ErrorResult | ||
import coil.request.ImageRequest | ||
import coil.request.ImageResult | ||
import coil.request.SuccessResult | ||
import okhttp3.HttpUrl | ||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.Response | ||
import org.jsoup.HttpStatusException | ||
import org.koitharu.kotatsu.BuildConfig | ||
import org.koitharu.kotatsu.core.exceptions.CloudFlareBlockedException | ||
import org.koitharu.kotatsu.core.util.ext.ensureSuccess | ||
import org.koitharu.kotatsu.core.util.ext.isHttpOrHttps | ||
import org.koitharu.kotatsu.parsers.util.await | ||
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable | ||
import java.net.HttpURLConnection | ||
import java.util.Collections | ||
|
||
abstract class BaseImageProxyInterceptor : ImageProxyInterceptor { | ||
|
||
private val blacklist = Collections.synchronizedSet(ArraySet<String>()) | ||
|
||
final override suspend fun intercept(chain: Interceptor.Chain): ImageResult { | ||
val request = chain.request | ||
val url: HttpUrl? = when (val data = request.data) { | ||
is HttpUrl -> data | ||
is String -> data.toHttpUrlOrNull() | ||
else -> null | ||
} | ||
if (url == null || !url.isHttpOrHttps || url.host in blacklist) { | ||
return chain.proceed(request) | ||
} | ||
val newRequest = onInterceptImageRequest(request, url) | ||
return when (val result = chain.proceed(newRequest)) { | ||
is SuccessResult -> result | ||
is ErrorResult -> { | ||
logDebug(result.throwable, newRequest.data) | ||
chain.proceed(request).also { | ||
if (it is SuccessResult && result.throwable.isBlockedByServer()) { | ||
blacklist.add(url.host) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
final override suspend fun interceptPageRequest(request: Request, okHttp: OkHttpClient): Response { | ||
val newRequest = onInterceptPageRequest(request) | ||
return runCatchingCancellable { | ||
okHttp.doCall(newRequest) | ||
}.recover { error -> | ||
logDebug(error, newRequest.url) | ||
okHttp.doCall(request).also { | ||
if (error.isBlockedByServer()) { | ||
blacklist.add(request.url.host) | ||
} | ||
} | ||
}.getOrThrow() | ||
} | ||
|
||
protected abstract suspend fun onInterceptImageRequest(request: ImageRequest, url: HttpUrl): ImageRequest | ||
|
||
protected abstract suspend fun onInterceptPageRequest(request: Request): Request | ||
|
||
private suspend fun OkHttpClient.doCall(request: Request): Response { | ||
return newCall(request).await().ensureSuccess() | ||
} | ||
|
||
private fun logDebug(e: Throwable, url: Any) { | ||
if (BuildConfig.DEBUG) { | ||
Log.w("ImageProxy", "${e.message}: $url", e) | ||
} | ||
} | ||
|
||
private fun Throwable.isBlockedByServer(): Boolean { | ||
return this is CloudFlareBlockedException | ||
|| (this is HttpException && response.code == HttpURLConnection.HTTP_FORBIDDEN) | ||
|| (this is HttpStatusException && statusCode == HttpURLConnection.HTTP_FORBIDDEN) | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
app/src/main/kotlin/org/koitharu/kotatsu/core/network/imageproxy/ImageProxyInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.koitharu.kotatsu.core.network.imageproxy | ||
|
||
import coil.intercept.Interceptor | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.Response | ||
|
||
interface ImageProxyInterceptor : Interceptor { | ||
|
||
suspend fun interceptPageRequest(request: Request, okHttp: OkHttpClient): Response | ||
} |
42 changes: 42 additions & 0 deletions
42
...src/main/kotlin/org/koitharu/kotatsu/core/network/imageproxy/RealImageProxyInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.koitharu.kotatsu.core.network.imageproxy | ||
|
||
import coil.intercept.Interceptor | ||
import coil.request.ImageResult | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.plus | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.Response | ||
import org.koitharu.kotatsu.core.prefs.AppSettings | ||
import org.koitharu.kotatsu.core.prefs.observeAsStateFlow | ||
import org.koitharu.kotatsu.core.util.ext.processLifecycleScope | ||
import org.koitharu.kotatsu.parsers.util.await | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Singleton | ||
class RealImageProxyInterceptor @Inject constructor( | ||
private val settings: AppSettings, | ||
) : ImageProxyInterceptor { | ||
|
||
private val delegate = settings.observeAsStateFlow( | ||
scope = processLifecycleScope + Dispatchers.Default, | ||
key = AppSettings.KEY_IMAGES_PROXY, | ||
valueProducer = { createDelegate() }, | ||
) | ||
|
||
override suspend fun intercept(chain: Interceptor.Chain): ImageResult { | ||
return delegate.value?.intercept(chain) ?: chain.proceed(chain.request) | ||
} | ||
|
||
override suspend fun interceptPageRequest(request: Request, okHttp: OkHttpClient): Response { | ||
return delegate.value?.interceptPageRequest(request, okHttp) ?: okHttp.newCall(request).await() | ||
} | ||
|
||
private fun createDelegate(): ImageProxyInterceptor? = when (val proxy = settings.imagesProxy) { | ||
-1 -> null | ||
0 -> WsrvNlProxyInterceptor() | ||
1 -> ZeroMsProxyInterceptor() | ||
else -> error("Unsupported images proxy $proxy") | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
app/src/main/kotlin/org/koitharu/kotatsu/core/network/imageproxy/WsrvNlProxyInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.koitharu.kotatsu.core.network.imageproxy | ||
|
||
import coil.request.ImageRequest | ||
import coil.size.Dimension | ||
import coil.size.isOriginal | ||
import okhttp3.HttpUrl | ||
import okhttp3.Request | ||
|
||
class WsrvNlProxyInterceptor : BaseImageProxyInterceptor() { | ||
|
||
override suspend fun onInterceptImageRequest(request: ImageRequest, url: HttpUrl): ImageRequest { | ||
val newUrl = HttpUrl.Builder() | ||
.scheme("https") | ||
.host("wsrv.nl") | ||
.addQueryParameter("url", url.toString()) | ||
.addQueryParameter("we", null) | ||
val size = request.sizeResolver.size() | ||
if (!size.isOriginal) { | ||
newUrl.addQueryParameter("crop", "cover") | ||
(size.height as? Dimension.Pixels)?.let { newUrl.addQueryParameter("h", it.toString()) } | ||
(size.width as? Dimension.Pixels)?.let { newUrl.addQueryParameter("w", it.toString()) } | ||
} | ||
|
||
return request.newBuilder() | ||
.data(newUrl.build()) | ||
.build() | ||
} | ||
|
||
override suspend fun onInterceptPageRequest(request: Request): Request { | ||
val sourceUrl = request.url | ||
val targetUrl = HttpUrl.Builder() | ||
.scheme("https") | ||
.host("wsrv.nl") | ||
.addQueryParameter("url", sourceUrl.toString()) | ||
.addQueryParameter("we", null) | ||
return request.newBuilder() | ||
.url(targetUrl.build()) | ||
.build() | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
app/src/main/kotlin/org/koitharu/kotatsu/core/network/imageproxy/ZeroMsProxyInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.koitharu.kotatsu.core.network.imageproxy | ||
|
||
import coil.request.ImageRequest | ||
import okhttp3.HttpUrl | ||
import okhttp3.HttpUrl.Companion.toHttpUrl | ||
import okhttp3.Request | ||
|
||
class ZeroMsProxyInterceptor : BaseImageProxyInterceptor() { | ||
|
||
override suspend fun onInterceptImageRequest(request: ImageRequest, url: HttpUrl): ImageRequest { | ||
if (url.host == "x.0ms.dev" || url.host == "0ms.dev") { | ||
return request | ||
} | ||
val newUrl = ("https://x.0ms.dev/q70/$url").toHttpUrl() | ||
return request.newBuilder() | ||
.data(newUrl) | ||
.build() | ||
} | ||
|
||
override suspend fun onInterceptPageRequest(request: Request): Request { | ||
val newUrl = ("https://x.0ms.dev/q70/${request.url}").toHttpUrl() | ||
return request.newBuilder() | ||
.url(newUrl) | ||
.build() | ||
} | ||
} |
Oops, something went wrong.