Open jwadolowski opened 6 years ago
Hi @jwadolowski , you may configure what headers are returned by Knot.x Server instance and what are not by overriding allowedResponseHeaders
in the conf/includes/server.conf
. With that you can achieve the expected behavior you mentioned:
stop sending Last-Modified header completely (just remove
Last-Modified
entry in your Knot.x instance configuration).
The default behavior you suggested:
re-set Last-Modified if Handlebars markup got evaluated and placeholders were filled in with dynamic data
looks good to me. It could quite nice improvement.
Let us know it that helped.
Thanks @Skejven. allowedResponseHeaders
will do the trick, however there are 2 downsides of this approach:
Last-Modified
is actually expected. This is a global change, so we may break other things that rely on such headerallowedResponseHeaders
is a whitelist, which on one hand is good, but on the other hand makes "allow all the headers except X and Y" policy quite hard to implement. This is not a big deal for most users, but I can imagine some could complain about that.Workaround I used was implemented directly at CDN level.
Regarding re-setting Last-Modified
- I started thinking about that and it seems to be more complex than I originally assumed. Here's a few use cases:
Last-Modified
from the template itselfLast-Modified
header knot.x could pick the newest date and send it back to the client. If the header doesn't appear in a consistent manner then knot.x should probably calculate its own valueETag
is probably more appropriate.In general there's probably no universal solution.
@jwadolowski , there might be a solution that Knot.x can technically support. It is a bit simplified scenario in comparison to your proposition:
Last-Modified
header.304
, additional call is made without the header for the template.snippet
.304
is returned by Knot.x, otherwise standard template processing is done.As you wrote, this is not universal solution. It is custom behaviour, not everyone might want to use it. In my opinion this is good candidate for Knot.x 2.0
when it will be easy to insert some custom handler with that logic.
Bug description
I recently discovered that knot.x copies
Last-Modified
header it receives from template repository and sends it back to the HTTP client. Such behavior can cause caching issues, especially when rather static templates are combined with dynamic data and the response goes through shared cache (CDN, forward proxy server, etc).knot.x version:
1.4.0
Steps to reproduce
I captured 2 scenarios that outline the problem.
1st example
Cache-Control: private
) and contains the sameLast-Modified
header knot.x got from template repositoryIf-Modified-Since
header (to be honest I have no idea why Chrome decided to send such request, perhapsLast-Modified
presence was enough andCache-Control: private
doesn't have any meaning in this context)Last-Modified
header. At the same time it remembered that the request hadIf-Modified-Since
header. Simple date comparison takes place and it turns out that nothing has changed, so CDN thinks it's ok to reply with 304 to save some bandwidth (304 doesn't have the body)2nd example
Cache-Control
,Surrogate-Control
,Edge-Control
or any other header that tells CDN how long it can keep it in the cacheLast-Modified
header value and sends GET withIf-Modified-Since: <date_from_last_modified_header>
. knot.x does its magic and returnsLast-Modified
it got from the template call.Expected behavior
My first thought was that knot.x should do one of the following things:
Last-Modified
it gets from template repositoryLast-Modified
if Handlebars markup got evaluated and placeholders were filled in with dynamic dataLast-Modified
header completelyAfter a bit of thinking I realized that in some cases
Last-Modified
header presence could be needed (i.e. template that renders single object off of some identifier that doesn't change often). At the same time re-using whatever came from template repository is definitely not expected.As a rule of thumb I'd say that whenever knot.x injects data into Handlebars template it should remove
Last-Modified
header and possibly re-set its value. Ideally the 2nd part should be somehow configurable.Screenshots
N/A
Additional context
N/A