如何在 Ktor 中获取 call.reponse 的 http body?

How to get http body of call.reponse in Ktor?

我用 Ktor 构建了一个网络服务器,想缓存 API 方法的结果。但是我不知道如何从 call.response 获取响应主体。代码如下

fun Application.module(){

    // before method was called
    intercept(ApplicationCallPipeline.Features) {
        val cache = redis.get("cache")
        if(cache) {
            call.respond(cache)
        }

        return @intercept finish()
    }
    
    // after method was called
    intercept(ApplicationCallPipeline.Fallback) {
        // TODO, how to get call.response.body
        redis.set("cache", call.response.body)
    }
}

如果我无法获取响应主体,还有其他解决方案可以在 Ktor 中缓存 API 方法的结果吗?

在拦截器中,对于 ApplicationCallPipeline.Features 阶段,您可以在 ApplicationSendPipeline.Engine 之前添加一个阶段并拦截它以检索响应主体 (content):

val phase = PipelinePhase("phase")
call.response.pipeline.insertPhaseBefore(ApplicationSendPipeline.Engine, phase)
call.response.pipeline.intercept(phase) { response ->
    val content: ByteReadChannel = when (response) {
        is OutgoingContent.ByteArrayContent -> ByteReadChannel(response.bytes())
        is OutgoingContent.NoContent -> ByteReadChannel.Empty
        is OutgoingContent.ReadChannelContent -> response.readFrom()
        is OutgoingContent.WriteChannelContent -> GlobalScope.writer(coroutineContext, autoFlush = true) {
            response.writeTo(channel)
        }.channel
        else -> error("")
    }

    // Do something with content
}