Closed macrojames closed 9 years ago
So, the issue is multiple requests within the remaining part of a second since an image was cached will result in the image being sent again?
It happens on single requests, even after some time. The mtime is more accurate and is always some microseconds "newer" than the header. Happens for all of my files but only in wsgi mode, not in the flask integrate dev server.
But, how? If-Modified-Since
generally contains the value of Last-Modified
as originally sent by the server (unless the client assumes the responsibility of fully understanding the server's concept of time). Last-Modified
will be set to the same value as mtime
(without microseconds). So the only time (in which I can conceive of) this happens is when requested again within the remaining fraction of a second as another request, which is also the same second that the file was modified.
No, because the browser or the Apache just drops the fraction. The browser never knows about the fraction. The next request will consider if-modified-since
as datetime without fractional seconds. Like a floor()
operation.
Indeed.
Given that, the only time that request.if_modified_since >= mtime
gives an unintended result should be within the remaining fraction of a second as another request, which is also the same second that the file was modified.
So sure, it can happen, but only in that tiny slice of time in a use pattern way outside normal. And even then, it will likely catch against the etag before sending the payload.
That is my understanding, at least. I'd love to know how I'm wrong.
If-modified-since
is independent from the request time. It is the saved timestamp from the browser cache. It will stay the last received mtime
until a newer file is received.
:bulb:!
The Last-Modified
is always set from the file's mtime, and then compared to it again, at which point the microseconds have been truncated and it fails. The reason why mine works is because my platforms do not have microseconds returned from os.path.getmtime
.
I propose truncating the microseconds off of the timestamp. Either with a .replace
or math.floor
(.replace
seems better).
Thanks for sticking with this. :grinning:
That makes last_modified bigger than if_modified_since because of the microseconds Impact: no 304 (Not modified) is sent, but the picture itself.
My ugly patch was:
That works for me, but doesn't solve the real problem. Root cause is unknown for me, but the header will never have parts of seconds set.