Handle invalid UTF-8 characters in response body (#778)
This commit is contained in:
1 parent
1eeb5a51f6
commit
4191e2091c
3 files changed
+21
-27
No files matched your search
@@ -37,7 +37,6 @@ import com.hippo.ehviewer.client.parser.ForumsParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryApiParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryListParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryListResult
|
||||
import com.hippo.ehviewer.client.parser.GalleryNotAvailableParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryPageParser
|
||||
import com.hippo.ehviewer.client.parser.GalleryTokenApiParser
|
||||
@@ -54,19 +53,15 @@ import com.hippo.ehviewer.dailycheck.today
|
||||
import com.hippo.ehviewer.util.AppConfig
|
||||
import com.hippo.ehviewer.util.ReadableTime
|
||||
import com.hippo.ehviewer.util.StatusCodeException
|
||||
import com.hippo.ehviewer.util.bodyAsUtf8Text
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import io.ktor.client.request.forms.append
|
||||
import io.ktor.client.statement.HttpStatement
|
||||
import io.ktor.client.statement.bodyAsChannel
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.utils.io.core.writeFully
|
||||
import io.ktor.utils.io.pool.DirectByteBufferPool
|
||||
import io.ktor.utils.io.pool.useInstance
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.FileChannel
|
||||
import kotlin.math.ceil
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.delay
|
||||
@@ -149,7 +144,7 @@ fun rethrowExactly(code: Int, body: Either<String, ByteBuffer>, e: Throwable): N
|
||||
val httpContentPool = DirectByteBufferPool(8, 0x80000)
|
||||
|
||||
suspend inline fun <T> HttpStatement.fetchUsingAsText(crossinline block: suspend String.() -> T) = execute { response ->
|
||||
val body = response.bodyAsText()
|
||||
val body = response.bodyAsUtf8Text()
|
||||
runSuspendCatching {
|
||||
block(body)
|
||||
}.onFailure {
|
||||
@@ -433,24 +428,6 @@ object EhEngine {
|
||||
}
|
||||
}.fetchUsingAsText(GalleryTokenApiParser::parse)
|
||||
|
||||
suspend fun imageSearch(jpeg: File, uss: Boolean, osc: Boolean): GalleryListResult {
|
||||
val location = noRedirectEhRequest(EhUrl.imageSearchUrl, EhUrl.referer, EhUrl.origin) {
|
||||
multipartBody {
|
||||
append("sfile", "a.jpg", ContentType.Image.JPEG, jpeg.length()) {
|
||||
RandomAccessFile(jpeg, "r").use {
|
||||
writeFully(it.channel.map(FileChannel.MapMode.READ_ONLY, 0, it.length()))
|
||||
}
|
||||
}
|
||||
if (uss) append("fs_similar", "on")
|
||||
if (osc) append("fs_covers", "on")
|
||||
append("f_sfile", "File Search")
|
||||
}
|
||||
}.execute { it.headers["Location"] ?: error("Failed to search image!!!") }
|
||||
return ehRequest(location).fetchUsingAsByteBuffer(GalleryListParser::parse).apply {
|
||||
galleryInfoList.fillInfo(EhUrl.imageSearchUrl)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MutableList<BaseGalleryInfo>.fillInfo(url: String, filter: Boolean = false) = with(EhFilter) {
|
||||
if (filter) removeAllSuspend { filterTitle(it) || filterUploader(it) }
|
||||
val hasTags = any { !it.simpleTags.isNullOrEmpty() }
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.hippo.ehviewer.client
|
||||
import com.hippo.ehviewer.EhApplication.Companion.ktorClient
|
||||
import com.hippo.ehviewer.EhApplication.Companion.noRedirectKtorClient
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.util.bodyAsUtf8Text
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import io.ktor.client.request.HttpRequestBuilder
|
||||
import io.ktor.client.request.forms.FormBuilder
|
||||
@@ -28,7 +29,6 @@ import io.ktor.client.request.header
|
||||
import io.ktor.client.request.prepareRequest
|
||||
import io.ktor.client.request.setBody
|
||||
import io.ktor.client.statement.HttpStatement
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
@@ -45,7 +45,7 @@ import okio.BufferedSource
|
||||
|
||||
inline fun JsonObjectBuilder.array(name: String, builder: JsonArrayBuilder.() -> Unit) = put(name, buildJsonArray(builder))
|
||||
|
||||
suspend inline fun <reified T> HttpStatement.executeAndParseAs() = execute { it.bodyAsText().parseAs<T>() }
|
||||
suspend inline fun <reified T> HttpStatement.executeAndParseAs() = execute { it.bodyAsUtf8Text().parseAs<T>() }
|
||||
inline fun <reified T> BufferedSource.parseAs(): T = json.decodeFromBufferedSource(this)
|
||||
inline fun <reified T> String.parseAs(): T = json.decodeFromString(this)
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.hippo.ehviewer.util
|
||||
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.utils.io.charsets.decode
|
||||
import io.ktor.utils.io.core.ByteReadPacket
|
||||
import java.nio.charset.CodingErrorAction
|
||||
|
||||
suspend fun HttpResponse.bodyAsUtf8Text(): String {
|
||||
val decoder = Charsets.UTF_8.newDecoder().apply {
|
||||
onMalformedInput(CodingErrorAction.REPLACE)
|
||||
onUnmappableCharacter(CodingErrorAction.REPLACE)
|
||||
}
|
||||
val input = body<ByteReadPacket>()
|
||||
|
||||
return decoder.decode(input)
|
||||
}
|
||||
Reference in new issue
Block a user