[MangaReader] Fix NetShield bypass

pull/368/head
Koitharu 3 years ago
parent 154ae09c6e
commit 02463e5833
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -8,6 +8,7 @@ import okhttp3.Cookie
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
import okhttp3.internal.closeQuietly
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
@ -33,6 +34,7 @@ internal abstract class MangaReaderParser(
protected open val listUrl = "/manga" protected open val listUrl = "/manga"
protected open val datePattern = "MMMM d, yyyy" protected open val datePattern = "MMMM d, yyyy"
protected open val isNetShieldProtected = false
private var tagCache: ArrayMap<String, MangaTag>? = null private var tagCache: ArrayMap<String, MangaTag>? = null
private val mutex = Mutex() private val mutex = Mutex()
@ -304,20 +306,31 @@ internal abstract class MangaReaderParser(
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 (context.cookieJar.getCookies(domain).none { it.name.contains("NetShield") }) { if (!isNetShieldProtected) {
val cookie = runBlocking { response.parseHtml().getNetShieldCookie() } ?: return response return response
}
val contentType = response.mimeType
if (
contentType?.endsWith("/html") != false &&
context.cookieJar.getCookies(domain).none { it.name.contains("NetShield") }
) {
val cookie = runBlocking { response.copy().parseHtml().getNetShieldCookie() } ?: return response
context.cookieJar.insertCookie(domain, cookie) context.cookieJar.insertCookie(domain, cookie)
return chain.proceed(response.request.newBuilder().build()) return chain.proceed(response.request.newBuilder().build()).also {
response.closeQuietly()
}
} }
return response return response
} }
private suspend fun Document.getNetShieldCookie(): Cookie? { private suspend fun Document.getNetShieldCookie(): Cookie? = runCatchingCancellable {
val script = select("script").firstNotNullOfOrNull { s -> val script = select("script").firstNotNullOfOrNull { s ->
s.html().takeIf { x -> x.contains("slowAES.decrypt") } s.html().takeIf { x -> x.contains("slowAES.decrypt") }
} ?: return null } ?: return@runCatchingCancellable null
val min = webClient.httpGet("https://$domain/min.js").parseRaw() val min = webClient.httpGet("https://$domain/min.js").parseRaw()
val res = context.evaluateJs(min + "\n\n" + script.replace("document.cookie =", "return")) val res = context.evaluateJs(min + "\n\n" + script.replace(Regex("document.cookie\\s*=\\s*"), "return "))
return Cookie.parse(baseUri().toHttpUrl(), res ?: return null) res?.let {
} Cookie.parse(baseUri().toHttpUrl(), it)
}
}.getOrNull()
} }

@ -15,6 +15,7 @@ internal class SwaTeam(context: MangaLoaderContext) :
override val datePattern = "MMMM dd, yyyy" override val datePattern = "MMMM dd, yyyy"
override val selectMangaList = ".listupd .bs .bsx" override val selectMangaList = ".listupd .bs .bsx"
override val selectMangaListImg = "img" override val selectMangaListImg = "img"
override val isNetShieldProtected = true
override suspend fun getListPage( override suspend fun getListPage(
page: Int, page: Int,

@ -13,4 +13,5 @@ internal class MangaSusuku(context: MangaLoaderContext) :
override val listUrl = "/komik" override val listUrl = "/komik"
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"
override val sourceLocale: Locale = Locale.ENGLISH override val sourceLocale: Locale = Locale.ENGLISH
override val isNetShieldProtected = true
} }

@ -9,4 +9,5 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
internal class AfroditScans(context: MangaLoaderContext) : internal class AfroditScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.AFRODITSCANS, "afroditscans.com", pageSize = 20, searchPageSize = 10) { MangaReaderParser(context, MangaSource.AFRODITSCANS, "afroditscans.com", pageSize = 20, searchPageSize = 10) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"
override val isNetShieldProtected = true
} }

@ -14,7 +14,7 @@ suspend fun Call.await(): Response = suspendCancellableCoroutine { continuation
} }
val Response.mimeType: String? val Response.mimeType: String?
get() = body?.contentType()?.run { "$type/$subtype" } get() = header("content-type")?.takeUnless { it.isEmpty() }
val Response.contentDisposition: String? val Response.contentDisposition: String?
get() = header("Content-Disposition") get() = header("Content-Disposition")
@ -27,3 +27,7 @@ fun Headers.Builder.mergeWith(other: Headers, replaceExisting: Boolean): Headers
} }
return this return this
} }
fun Response.copy() = newBuilder()
.body(peekBody(Long.MAX_VALUE))
.build()

Loading…
Cancel
Save