Stijndcl
06/30/2024, 9:41 PMAccept
headers from the client-side ContentNegotiation
plugin? I'm using a JSON api that can return a downloadable file for one endpoint if you pass Accept: application/octet-stream
instead, but if I set that in my client.get{}
then ContentNegotiation adds application/json
afterwards every time, and the API seems to pick the last supplied header. AKA I can never actually download this file unless I disable contentegotiation globally, which is not exactly convenient.Ulf
07/01/2024, 8:10 AMaccept(ContentType.Application.Pdf)
in the builder and stream the response to file with bodyAsChannel()Ulf
07/01/2024, 8:10 AM// ContentNegotiation plugin unconditionally adds accept headers for all supported conversions.
// However, if we explicitly set the accept header we don't want any to be added
client.requestPipeline.intercept(HttpRequestPipeline.Transform) { content ->
val request = this.context
val hasMultipleAccept = (request.headers.getAll(HttpHeaders.Accept)?.size ?: 0) > 1
if (hasMultipleAccept) {
// Remove all headers added by ContentNegotiation (for us it's only json)
request.headers.remove(HttpHeaders.Accept, ContentType.Application.Json.toString())
}
proceedWith(content)
}
Aleksei Tirman [JB]
07/01/2024, 11:10 AMapplication/octet-stream
content type?
install(ContentNegotiation) {
register(ContentType.Application.OctetStream, KotlinxSerializationConverter(Json { }))
}
Stijndcl
07/01/2024, 11:12 AMUlf
07/01/2024, 11:20 AMUlf
07/01/2024, 11:21 AM...
internal suspend fun convertRequest(request: HttpRequestBuilder, body: Any): Any? {
registrations.forEach {
LOGGER.trace("Adding Accept=${it.contentTypeToSend.contentType} header for ${request.url}")
if (request.headers.contains(HttpHeaders.Accept, it.contentTypeToSend.toString())) return@forEach
request.accept(it.contentTypeToSend)
}
Stijndcl
07/01/2024, 11:22 AMStijndcl
07/01/2024, 11:32 AMUlf
07/01/2024, 11:55 AMcreateClientPlugin("RemoveContentNegotiationAccept") {
transformRequestBody { request, _, _ ->
val hasMultipleAccept = (request.headers.getAll(HttpHeaders.Accept)?.size ?: 0) > 1
if (hasMultipleAccept) {
// Remove all headers added by ContentNegotiation (for us it's only json)
request.headers.remove(HttpHeaders.Accept, ContentType.Application.Json.toString())
}
null
}
}