Chris C
01/07/2022, 12:21 PMjava.lang.IllegalArgumentException: List has more than one element
because there are two values in the Accept header. Removing jackson fixes it, but I was hoping to use the same client for json responses too. Is this possible? I’m using 2.0.0-beta-1.
class AcceptTest {
private val readmeContentType = ContentType.parse("application/vnd.github.v3.html")
@Test
fun acceptTest() {
val client = HttpClient() {
install(ContentNegotiation) {
jackson { }
}
}
val readme: String = runBlocking {
client.get("<https://api.github.com/repos/ktorio/ktor/readme>") {
header(HttpHeaders.Accept, readmeContentType)
}.body()
}
println(readme)
}
}
Rustam Siniukov
01/07/2022, 9:26 PMContent-Type
header, when client sends 2 values in Accept
: Content-Type: application/json,application/vnd.github.v3.html; charset=utf-8
Chris C
01/08/2022, 2:55 PMRustam Siniukov
01/08/2022, 6:27 PMAccept: application/json, text/plain
. Then server can choose which format to replyChris C
01/08/2022, 9:20 PMval registrations = plugin.registrations
registrations.forEach { context.accept(it.contentTypeToSend) }
If that would be changed to this then I think that would give the request accept header precedence wouldn’t it?
val registrations = plugin.registrations
if (!context.headers.contains(HttpHeaders.Accept)) {
registrations.forEach { context.accept(it.contentTypeToSend) }
}
What do you think @Rustam Siniukov?Rustam Siniukov
01/10/2022, 1:56 PMAccept
header when needed. Something like
private val OverrideAcceptHeaderKey = AttributeKey<ContentType>("OverrideAcceptHeaderKey")
public var HttpRequestBuilder.overrideAcceptHeader: ContentType?
get() = attributes.getOrNull(OverrideAcceptHeaderKey)
set(value) {
if (value != null) attributes.put(OverrideAcceptHeaderKey, value)
else attributes.remove(OverrideAcceptHeaderKey)
}
@Test
fun acceptTest() = runBlocking {
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json()
}
}
val overrideAcceptHeaderPhase = PipelinePhase("overrideAcceptHeaderPhase")
client.requestPipeline.insertPhaseBefore(HttpRequestPipeline.Send, overrideAcceptHeaderPhase)
client.requestPipeline.intercept(overrideAcceptHeaderPhase) {
val acceptHeaderValue = context.overrideAcceptHeader ?: return@intercept
context.headers[HttpHeaders.Accept] = acceptHeaderValue
}
val response = client.get("<https://api.github.com/repos/ktorio/ktor/readme>") {
overrideAcceptHeader = readmeContentType
}
}
ContentNegotiation
from adding headers when they are already present in the request is not a solution.Chris C
01/10/2022, 3:35 PMRustam Siniukov
01/10/2022, 4:14 PMAccept
header and there are more plugins that manipulate headers than just ContentNegotiation
. Good solution should not be ad-hoc for just this one specific case.
Btw, point 3 can be solved with q
parameter on ContentType
Chris C
01/10/2022, 4:59 PM