HTTP Compliance: improve age calculation. Account for response delay in age calculation as described in RFC 2616 section 13.2.3. Co-Advisor test cases: test_case/rfc2616/ageCalc-none-7-none test_case/rfc2616/ageCalc-5400-4-5 === modified file 'src/store.cc' --- src/store.cc 2010-09-01 05:07:21 +0000 +++ src/store.cc 2010-09-28 03:48:39 +0000 @@ -1487,63 +1487,66 @@ StoreEntry::validToSend() const { if (EBIT_TEST(flags, RELEASE_REQUEST)) return 0; if (EBIT_TEST(flags, ENTRY_NEGCACHED)) if (expires <= squid_curtime) return 0; if (EBIT_TEST(flags, ENTRY_ABORTED)) return 0; return 1; } void StoreEntry::timestampsSet() { const HttpReply *reply = getReply(); time_t served_date = reply->date; int age = reply->header.getInt(HDR_AGE); - /* - * The timestamp calculations below tries to mimic the properties - * of the age calculation in RFC2616 section 13.2.3. The implementaion - * isn't complete, and the most notable exception from the RFC is that - * this does not account for response_delay, but it probably does - * not matter much as this is calculated immediately when the headers - * are received, not when the whole response has been received. - */ + + /* Compute the timestamp, mimicking RFC2616 section 13.2.3. */ + /* make sure that 0 <= served_date <= squid_curtime */ if (served_date < 0 || served_date > squid_curtime) served_date = squid_curtime; /* * Compensate with Age header if origin server clock is ahead * of us and there is a cache in between us and the origin * server. But DONT compensate if the age value is larger than * squid_curtime because it results in a negative served_date. */ if (age > squid_curtime - served_date) if (squid_curtime > age) served_date = squid_curtime - age; + // compensate for Squid-to-server and server-to-Squid delays + if (mem_obj && mem_obj->request) { + const time_t request_sent = + mem_obj->request->hier.peer_http_request_sent.tv_sec; + if (0 < request_sent && request_sent < squid_curtime) + served_date -= (squid_curtime - request_sent); + } + if (reply->expires > 0 && reply->date > -1) expires = served_date + (reply->expires - reply->date); else expires = reply->expires; lastmod = reply->last_modified; timestamp = served_date; } void StoreEntry::registerAbort(STABH * cb, void *data) { assert(mem_obj); assert(mem_obj->abort.callback == NULL); mem_obj->abort.callback = cb; mem_obj->abort.data = cbdataReference(data); } void