[Zope-dev] problems with file caching

Itamar Shtull-Trauring itamars@ibm.net
Mon, 13 Dec 1999 11:41:35 +0200


Jonothan Farr wrote:

> The first problem has to do with the index_html() method of the File class in
> OFS/image.py.
> 
> Line 188 says:
> 
>             if self._p_mtime > ms:
>                 RESPONSE.setStatus(304)
>                 return RESPONSE
> 
> What this seems to say to me is, "If my modification time is later than the
> modification time of the cached file then send a 304 (Not Modified) response."
> If I'm not mistaken, this is exactly the opposite of what the HTTP
> specification says about the If-Modified-Since header.
> 
> So, line 188 should say:
> 
>             if self._p_mtime <= ms:
>                 ...

Here's an email I sent to Brian Lloyd, who said he'll fix this in 2.2.  I
hope you can make some sense out of it - the gist of it is that HTTP uses 1
second resolution, while DateTime has a resolution of more than 1 second:

Got it!  Or at least why <= wouldn't cache objects at all, and > had caching
working.  DateTime().timeTime() returns a float (resolution of more than 1
second).  The If-Modified-Since sends an int (resolution of a second, as
required by HTTP protocol).  HTTP 1.1 recommends If-Modified-Since send the
Last-Modified of the cached object.  But the Last-Modified header is
different than _p_mtime - _p_mtime is a float, most likely not a whole
number, while Last-Modified only has a resolution of seconds - it's a int. 
So the 304 is never sent if you use 'self._p_mtime <= ms'.  The fix is
simple:

in lib/python/OFS/Image.py, we do this:

        if int(self._p_mtime) <= ms:
                RESPONSE.setStatus(304)
                return RESPONSE

instead of:
        
        if self._p_mtime > ms:
                RESPONSE.setStatus(304)
                return RESPONSE

should solve the problem. Storing _p_mtime as a truncated integer would of
course be more efficient.  The cacheability engine at least likes it, while
without the int() says that image won't get cached.  

With > caching validation also sort of worked, since self._p_mtime is
usually bigger than int(self._p_mtime).  Since int(self._p_mtime) is what
cacheability, and presumabely proxies, send as If-Modified-Since (they take
it from Last-Modified of the image, which is int(self_p_mtime).

-- 
Itamar S.T.  itamars@ibm.net