I added a custom caching behavior to my application, similar to what Thierry has proposed in this article. For every CSS, JS and HTML file server in my static content I am adding the two following headers:
// Added by me
ETag: "0c635aa7113262fac7606da2432e00f5" // md5(last_mod_date_of_file)
Cache-Control: max-age=31536000 // one year
// Automatically added by Restlet (probably Directory class?)
Date: Wed, 09 Nov 2016 11:50:53 GMT
Expires: Wed, 09 Nov 2016 12:00:53 GMT
Last-Modified: Wed, 09 Nov 2016 17:30:56 GMT
This works fine, however I have noticed that after deploying the code on test server and hitting F5 in Chrome, I fetch the entire body of response once again (with HTTP 200 returned).
I've noticed that those requests are using proper headers too:
Cache-Control:max-age=0
If-Modified-Since: Wed, 09 Nov 2016 17:30:56 GMT
If-None-Match: "0c635aa7113262fac7606da2432e00f5"
My question is, should I do any manual verifications of If-None-Match header in my server filter and return 304 response then? Or is that handled by Restlet?
Note: what's a bit strange in this issue is the fact that it seemed to work properly on my local development environment. I'm also a little bit confused as to why Expires is set by Restlet to a date before Last-Modified. I'll try to debug if this is the root of evil, but it doesn't invalidate my question about manual setting of 304 status and checking ETags on the server.
Ok, so I've been able to figure this out and I'm posting answers below.
Should I do any manual verification of If-None-Match header in my server filter and return 304 response then?
No, you don't have to do that yourself manually. This is automatically being handled by Restlet (
DirectoryServerResourcetakes care of that).What was the problem then?
The problem was indeed with the
Last-Modifiedheader being set to a future date. This has happened because my production server was inUTC-8Time Zone, whereas I'm developing inUTC+1.How did I fix it?
It required getting acquainted with Restlet API, but the solution was trivial then. I made sure that when my application is started it reads
File Last Modifiedproperty of my application directory from Operating System, as this is the value I wanted to use inLast-Modifiedheader. Now, you can't just set this header on aresponsein aFilter, as the automatic handling of HTTP caching headers happens before that in mentionedDirectoryServerResourceclass. So the solution is the following:Create a class which extends DSR (giving you all the automatic caching handling for free) and modify its
handle()method so thatLast-Modifiedheader is set before this logic kicks in:Now, make sure that your newly created resource is used by custom
Directoryclass.After that you can use
CachedWebAssetsDirectoryas you wish, building any custom filters on top of that.