mirror of
https://github.com/CCBlueX/LiquidBounce.git
synced 2025-09-06 17:50:42 +00:00
fix: IllegalStateException(closed) from reading HTTP response (#5989)
* fix: incorrect closing If we take InputStream or BufferedSource, it will be returned after closing... * exception log
This commit is contained in:
@@ -31,6 +31,7 @@ import okio.buffer
|
||||
import okio.sink
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.io.Reader
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
@@ -99,21 +100,47 @@ enum class HttpMethod {
|
||||
GET, POST, PUT, DELETE, PATCH
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse body from [Response].
|
||||
*
|
||||
* If [T] is one of following types, it should be closed after using:
|
||||
* [InputStream] / [BufferedSource] / [Reader]
|
||||
*/
|
||||
inline fun <reified T> Response.parse(): T {
|
||||
return use {
|
||||
when (T::class.java) {
|
||||
String::class.java -> body.string() as T
|
||||
Unit::class.java -> Unit as T
|
||||
InputStream::class.java -> body.byteStream() as T
|
||||
BufferedSource::class.java -> body.source() as T
|
||||
NativeImageBackedTexture::class.java -> body.byteStream().use { stream ->
|
||||
NativeImageBackedTexture(NativeImage.read(stream)) as T
|
||||
}
|
||||
else -> decode<T>(body.charStream())
|
||||
return when (T::class.java) {
|
||||
String::class.java -> body.string()
|
||||
Unit::class.java -> close()
|
||||
InputStream::class.java -> body.byteStream()
|
||||
BufferedSource::class.java -> body.source()
|
||||
Reader::class.java -> body.charStream()
|
||||
NativeImageBackedTexture::class.java -> body.byteStream().use { stream ->
|
||||
NativeImageBackedTexture(NativeImage.read(stream))
|
||||
}
|
||||
}
|
||||
else -> decode(body.charStream())
|
||||
} as T
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all UTF-8 lines from [BufferedSource] as an [Iterator].
|
||||
*
|
||||
* When there are no more lines to read, the source is closed automatically.
|
||||
*/
|
||||
fun BufferedSource.utf8Lines(): Iterator<String> =
|
||||
object : AbstractIterator<String>() {
|
||||
override fun computeNext() {
|
||||
val nextLine = readUtf8Line()
|
||||
if (nextLine != null) {
|
||||
setNext(nextLine)
|
||||
} else {
|
||||
close()
|
||||
done()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save response body to file.
|
||||
*/
|
||||
fun Response.toFile(file: File) = use { response ->
|
||||
file.sink().buffer().use(response.body.source()::readAll)
|
||||
}
|
||||
|
@@ -22,12 +22,12 @@ package net.ccbluex.liquidbounce.api.services.cdn
|
||||
|
||||
import net.ccbluex.liquidbounce.api.core.BaseApi
|
||||
import net.ccbluex.liquidbounce.api.core.CLIENT_CDN
|
||||
import net.ccbluex.liquidbounce.api.core.utf8Lines
|
||||
import net.ccbluex.liquidbounce.api.models.cdn.IpcConfiguration
|
||||
import okio.BufferedSource
|
||||
|
||||
object ClientCdn : BaseApi(CLIENT_CDN) {
|
||||
suspend fun requestDiscordConfiguration() = get<IpcConfiguration>("/discord.json")
|
||||
suspend fun requestStaffList(address: String): Set<String> = get<BufferedSource>("/staffs/$address").use {
|
||||
generateSequence { it.readUtf8Line() }.toHashSet()
|
||||
}
|
||||
suspend fun requestStaffList(address: String): Set<String> =
|
||||
get<BufferedSource>("/staffs/$address").utf8Lines().asSequence().toHashSet()
|
||||
}
|
||||
|
@@ -72,7 +72,7 @@ object ModuleAntiStaff : ClientModule("AntiStaff", Category.MISC) {
|
||||
if (serverStaffList.containsKey(address)) {
|
||||
return
|
||||
}
|
||||
serverStaffList[address] = emptySet<String>()
|
||||
serverStaffList[address] = emptySet()
|
||||
|
||||
withScope {
|
||||
loadStaffList(address)
|
||||
@@ -87,7 +87,7 @@ object ModuleAntiStaff : ClientModule("AntiStaff", Category.MISC) {
|
||||
if (serverStaffList.containsKey(address)) {
|
||||
return@sequenceHandler
|
||||
}
|
||||
serverStaffList[address] = emptySet<String>()
|
||||
serverStaffList[address] = emptySet()
|
||||
|
||||
// Keeps us from loading the staff list multiple times
|
||||
waitUntil { inGame && mc.currentScreen != null }
|
||||
@@ -131,6 +131,7 @@ object ModuleAntiStaff : ClientModule("AntiStaff", Category.MISC) {
|
||||
NotificationEvent.Severity.ERROR)
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
logger.error("Failed to load staff list of $address", exception)
|
||||
notification("AntiStaff", message("staffsFailed", address, exception.javaClass.simpleName),
|
||||
NotificationEvent.Severity.ERROR)
|
||||
}
|
||||
|
Reference in New Issue
Block a user