Looks like a possible RFC 2616 MUST violation. Various malformed Expires header values (including the "0" value explicitly mentioned by RFC 2616) are not treated as "in the past". See attached trace(s) for details and ways to reproduce the violation mentioned above. Test case IDs in the trace link to human-oriented test case description and RFC quotes, if available.
Created attachment 4610 [details] "Expires: 0" case trace
Created attachment 4612 [details] "Expires: yesterday" case trace
Created attachment 7085 [details] Patch submitted by Kris Verbeeck <kris.verbeeck@chello.be>. See next comment for more info.
(Comments by Kris Verbeeck. Easier to find them if they are in the PR. - Paul J. Reder) PR 16521 states that mod_cache caches and returns responses that have an invalid Expires header (value is 0 or yesterday). The attached patch resolves this issue. Some explanation: - when apr_date_parse_http returns APR_DATE_BAD, the local variable containing the expires header was reset to NULL; - the check a bit lower in the code: if (exps != NULL && exp == APR_DATE_BAD) { would always fail because when exp equals APR_DATE_BAD, exps was always NULL.
Created attachment 7125 [details] test case trace (extended RFC850 format)
Getting closer! With the proposed patch, "0" and "yesterday" cases pass as do other 8 cases in this "bad Expires" clause. However, one test case still fails. The failed test case deals with dates in RFC 850 format followed by junk. Perhaps Apache is forgetting to check that no "extra" characters exist after partsing RFC 850 dates correctly? The trace for the failed case is attached. Thank you.
Created attachment 7186 [details] Fix for handling the date ending with extra junk characters.
This patch (attachement ID 7186)is to fix the date followed by junk, in all RFC 850, RFC 1123 and Asctime formats. Do we need to handle the condition where the Date is not represented in GMT or no time zone is specified? (Example: "Sun, 06 Nov 1994 08:49:37 ") RFC 2616, 3.3.1 says: All HTTP date/time stamps MUST be represented in GMT, without exception. HTTP-date is case sensitive and MUST NOT include additional LWS beyond that specifically included as SP in the grammar. Note: Recipients of date values are encouraged to be robust in accepting date values that may have been sent by non-HTTP applications, as is sometimes the case when retrieving or posting messages via proxies/gateways to SMTP or NNTP.
IMO, yes, you do. Recall that we are talking about cache freshness here. A cache is a performance optimization with serious freshness side-effects. We should err on the safe side (generate a miss, not a hit) whenever there are doubts. The above does not mean that implementation should reject messages with invalid expiration dates, of course. Just treat them as stale.
Created attachment 7430 [details] a safer version of the patch in attachment 7186 [details]?
The patch in attachment 7186 [details] (when used with the original patch in the attacment 7085) leads to coredumps. I am not an Apache developer, but it looks like "timstr" may be NULL while it is used in the if-statement in the attachment 7186 [details]. Attachment 7430 [details] contains a safer combination of the above mentioned two patches. It does not lead to coredumps and does let Apache pass all test cases in this test clause. I do not know if it does the right thing overall though. Please check.
I'm going through the bug db to make sure patches are findable. Please see http://httpd.apache.org/dev/patches.html
FYI: this violation seems to be present in httpd-2.0.54
The fix to the Expires being treated as missing instead of in the past when a bad date arrives is fixed on trunk in r1070128. As to rejecting the junk characters at the end, some browsers such as Netscape have inserted junk at the end in the past, and it's safer to be lenient in what we accept. The APR people, when asked, said no to being more restrictive than strictly necessary, so this bit is wontfix. http://mail-archives.apache.org/mod_mbox/apr-dev/201102.mbox/%3CA39C22BC-D1CF-445F-BAE1-C83C25276DF4@gbiv.com%3E