I'd like to understand how `ContentNegotiation` wo...
# ktor
t
I'd like to understand how
ContentNegotiation
works so I can understand if the behaviour I am running into is a bug, or, expected. The situation is that using Ktor Client I want to send a POST request of type
application/json
with an
Accept image/jpeg
header. The behaviour I am seeing is that using the
headers {}
function to set the Accept header of type image results in the Accept type being
application/json
. I am using kotlinx serialization as my serialization plugin. Given this client, for example:
Copy code
HttpClient(Java) {
            install(Auth) {
                bearer {
                    loadTokens {
                        BearerTokens(
                            accessToken = "<redacted>",
                            refreshToken = null,
                        )
                    }
                }
            }
            install(Logging) {
                level = LogLevel.ALL
            }
            install(ContentNegotiation) {
                json()
            }
Followed by this request:
Copy code
return httpClient
            .post(URL) {
                contentType(ContentType.Application.Json)
                setBody(request)
                headers {
                    append(HttpHeaders.Accept, "image/jpeg")
                }
            }.readRawBytes()
Clearly shows from the Ktor logging that the Accept header is set to `application/json`:
Copy code
METHOD: POST
COMMON HEADERS
-> Accept: application/json
-> Accept-Charset: UTF-8
-> Authorization: Bearer <redacted>
Am I mis-using the configuration API?
a
I cannot reproduce the problem with the following code:
Copy code
val client = HttpClient(Java) {
    install(ContentNegotiation) {
        json()
    }
}

val response = <http://client.post|client.post>("<https://httpbin.org/post>") {
    contentType(ContentType.Application.Json)
    setBody("test")
    headers {
        append(HttpHeaders.Accept, "image/jpeg")
    }
}

println(response.bodyAsText())
As a result, the
Accept: image/jpeg,application/json
header is sent to the server. Since the
json
method registers the content converter for the
application/json
content type, the
Accept
header contains both content types.
t
Which versions are you using?
a
3.1.1
t
Sort of user error? IntelliJ keeps auto importing
import io.ktor.http.headers
which is not the correct header builder. Even after I delete it to specify the proper import
import io.ktor.client.request.headers
it just keeps bringing it back until you delete the associated code. Mystery solved, but annoying! Thanks.
a
Ah, that's the problem. Feel free to file an issue.