Search code examples
androidkotlinktorktor-client

Sanitise/Remove emojis from all requests type before requesting to server


I need to remove emojies from the request body (json type) before sending it to the server, like we can sanitise headers while using Logger. so far I know we can intercept the request like this

      HttpClient {
        ......
        .....
      }.plugin(HttpSend).intercept { request ->
        val originalCall = execute(request)
        val contentType = originalCall.request.content.contentType
        val isJson: Boolean = contentType == ContentType("application", "json")
        if (isJson) {
          //how to find and remove emojis from the body
          //then execute(sanitised request)
        } else {
          originalCall
        }

is there a better way to do this please share thanks


Solution

  • To sanitize the request body you can determine the type of the HttpRequestBuilder.body property and create a new request body with the sanitized content. Here is an example:

    import io.ktor.client.*
    import io.ktor.client.engine.cio.*
    import io.ktor.client.plugins.api.*
    import io.ktor.client.plugins.contentnegotiation.*
    import io.ktor.client.request.*
    import io.ktor.client.statement.*
    import io.ktor.content.*
    import io.ktor.http.*
    import io.ktor.serialization.kotlinx.json.*
    import io.ktor.util.*
    import kotlinx.serialization.Serializable
    
    @OptIn(InternalAPI::class)
    val plugin = createClientPlugin("no-emojis") {
        on(Send) {
            val newBody = when (val body = it.body) {
                is TextContent -> {
                    val text = body.text.replace("x", "value") // An example of sanitizing
                    TextContent(text, body.contentType, body.status)
                }
    
                else -> error("I don't know how to sanitize $body")
            }
            it.body = newBody
            proceed(it)
        }
    }
    
    @Serializable
    data class Some(val x: Int)
    
    suspend fun main() {
        val client = HttpClient(CIO) {
            install(ContentNegotiation) {
                json()
            }
            install(plugin)
        }
        val r = client.post("https://httpbin.org/post") {
            setBody(Some(123))
            contentType(ContentType.Application.Json)
        }
        println(r.bodyAsText())
    }