Ktor: enhance api for ConditionalHeaders usage

Created on 2 Nov 2018  路  6Comments  路  Source: ktorio/ktor

sorry if there is already an appropriate way of doing this what I'm going to ask for. Since the documentation is lacking with respect to the usage of the ConditionalHeaders feature I coulnd't find a way of managing it concisely.
As far as I could see, in order to utilize ConditionalHeaders the OutgoingContent's headers need to be set. Thus this here

// somewhere in installation phase
    install(ContentNegotiation) {
        register(ContentType.Application.Json, GsonConverter())
    }
    install(ConditionalHeaders)

// somewhere in api call
ctx.call.response.header(HttpHeaders.LastModified, lastModifiedTime)
ctx.call.respond(HttpStatusCode.OK, anydata)

don't have any effect since the header of the ApplicationResponse is set (instead of the content).
Therefore when I use ContentNegotiation I would need to adapt the conversion process so that the produced OutgoingContent instances also contain the relevant headers which is imho against the concise api nature of ktor.

wouldn't it make sense that ApplicationResponse headers are applied to the OutgoingContent headers?

ux

Most helpful comment

I see only two options (we probably need both):

  • a content converter need to know how to extract lastModified/etag from a data object
  • conditional headers feature could check both content and response headers

The second one is easy to implement while the first requires design

All 6 comments

I see only two options (we probably need both):

  • a content converter need to know how to extract lastModified/etag from a data object
  • conditional headers feature could check both content and response headers

The second one is easy to implement while the first requires design

Please note that there is version function in ConditionalHeaders

application.install(ConditionalHeaders) {
    version { obj -> listOf(EntityTagVersion("tag1")) }
}

Unfortunately it's usage is very limited and need to be improved

@soywiz it's not documented btw, need to notice it here https://ktor.io/servers/features/conditional-headers.html

as a workaround I'll use this for the moment:

install(ContentNegotiation) {
    register(ContentType.Application.Json, GsonConverter())
}

sendPipeline.intercept(ApplicationSendPipeline.Render) { subject ->
    if(subject is OutgoingContent.ByteArrayContent) {
        proceedWith(ContentWithResponseHeaders(subject, context.response.headers.allValues()))
    }

}

install(ConditionalHeaders)

the workaround I shared with you a year ago was actually causing the issue of duplication #1471. Therefore the fix needs to happen in the feature itself

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Was this page helpful?
0 / 5 - 0 ratings