https://kotlinlang.org logo
#ktor
Title
# ktor
j

Jamie Craane

01/05/2020, 8:23 PM
I am looking into Ktor interceptors (from a Ktor server perspective) to modify the original response before it is send to the client. A quick example of what I want to achieve: suppose I have a route which returns some response, for example:
Copy code
route {
    get("sample") {
        call.respondText("Hello {Name}")
    }
}
And I want to use a global interceptor to replace the {Name} variable in the response with some other value. How do I access the contents of the response in an interceptor? (I know how I can send a custom response but not yet how I can access the original response, and modify it)
I have worked out a potential solution by writing a custom feature (inspired by the Compression feature). A simple example of the code is shown below:
Copy code
class TokenReplaceFeature : ApplicationFeature<ApplicationCallPipeline, Compression.Configuration, TokenReplacer> {
    override val key = AttributeKey<TokenReplacer>("replacer")

    override fun install(pipeline: ApplicationCallPipeline, configure: Compression.Configuration.() -> Unit): TokenReplacer {
        val feature = TokenReplacer()
        pipeline.sendPipeline.intercept(ApplicationSendPipeline.ContentEncoding) {
            feature.interceptor(this)
        }
        return feature
    }
}

class TokenReplacer {
    suspend fun interceptor(context: PipelineContext<Any, ApplicationCall>) {
        val call = context.call
        val message = context.subject
        if (message is TextContent) {
            val replaced = message.text.replace("{HOST_IP}", "10.0.0.2")
            context.proceedWith(TextContent(replaced, message.contentType, call.response.status()))
        }
    }
}
You can then simply install this feature with:
Copy code
install(TokenReplaceFeature())
50 Views