Why is Firefox not sending the If-Modified-Since header?
Okay, I feel like a doofus but decided to put my pride aside, and rather than just deleting this question, tell what the solution was in case anyone else ever did the same thing...
Once upon a time, in order to test something, I had turned off caching in Firefox. I turned it back on, and now it is sending the header.
For me, the problem turned out to be that the Last-Modified
date in the response I was sending wasn't exactly RFC 1123. Chrome didn't mind; it happily sent my malformed timestamp back in the If-Modified-Since
header. Firefox, however, quietly ignored it.
I can see from your headers this wasn't the reason in your case, but I'm posting this answer anyhow, since it took a while for me to realise this was the issue, and maybe, some day, somebody else will have the same problem.
This is under Linux, FWIW (Mint 17, to be precise) but I expect both browsers would behave the same way under other OSes.
For me, it was that Firefox (ESR 60.4.0) wasn't sending "If-Modified-Since" nor "If-None-Match" headers for some resources (like CSS, JS) when I loaded site from address bar.
However, when asking for reload with "ctrl+r", it was sending both headers, but resources still were reloaded with "200 OK" even if they should have returned "304 Not modified"
After some tracking, I found out that it was due to apache 2.4.25 deflate module. If resources were compressed, they effectively would not be cached (that is, they would be reloaded on next access). When looking more into it, it turns out it is due to ETag handling when using deflate.
So the most reasonable kludge for me was using "FileETag None", and now I properly get "304" even for compressed documents when I do "ctrl-r".
Amazingly, even after that it still showed green "200 OK" indicating full retrieval od CSS and JS (and no "If-Modified-Since" in detailed "Request headers" panel) which drove me crazy, until I figured out that this column is sometimes FAKED (there is another column called "Transferred", and if it says "cached" instead of number of bytes, it means firefox actually got the value from internal cache, and not from network "200 OK" request it shows. Checking access_log on server side confirmed that there is no network activity then, so that part just bad UI)