From 7fb93eef2c29db132d55a883d74c3d5a3e1c90eb Mon Sep 17 00:00:00 2001 From: yyuueexxiinngg Date: Sun, 9 Aug 2020 13:45:36 +0800 Subject: [PATCH] Fix http server encoding error when receiving json post text. Closes #25 --- build.gradle.kts | 2 +- .../mihoyo/mirai/web/http/HttpApiModule.kt | 22 +++++++++++++++++-- .../mihoyo/mirai/web/http/HttpApiServer.kt | 1 - 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9dce94c..3ebf59d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -56,6 +56,7 @@ tasks { val runMiraiConsole by creating(JavaExec::class.java) { group = "mirai" + main = "mirai.RunMirai" dependsOn(shadowJar) dependsOn(testClasses) @@ -91,7 +92,6 @@ tasks { copyBuildOutput() classpath = sourceSets["test"].runtimeClasspath - main = "mirai.RunMirai" standardInput = System.`in` args(miraiCoreVersion, miraiConsoleVersion) } diff --git a/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiModule.kt b/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiModule.kt index 6ebaba6..64eff40 100644 --- a/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiModule.kt +++ b/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiModule.kt @@ -28,6 +28,7 @@ import tech.mihoyo.mirai.callMiraiApi import tech.mihoyo.mirai.data.common.CQResponseDTO import tech.mihoyo.mirai.util.logger import tech.mihoyo.mirai.util.toJson +import java.nio.charset.Charset import kotlin.coroutines.EmptyCoroutineContext @ExperimentalCoroutinesApi @@ -252,7 +253,7 @@ internal inline fun Route.cqHttpApi( } post { if (checkAccessToken(call, serviceConfig)) { - body(Pair(Json.parseJson(call.receiveText()).jsonObject, false)) + body(Pair(Json.parseJson(call.receiveTextWithCorrectEncoding()).jsonObject, false)) } } } @@ -269,7 +270,7 @@ internal inline fun Route.cqHttpApi( } post { if (checkAccessToken(call, serviceConfig)) { - val req = call.receiveText() + val req = call.receiveTextWithCorrectEncoding() call.responseDTO(CQResponseDTO.CQAsyncStarted()) CoroutineScope(EmptyCoroutineContext).launch { body(Pair(Json.parseJson(req).jsonObject, true)) @@ -278,3 +279,20 @@ internal inline fun Route.cqHttpApi( } } } + +// https://github.com/ktorio/ktor/issues/384#issuecomment-458542686 +/** + * Receive the request as String. + * If there is no Content-Type in the HTTP header specified use ISO_8859_1 as default charset, see https://www.w3.org/International/articles/http-charset/index#charset. + * But use UTF-8 as default charset for application/json, see https://tools.ietf.org/html/rfc4627#section-3 + */ +private suspend fun ApplicationCall.receiveTextWithCorrectEncoding(): String { + fun ContentType.defaultCharset(): Charset = when (this) { + ContentType.Application.Json -> Charsets.UTF_8 + else -> Charsets.ISO_8859_1 + } + + val contentType = request.contentType() + val suitableCharset = contentType.charset() ?: contentType.defaultCharset() + return receiveStream().bufferedReader(charset = suitableCharset).readText() +} \ No newline at end of file diff --git a/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiServer.kt b/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiServer.kt index ba9149c..554ebb8 100644 --- a/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiServer.kt +++ b/src/main/kotlin/tech/mihoyo/mirai/web/http/HttpApiServer.kt @@ -41,5 +41,4 @@ class HttpApiServer( fun close() { server.stop(5000, 5000) } - } \ No newline at end of file