diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 525947053..113812f8b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -108,7 +108,11 @@ "Bash(node -e ' *)", "Bash(node *)", "Bash(Select-String -Pattern \"BUILD|error|Error\")", - "Bash(Select-Object -First 10)" + "Bash(Select-Object -First 10)", + "Bash(git push *)", + "Bash(gh run *)", + "WebFetch(domain:ktor.io)", + "WebFetch(domain:api.ktor.io)" ] } } diff --git a/app/src/main/java/io/legado/app/web/KtorServer.kt b/app/src/main/java/io/legado/app/web/KtorServer.kt index c6081d0b0..4ae2cc133 100644 --- a/app/src/main/java/io/legado/app/web/KtorServer.kt +++ b/app/src/main/java/io/legado/app/web/KtorServer.kt @@ -13,8 +13,7 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.websocket.* -import io.ktor.util.pipeline.* -import io.ktor.util.toMap +import io.ktor.utils.io.readAvailable import io.legado.app.api.ReturnData import io.legado.app.api.controller.BookController import io.legado.app.api.controller.BookSourceController @@ -35,8 +34,8 @@ import java.io.ByteArrayOutputStream import java.io.File class KtorServer(private val port: Int) { - private var server: ApplicationEngine? = null - private var wsServer: ApplicationEngine? = null + private var server: EmbeddedServer<*, *>? = null + private var wsServer: EmbeddedServer<*, *>? = null private val assetsWeb = AssetsWeb("web") fun start() { @@ -73,9 +72,13 @@ class KtorServer(private val port: Int) { if (part.name == "fileName") fileName = part.value } is PartData.FileItem -> { - part.streamProvider().use { input -> - tempFile.outputStream().use { output -> - input.copyTo(output) + val channel = part.provider() + tempFile.outputStream().use { output -> + val buffer = ByteArray(8192) + while (true) { + val bytesRead = channel.readAvailable(buffer) + if (bytesRead == -1) break + output.write(buffer, 0, bytesRead) } } if (fileName == null) { @@ -169,7 +172,7 @@ class KtorServer(private val port: Int) { wsServer?.stop(0, 0) } - private suspend fun PipelineContext.handlePost( + private suspend fun RoutingContext.handlePost( block: suspend (String?) -> ReturnData ) { WebService.serve() @@ -183,12 +186,13 @@ class KtorServer(private val port: Int) { } } - private suspend fun PipelineContext.handleGet( + private suspend fun RoutingContext.handleGet( block: (Map>) -> ReturnData? ) { WebService.serve() try { - val parameters = call.request.queryParameters.toMap() + val parameters = call.queryParameters.entries() + .associate { it.key to it.value } val returnData = block(parameters) if (returnData != null) { respondReturnData(returnData) @@ -201,7 +205,7 @@ class KtorServer(private val port: Int) { } } - private suspend fun PipelineContext.respondReturnData(returnData: ReturnData) { + private suspend fun RoutingContext.respondReturnData(returnData: ReturnData) { if (returnData.data is Bitmap) { val bitmap = returnData.data as Bitmap val outputStream = ByteArrayOutputStream() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 32a306478..9ea8e6460 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,7 +37,7 @@ lifecycle = "2.10.0" glide = "5.0.7" gson = "2.14.0" jsonPath = "3.0.0" -ktor = "2.3.12" +ktor = "3.5.0" # issue #3811,不要更新版本,新版引入了一个破坏性变更(详见https://github.com/jhy/jsoup/pull/2017) # 若要升级请确保相关代码不会受此变更影响(如AnalyzeByJSoup.kt、JsoupXpath库等) jsoup = "1.16.2"