获取 Ktor http 请求的内容

Posted

技术标签:

【中文标题】获取 Ktor http 请求的内容【英文标题】:Get content of Ktor http request 【发布时间】:2019-02-15 00:27:34 【问题描述】:

如何让 Ktor 功能在路由功能之前从 ApplicationCall 上下文中获取内容? 主要目标是获取而不是消费,以便所有下一个拦截器都可以使用它。

如果我们要做这样的事情:

pipeline.intercept(ApplicationCallPipeline.Call) 
                feature.intercept(this)
                val content = call.receiveText()
                proceed()
            

或者像这样

pipeline.intercept(ApplicationCallPipeline.Call) 
            val params = this.call.receiveParameters().entries()
            proceed()
        

我们将进行下一步:

java.io.IOException: Broken delimiter occurred
at kotlinx.coroutines.experimental.io.DelimitedKt$skipDelimiterSuspend$2.doResume(Delimited.kt:57)
at kotlinx.coroutines.experimental.io.DelimitedKt$skipDelimiterSuspend$2.invoke(Delimited.kt)
at kotlinx.coroutines.experimental.io.DelimitedKt$skipDelimiterSuspend$2.invoke(Delimited.kt)
at kotlinx.coroutines.experimental.io.ByteBufferChannel.lookAheadSuspend(ByteBufferChannel.kt:1746)
at kotlinx.coroutines.experimental.io.DelimitedKt.skipDelimiterSuspend(Delimited.kt:55)
at kotlinx.coroutines.experimental.io.DelimitedKt.skipDelimiter(Delimited.kt:50)
at io.ktor.http.cio.MultipartKt.boundary(Multipart.kt:89)
at io.ktor.http.cio.MultipartKt$parseMultipart$1.doResume(Multipart.kt:158)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:42)
at kotlinx.coroutines.experimental.DispatchedKt.resumeCancellable(Dispatched.kt:209)
at kotlinx.coroutines.experimental.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:35)
at kotlinx.coroutines.experimental.CoroutineStart.invoke(CoroutineStart.kt:111)
at kotlinx.coroutines.experimental.AbstractCoroutine.start(AbstractCoroutine.kt:165)
at kotlinx.coroutines.experimental.channels.ProduceKt.produce(Produce.kt:95)
at kotlinx.coroutines.experimental.channels.ProduceKt.produce$default(Produce.kt:88)
at io.ktor.http.cio.MultipartKt.parseMultipart(Multipart.kt:145)
at io.ktor.http.cio.MultipartKt.parseMultipart(Multipart.kt:138)
at io.ktor.http.cio.CIOMultipartDataBase.<init>(CIOMultipartData.kt:33)
at io.ktor.http.cio.CIOMultipartDataBase.<init>(CIOMultipartData.kt:31)
at io.ktor.server.engine.DefaultTransformKt.multiPartData(DefaultTransform.kt:70)
at io.ktor.server.engine.DefaultTransformKt.access$multiPartData(DefaultTransform.kt:1)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$2.doResume(DefaultTransform.kt:44)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$2.invoke(DefaultTransform.kt)
at io.ktor.server.engine.DefaultTransformKt$installDefaultTransformations$2.invoke(DefaultTransform.kt)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.pipeline.Pipeline.execute(Pipeline.kt:22)
at io.ktor.request.ApplicationReceiveFunctionsKt.receive(ApplicationReceiveFunctions.kt:64)
at accreditation.controller.RequisitesRoutingKt$requisites$1$1.doResume(RequisitesRouting.kt:54)
at accreditation.controller.RequisitesRoutingKt$requisites$1$1.invoke(RequisitesRouting.kt)
at accreditation.controller.RequisitesRoutingKt$requisites$1$1.invoke(RequisitesRouting.kt)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.pipeline.Pipeline.execute(Pipeline.kt:22)
at io.ktor.routing.Routing.executeResult(Routing.kt:100)
at io.ktor.routing.Routing.interceptor(Routing.kt:25)
at io.ktor.routing.Routing$Feature$install$1.doResume(Routing.kt:66)
at io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt)
at io.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt:51)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at accreditation.utils.logging.RequestLogger$Feature$install$1.doResume(RequestLogger.kt:80)
at accreditation.utils.logging.RequestLogger$Feature$install$1.invoke(RequestLogger.kt)
at accreditation.utils.logging.RequestLogger$Feature$install$1.invoke(RequestLogger.kt:66)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.features.ContentNegotiation$Feature$install$1.doResume(ContentNegotiation.kt:60)
at io.ktor.features.ContentNegotiation$Feature$install$1.invoke(ContentNegotiation.kt)
at io.ktor.features.ContentNegotiation$Feature$install$1.invoke(ContentNegotiation.kt:50)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.features.StatusPages.intercept(StatusPages.kt:55)
at io.ktor.features.StatusPages$Feature$install$1.doResume(StatusPages.kt:84)
at io.ktor.features.StatusPages$Feature$install$1.invoke(StatusPages.kt)
at io.ktor.features.StatusPages$Feature$install$1.invoke(StatusPages.kt:78)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.features.CallLogging$Feature$install$1.doResume(CallLogging.kt:69)
at io.ktor.features.CallLogging$Feature$install$1.invoke(CallLogging.kt)
at io.ktor.features.CallLogging$Feature$install$1.invoke(CallLogging.kt:61)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.pipeline.Pipeline.execute(Pipeline.kt:22)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.doResume(DefaultEnginePipeline.kt:66)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invoke(DefaultEnginePipeline.kt)
at io.ktor.server.engine.DefaultEnginePipelineKt$defaultEnginePipeline$2.invoke(DefaultEnginePipeline.kt)
at io.ktor.pipeline.PipelineContext.proceed(PipelineContext.kt:49)
at io.ktor.pipeline.Pipeline.execute(Pipeline.kt:22)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.doResume(NettyApplicationCallHandler.kt:31)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invoke(NettyApplicationCallHandler.kt)
at io.ktor.server.netty.NettyApplicationCallHandler$handleRequest$1.invoke(NettyApplicationCallHandler.kt:10)
at kotlinx.coroutines.experimental.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:44)
at kotlinx.coroutines.experimental.CoroutineStart.invoke(CoroutineStart.kt:113)
at kotlinx.coroutines.experimental.AbstractCoroutine.start(AbstractCoroutine.kt:165)
at kotlinx.coroutines.experimental.BuildersKt__Builders_commonKt.launch(Builders.common.kt:72)
at kotlinx.coroutines.experimental.BuildersKt.launch(Unknown Source)
at kotlinx.coroutines.experimental.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:64)
at kotlinx.coroutines.experimental.BuildersKt.launch$default(Unknown Source)
at io.ktor.server.netty.NettyApplicationCallHandler.handleRequest(NettyApplicationCallHandler.kt:22)
at io.ktor.server.netty.NettyApplicationCallHandler.channelRead(NettyApplicationCallHandler.kt:16)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:38)
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:353)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)

主要思想是在路由功能处理之前记录请求内容(如果是Json或UrlEncoded),并记录每个响应内容。

【问题讨论】:

你使用的是什么版本的ktor,什么时候抛出异常? ktor_version = '0.9.3' 路由管道(例如)尝试接收请求有效负载时抛出异常(但它已经为空) 【参考方案1】:

如果请求正文被读取两次,旧版本中的 IIRC Ktor 会抛出。 目前(0.9.5),它将允许您阅读两次,但是第二次正文将是空的(已消耗)。

在此处查看文档:https://ktor.io/servers/calls/requests.html#receiving

【讨论】:

【参考方案2】:

当请求不包含任何参数时也可能发生这种情况

【讨论】:

以上是关于获取 Ktor http 请求的内容的主要内容,如果未能解决你的问题,请参考以下文章

Ktor sse 客户端断开连接

当响应时间超过 requestReadTimeoutSeconds 时,KTor 将终止 GET 请求

如何在 Ktor 中调用内部端点?

如何获取 ktor 服务的服务器 IP/端口?

如何使用 ktor 获取客户端 IP

在 Ktor 应用程序模块而不是 Main 中获取命令行参数?