sagarkothari
sagarkothari

Reputation: 24820

Kotlin ktor jetty modify response headers

This is what I've tried so far.

embeddedServer(Jetty, 9000) {
    install(ContentNegotiation) {
        gson {}
    }
    routing {
        post("/account/login") {
            // 1. Create URL
            val url = URL("http://some.server.com/account/login")
            // 2. Create HTTP URL Connection
            var connection: HttpURLConnection = url.openConnection() as HttpURLConnection
            // 3. Add Request Headers
            connection.addRequestProperty("Host", "some.server.com")
            connection.addRequestProperty("Content-Type", "application/json;charset=utf-8")
            // 4. Set Request method
            connection.requestMethod = "POST"
            // 5. Set Request Body
            val requestBodyText = call.receiveText()
            val outputInBytes: ByteArray = requestBodyText.toByteArray(Charsets.UTF_8)
            val os: OutputStream = connection.getOutputStream()
            os.write(outputInBytes)
            os.close()
            // 6. Get Response as string from HTTP URL Connection
            val string = connection.getInputStream().reader().readText()
            // 7. Get headers from HTTP URL Connection
            val headerFields =  connection.headerFields
            // 8. Get Cookies Out of response
            val cookiesHeader = headerFields["Set-Cookie"]?.joinToString { "${it};" } ?: ""
            // 9. Respond to Client with JSON Data
            call.respondText(string, ContentType.Text.JavaScript, HttpStatusCode.OK)
            // 10. Add Response headers
            call.response.header("Set-Cookie", cookiesHeader)
        }
    }
}.start(wait = false)

If step 9 is executed first, step 10- doesn't set the headers to response. If step 10 is executed first, step-9 response body isn't set.

How do I send both together - response body & response headers?

Upvotes: 1

Views: 1714

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49525

I only have a half answer, sorry.

Seems like the call.respondText(...., HttpStatusCode.OK) will commit the response (as it has the status code "OK" declared as a parameter).

A committed response would prevent you from modifying the response headers.

The call.response.header("Set-Cookie", ...) should just set a header and do nothing else.

From a general HTTP server point of view, you want to set response status code first, then response headers, then produce response body content, then (optionally) produce response trailers.

Upvotes: 2

Related Questions