diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt index fd58032c..af6f048f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt @@ -304,7 +304,7 @@ internal class ExHentaiParser( override fun intercept(chain: Interceptor.Chain): Response { val response = chain.proceed(chain.request()) if (response.headersContentLength() <= 256) { - val text = response.peekBody(256).string() + val text = response.peekBody(256).use { it.string() } if (text.contains("IP address has been temporarily banned", ignoreCase = true)) { val hours = Regex("([0-9]+) hours?").find(text)?.groupValues?.getOrNull(1)?.toLongOrNull() ?: 0 val minutes = Regex("([0-9]+) minutes?").find(text)?.groupValues?.getOrNull(1)?.toLongOrNull() ?: 0 diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt index 032978bb..4fc22136 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt @@ -456,7 +456,7 @@ internal abstract class MangaFireParser( } } - return@redrawImageResponse result + result } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaMana.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaMana.kt index 9269b1c7..967ab452 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaMana.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaMana.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.parsers.site.fr import kotlinx.coroutines.* import okhttp3.Headers -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import org.json.JSONArray import org.jsoup.Jsoup import org.jsoup.nodes.Document @@ -166,11 +165,11 @@ internal class MangaMana(context: MangaLoaderContext) : } } - val url = "https://$domain/liste-mangas" + val url = "https://$domain/liste-mangas".toHttpUrl() val token = webClient.httpGet(url).parseHtml().selectFirstOrThrow("meta[name=csrf-token]").attr("content") val headers = Headers.Builder().add("X-CSRF-TOKEN", token).add("X-Requested-With", "XMLHttpRequest") .add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build() - val doc = makeRequest(url, postData.toRequestBody(), headers) + val doc = makeRequest(url, postData, headers) return doc.select("div.p-2 div.col").map { div -> val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") @@ -206,13 +205,12 @@ internal class MangaMana(context: MangaLoaderContext) : } - private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document { + private suspend fun makeRequest(url: HttpUrl, payload: String, headers: Headers): Document { var retryCount = 0 val backoffDelay = 2000L // Initial delay (milliseconds) - val request = Request.Builder().url(url).post(payload).headers(headers).build() while (true) { try { - return Jsoup.parse(context.httpClient.newCall(request).execute().parseJson().getString("html")) + return Jsoup.parse(webClient.httpPost(url, payload, headers).parseJson().getString("html")) } catch (e: Exception) { // Log or handle the exception as needed diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt index 330073e2..b8274057 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.parsers.site.madara.en import kotlinx.coroutines.* import okhttp3.Headers -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import org.json.JSONObject import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext @@ -126,10 +125,10 @@ internal class AdultWebtoon(context: MangaLoaderContext) : override suspend fun loadChapters(mangaUrl: String, document: Document): List { val mangaId = document.select("div#manga-chapters-holder").attr("data-id") - val url = "https://$domain/wp-admin/admin-ajax.php" + val url = "https://$domain/wp-admin/admin-ajax.php".toHttpUrl() val postData = "post_id=$mangaId&action=ajax_chap" val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build() - val doc = makeRequest(url, postData.toRequestBody(), headers) + val doc = makeRequest(url, postData, headers) val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.select(selectChapter).mapChapters(reversed = true) { i, li -> val a = li.selectFirst("a") @@ -216,14 +215,12 @@ internal class AdultWebtoon(context: MangaLoaderContext) : return chunked(2).map { it.toInt(16).toByte() }.toByteArray() } - private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document { + private suspend fun makeRequest(url: HttpUrl, payload: String, headers: Headers): Document { var retryCount = 0 val backoffDelay = 2000L // Initial delay (milliseconds) - val request = Request.Builder().url(url).post(payload).headers(headers).build() while (true) { try { - return context.httpClient.newCall(request).execute().parseHtml() - + return webClient.httpPost(url, payload, headers).parseHtml() } catch (e: Exception) { // Log or handle the exception as needed if (++retryCount <= 5) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiManga.kt index a3fe0c8a..af280301 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiManga.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.parsers.site.madara.en import kotlinx.coroutines.* import okhttp3.Headers -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser @@ -120,10 +119,10 @@ internal class HentaiManga(context: MangaLoaderContext) : override suspend fun loadChapters(mangaUrl: String, document: Document): List { val mangaId = document.select("div#manga-chapters-holder").attr("data-id") - val url = "https://$domain/wp-admin/admin-ajax.php" + val url = "https://$domain/wp-admin/admin-ajax.php".toHttpUrl() val postData = "post_id=$mangaId&action=ajax_chap" val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build() - val doc = makeRequest(url, postData.toRequestBody(), headers) + val doc = makeRequest(url, postData, headers) val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.select(selectChapter).mapChapters(reversed = true) { i, li -> val a = li.selectFirst("a") @@ -148,14 +147,12 @@ internal class HentaiManga(context: MangaLoaderContext) : } } - private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document { + private suspend fun makeRequest(url: HttpUrl, payload: String, headers: Headers): Document { var retryCount = 0 val backoffDelay = 2000L // Initial delay (milliseconds) - val request = Request.Builder().url(url).post(payload).headers(headers).build() while (true) { try { - return context.httpClient.newCall(request).execute().parseHtml() - + return webClient.httpPost(url, payload, headers).parseHtml() } catch (e: Exception) { // Log or handle the exception as needed if (++retryCount <= 5) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiWebtoon.kt index f348c19f..72b042bd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HentaiWebtoon.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.parsers.site.madara.en import kotlinx.coroutines.* import okhttp3.Headers -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser @@ -120,10 +119,10 @@ internal class HentaiWebtoon(context: MangaLoaderContext) : override suspend fun loadChapters(mangaUrl: String, document: Document): List { val mangaId = document.select("div#manga-chapters-holder").attr("data-id") - val url = "https://$domain/wp-admin/admin-ajax.php" + val url = "https://$domain/wp-admin/admin-ajax.php".toHttpUrl() val postData = "post_id=$mangaId&action=ajax_chap" val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build() - val doc = makeRequest(url, postData.toRequestBody(), headers) + val doc = makeRequest(url, postData, headers) val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.select(selectChapter).mapChapters(reversed = true) { i, li -> val a = li.selectFirst("a") @@ -148,14 +147,12 @@ internal class HentaiWebtoon(context: MangaLoaderContext) : } } - private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document { + private suspend fun makeRequest(url: HttpUrl, payload: String, headers: Headers): Document { var retryCount = 0 val backoffDelay = 2000L // Initial delay (milliseconds) - val request = Request.Builder().url(url).post(payload).headers(headers).build() while (true) { try { - return context.httpClient.newCall(request).execute().parseHtml() - + return webClient.httpPost(url, payload, headers).parseHtml() } catch (e: Exception) { // Log or handle the exception as needed if (++retryCount <= 5) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManyToon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManyToon.kt index 3e9eb60c..fd337b67 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManyToon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManyToon.kt @@ -2,9 +2,8 @@ package org.koitharu.kotatsu.parsers.site.madara.en import kotlinx.coroutines.* import okhttp3.Headers -import okhttp3.Request -import okhttp3.RequestBody -import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrl import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser @@ -123,10 +122,10 @@ internal class ManyToon(context: MangaLoaderContext) : override suspend fun loadChapters(mangaUrl: String, document: Document): List { val mangaId = document.select("div#manga-chapters-holder").attr("data-id") - val url = "https://$domain/wp-admin/admin-ajax.php" + val url = "https://$domain/wp-admin/admin-ajax.php".toHttpUrl() val postData = "post_id=$mangaId&action=ajax_chap" val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build() - val doc = makeRequest(url, postData.toRequestBody(), headers) + val doc = makeRequest(url, postData, headers) val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.select(selectChapter).mapChapters(reversed = true) { i, li -> val a = li.selectFirst("a") @@ -151,14 +150,12 @@ internal class ManyToon(context: MangaLoaderContext) : } } - private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document { + private suspend fun makeRequest(url: HttpUrl, payload: String, headers: Headers): Document { var retryCount = 0 val backoffDelay = 2000L // Initial delay (milliseconds) - val request = Request.Builder().url(url).post(payload).headers(headers).build() while (true) { try { - return context.httpClient.newCall(request).execute().parseHtml() - + webClient.httpPost(url, payload, headers).parseHtml() } catch (e: Exception) { // Log or handle the exception as needed if (++retryCount <= 5) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt index 51d92c2f..f969878c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt @@ -209,6 +209,5 @@ internal abstract class MangAdventureParser( private val Manga.slug: String get() = url.substring(8, url.length - 1) - protected suspend fun HttpUrl.Builder.get() = - webClient.httpGet(build()).body?.string()?.let(::JSONObject) + protected suspend fun HttpUrl.Builder.get() = webClient.httpGet(build()).parseJson() } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt index 1d670d40..7f91163e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt @@ -2,8 +2,6 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en import androidx.collection.ArrayMap import kotlinx.coroutines.sync.withLock -import okhttp3.FormBody -import okhttp3.Request import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.* @@ -43,13 +41,8 @@ internal class RizzComic(context: MangaLoaderContext) : private val slugRegex = Regex("""[^a-z0-9]+""") private val searchMangaSelector = ".utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx" private suspend fun getRandomPart(): String { - val request = Request.Builder() - .url("https://$domain$listUrl") - .get() - .build() - - val response = context.httpClient.newCall(request).await() - val url = response.parseHtml() + val response = webClient.httpGet("https://$domain$listUrl").parseHtml() + val url = response .selectFirst(searchMangaSelector)!! .select("a").attr("href") @@ -74,9 +67,7 @@ internal class RizzComic(context: MangaLoaderContext) : !filter.query.isNullOrEmpty() -> { url = "https://$domain$searchUrl" if (filter.query != "") { - FormBody.Builder() - .add("search_value", filter.query.trim()) - .build() + mapOf("search_value" to filter.query.trim()) } else { null } @@ -87,28 +78,22 @@ internal class RizzComic(context: MangaLoaderContext) : val genres = filter.tags.map { it.key } - val formBuilder = FormBody.Builder() - .add("StatusValue", state) - .add("TypeValue", "all") - .add("OrderValue", order.toPayloadValue()) + val form = ArrayMap() + form["StatusValue"] = state + form["TypeValue"] = "all" + form["OrderValue"] = order.toPayloadValue() genres.forEach { genre -> - formBuilder.add("genres_checked[]", genre) + form["genres_checked[]"] = genre } - formBuilder.build() + form } } - val request = Request.Builder() - .url(url) - .apply { - if (payload != null) { - post(payload) - } else { - get() - } - } - .build() - val response = context.httpClient.newCall(request).execute().parseJsonArray() + val response = if (payload != null) { + webClient.httpPost(url, payload) + } else { + webClient.httpGet(url) + }.parseJsonArray() return response.mapJSON { j -> val title = j.getString("title") val urlManga = "https://$domain$listUrl/${randomPartCache.get()}-" + title.trim().lowercase() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/DuaLeoTruyen.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/DuaLeoTruyen.kt index bad6da28..9b0077d2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/DuaLeoTruyen.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/DuaLeoTruyen.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.parsers.site.vi +import okhttp3.internal.closeQuietly import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey @@ -140,7 +141,7 @@ internal class DuaLeoTruyen(context: MangaLoaderContext) : "truyen" to comicsId, "chap" to chapterId, ), - ) + ).closeQuietly() } return doc.select(".content_view_chap img").mapIndexed { i, img ->