project-mirai / mirai-api-http

Mirai HTTP API (console) plugin
GNU Affero General Public License v3.0
1.65k stars 345 forks source link

上传图片显示 E/MAH Access: io.ktor.http.cio.ParserException: Multiline headers via line folding is not supported since it is deprecated as per RFC7230. #671

Closed abcdefghHIM closed 11 months ago

abcdefghHIM commented 1 year ago

错误信息 2023-01-15 11:27:26 E/MAH Access: io.ktor.http.cio.ParserException: Multiline headers via line folding is not supported since it is deprecated as per RFC7230. io.ktor.http.cio.ParserException: Multiline headers via line folding is not supported since it is deprecated as per RFC7230. at mirai-api-http-2.6.2.jar//io.ktor.http.cio.HttpParserKt.parseHeaderNameFailed(HttpParser.kt:246) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.HttpParserKt.parseHeaderName(HttpParser.kt:232) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.HttpParserKt.parseHeaders(HttpParser.kt:114) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.HttpParserKt.parseHeaders$default(HttpParser.kt:93) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.MultipartKt.parsePartHeadersImpl(Multipart.kt:153) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.MultipartKt.access$parsePartHeadersImpl(Multipart.kt:1) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.MultipartKt$parseMultipart$1.invokeSuspend(Multipart.kt:362) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234) at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190) at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161) at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397) at kotlinx.coroutines.CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:513) at kotlinx.coroutines.channels.SendElement.completeResumeSend(AbstractChannel.kt:1079) at kotlinx.coroutines.channels.AbstractChannel.pollInternal(AbstractChannel.kt:546) at kotlinx.coroutines.channels.AbstractChannel.tryReceive-PtdJZtk(AbstractChannel.kt:638) at kotlinx.coroutines.channels.ReceiveChannel$DefaultImpls.poll(Channel.kt:323) at kotlinx.coroutines.channels.Channel$DefaultImpls.poll(Channel.kt:711) at kotlinx.coroutines.channels.AbstractChannel.poll(AbstractChannel.kt:515) at kotlinx.coroutines.channels.ChannelCoroutine.poll(ChannelCoroutine.kt) at mirai-api-http-2.6.2.jar//io.ktor.http.cio.CIOMultipartDataBase.readPart(CIOMultipartDataBase.kt:34) at mirai-api-http-2.6.2.jar//io.ktor.http.content.MultipartKt.readAllParts(Multipart.kt:126) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.router.MessageKt$messageRouter$1$invoke$$inlined$httpAuthedMultiPart$1$1.invokeSuspend(dsl.kt:196) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.router.MessageKt$messageRouter$1$invoke$$inlined$httpAuthedMultiPart$1$1.invoke(dsl.kt) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.router.MessageKt$messageRouter$1$invoke$$inlined$httpAuthedMultiPart$1$1.invoke(dsl.kt) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:78) at mirai-api-http-2.6.2.jar//io.ktor.routing.Routing.executeResult(Routing.kt:155) at mirai-api-http-2.6.2.jar//io.ktor.routing.Routing.interceptor(Routing.kt:39) at mirai-api-http-2.6.2.jar//io.ktor.routing.Routing$Feature$install$1.invokeSuspend(Routing.kt:107) at mirai-api-http-2.6.2.jar//io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt) at mirai-api-http-2.6.2.jar//io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.auth.Authorization$install$1.invokeSuspend(Authorization.kt:41) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.auth.Authorization$install$1.invoke(Authorization.kt) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.auth.Authorization$install$1.invoke(Authorization.kt) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.handler.HttpRouterAccessHandler.intercept(HttpRouterAccessHandler.kt:36) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.handler.HttpRouterAccessHandler.access$intercept(HttpRouterAccessHandler.kt:25) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.handler.HttpRouterAccessHandler$Feature$install$1.invokeSuspend(HttpRouterAccessHandler.kt:91) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.handler.HttpRouterAccessHandler$Feature$install$1.invoke(HttpRouterAccessHandler.kt) at mirai-api-http-2.6.2.jar//net.mamoe.mirai.api.http.adapter.http.feature.handler.HttpRouterAccessHandler$Feature$install$1.invoke(HttpRouterAccessHandler.kt) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:78) at mirai-api-http-2.6.2.jar//io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invokeSuspend(DefaultEnginePipeline.kt:127) at mirai-api-http-2.6.2.jar//io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invoke(DefaultEnginePipeline.kt) at mirai-api-http-2.6.2.jar//io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invoke(DefaultEnginePipeline.kt) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:248) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:116) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.SuspendFunctionGun.execute(SuspendFunctionGun.kt:136) at mirai-api-http-2.6.2.jar//io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:78) at mirai-api-http-2.6.2.jar//io.ktor.server.cio.CIOApplicationEngine$handleRequest$2.invokeSuspend(CIOApplicationEngine.kt:196) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Content-Type: multipart/form-data;boundary=A 提交内容: image

QQ截图20230115113606 image

尝试了在模板开头添加了Content-Type等其他操作,没有用 和网上大部分关于multiline的文章比对后没发现什么问题

MiraiConsole v2.13.0-RC2 net.mamoe.mirai-api-http v2.6.2

Guation commented 1 year ago

你这个boundary有点短 不知道是不是这个原因

abcdefghHIM commented 1 year ago

你这个boundary有点短 不知道是不是这个原因

刚刚试了增长boundary,没有效果,依然是这个错误

cssxsh commented 1 year ago

请尝试使用 https://github.com/project-mirai/mirai-api-http/releases/tag/v2.7.1

如果你是 mcl 自动更新 请将 config.json 中的 stable-v2 换成 maven-stable

ryoii commented 1 year ago

我查看了各种相关资料,确实不像是 multiline 的问题。

可是,我发现你截图的报文是有问题的。对于 file 类型的 multipart item,应该是有 Content-Type 的,但是你截图的报文中没有。所以 server 应该是按照 text 类型解析了 body 里的内容。中间大概率出现了 0x0D0x0A 触发了 multiline 的判定。

ryoii commented 1 year ago

这是我抓包获取的正常报文

image