diff --git a/include/iocore/cache/HttpTransactCache.h b/include/iocore/cache/HttpTransactCache.h index ecf7f70eefa..317bbcf19ed 100644 --- a/include/iocore/cache/HttpTransactCache.h +++ b/include/iocore/cache/HttpTransactCache.h @@ -65,6 +65,9 @@ class HttpTransactCache static float calculate_quality_of_accept_encoding_match(MIMEField *accept_field, MIMEField *content_field, MIMEField *cached_accept_field = nullptr); + static ink_time_t calculate_document_age(ink_time_t request_time, ink_time_t response_time, HTTPHdr *base_response, + ink_time_t base_response_date, ink_time_t now); + // 'encoding_identifier' is a nul-terminated string. static bool match_content_encoding(MIMEField *accept_field, const char *encoding_identifier); diff --git a/include/proxy/http/HttpTransactHeaders.h b/include/proxy/http/HttpTransactHeaders.h index ffabdc53b10..aa141fa5101 100644 --- a/include/proxy/http/HttpTransactHeaders.h +++ b/include/proxy/http/HttpTransactHeaders.h @@ -23,6 +23,8 @@ #pragma once +#include "proxy/http/HttpTransact.h" + #define ink_time_t time_t extern int nstrhex(char *d, unsigned int i); @@ -50,8 +52,6 @@ class HttpTransactHeaders static void convert_to_1_0_response_header(HTTPHdr *outgoing_response, char const *reason_phrase = nullptr); static void convert_to_1_1_response_header(HTTPHdr *outgoing_response, char const *reason_phrase = nullptr); - static ink_time_t calculate_document_age(ink_time_t request_time, ink_time_t response_time, HTTPHdr *base_response, - ink_time_t base_response_date, ink_time_t now); static bool does_server_allow_response_to_be_stored(HTTPHdr *resp, bool does_server_allow_response_to_be_stored); static bool downgrade_request(bool *origin_server_keep_alive, HTTPHdr *outgoing_request); static bool is_method_safe(int method); diff --git a/src/iocore/cache/HttpTransactCache.cc b/src/iocore/cache/HttpTransactCache.cc index a581e7b4339..6a391b0356a 100644 --- a/src/iocore/cache/HttpTransactCache.cc +++ b/src/iocore/cache/HttpTransactCache.cc @@ -25,14 +25,16 @@ #include "tscore/ink_platform.h" -#include "proxy/http/HttpTransact.h" -#include "proxy/http/HttpTransactHeaders.h" +#include "api/APIHook.h" +#include "api/InkAPIInternal.h" #include "iocore/cache/HttpTransactCache.h" #include +#include "proxy/HttpAPIHooks.h" #include "proxy/hdrs/HTTP.h" #include "proxy/hdrs/HttpCompat.h" #include "tscore/InkErrno.h" +#include "tscore/ink_time.h" /** Find the pointer and length of an etag, after stripping off any leading @@ -206,10 +208,10 @@ HttpTransactCache::SelectFromAlternates(CacheHTTPInfoVector *cache_vector, HTTPH if (alt_count > 1) { if (t_now == 0) { - t_now = ink_local_time(); + t_now = ink_hrtime_to_sec(ink_get_hrtime()); } - current_age = HttpTransactHeaders::calculate_document_age(obj->request_sent_time_get(), obj->response_received_time_get(), - cached_response, cached_response->get_date(), t_now); + current_age = HttpTransactCache::calculate_document_age(obj->request_sent_time_get(), obj->response_received_time_get(), + cached_response, cached_response->get_date(), t_now); // Overflow? if (current_age < 0) { current_age = CacheHighAgeWatermark; @@ -591,6 +593,74 @@ HttpTransactCache::calculate_quality_of_accept_match(MIMEField *accept_field, MI return (q); } +/////////////////////////////////////////////////////////////////////////////// +// Name : calculate_document_age() +// Description: returns age of document +// +// Input : +// Output : ink_time_t age +// +// Details : +// Algorithm is straight out of March 1998 1.1 specs, Section 13.2.3 +// +/////////////////////////////////////////////////////////////////////////////// +ink_time_t +HttpTransactCache::calculate_document_age(ink_time_t request_time, ink_time_t response_time, HTTPHdr *base_response, + ink_time_t base_response_date, ink_time_t now) +{ + ink_time_t age_value = base_response->get_age(); + ink_time_t date_value = 0; + ink_time_t apparent_age = 0; + ink_time_t corrected_received_age = 0; + ink_time_t response_delay = 0; + ink_time_t corrected_initial_age = 0; + ink_time_t current_age = 0; + ink_time_t resident_time = 0; + ink_time_t now_value = 0; + + ink_time_t tmp_value = 0; + + tmp_value = base_response_date; + date_value = (tmp_value > 0) ? tmp_value : 0; + + // Deal with clock skew. Sigh. + // + // TODO solve this global clock problem + now_value = std::max(now, response_time); + + ink_assert(response_time >= 0); + ink_assert(request_time >= 0); + ink_assert(response_time >= request_time); + ink_assert(now_value >= response_time); + + if (date_value > 0) { + apparent_age = std::max(static_cast(0), (response_time - date_value)); + } + if (age_value < 0) { + current_age = -1; // Overflow from Age: header + } else { + corrected_received_age = std::max(apparent_age, age_value); + response_delay = response_time - request_time; + corrected_initial_age = corrected_received_age + response_delay; + resident_time = now_value - response_time; + current_age = corrected_initial_age + resident_time; + } + + Debug("http_age", "[calculate_document_age] age_value: %" PRId64, (int64_t)age_value); + Debug("http_age", "[calculate_document_age] date_value: %" PRId64, (int64_t)date_value); + Debug("http_age", "[calculate_document_age] response_time: %" PRId64, (int64_t)response_time); + Debug("http_age", "[calculate_document_age] now: %" PRId64, (int64_t)now); + Debug("http_age", "[calculate_document_age] now (fixed): %" PRId64, (int64_t)now_value); + Debug("http_age", "[calculate_document_age] apparent_age: %" PRId64, (int64_t)apparent_age); + Debug("http_age", "[calculate_document_age] corrected_received_age: %" PRId64, (int64_t)corrected_received_age); + Debug("http_age", "[calculate_document_age] response_delay: %" PRId64, (int64_t)response_delay); + Debug("http_age", "[calculate_document_age] corrected_initial_age: %" PRId64, (int64_t)corrected_initial_age); + Debug("http_age", "[calculate_document_age] resident_time: %" PRId64, (int64_t)resident_time); + Debug("http_age", "[calculate_document_age] current_age: %" PRId64, (int64_t)current_age); + + return current_age; +} + /** Match request Accept-Charset with response Content-Type. diff --git a/src/iocore/cache/unit_tests/main.cc b/src/iocore/cache/unit_tests/main.cc index 863f656ee2a..9c39f6be1fb 100644 --- a/src/iocore/cache/unit_tests/main.cc +++ b/src/iocore/cache/unit_tests/main.cc @@ -366,3 +366,43 @@ CacheReadTest::start_test(int event, void *e) } constexpr size_t WRITE_LIMIT = 1024 * 3; + +/************ STUB ******************/ + +#include "api/FetchSM.h" +ClassAllocator FetchSMAllocator("unusedFetchSMAllocator"); +void +FetchSM::ext_launch() +{ +} +void +FetchSM::ext_destroy() +{ +} +ssize_t +FetchSM::ext_read_data(char *, unsigned long) +{ + return 0; +} +void +FetchSM::ext_add_header(char const *, int, char const *, int) +{ +} +void +FetchSM::ext_write_data(void const *, unsigned long) +{ +} +void * +FetchSM::ext_get_user_data() +{ + return nullptr; +} +void +FetchSM::ext_set_user_data(void *) +{ +} +void +FetchSM::ext_init(Continuation *, char const *, char const *, char const *, sockaddr const *, int) +{ +} +ChunkedHandler::ChunkedHandler() {} diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc index 53880f7cec7..55b646ca691 100644 --- a/src/proxy/http/HttpTransact.cc +++ b/src/proxy/http/HttpTransact.cc @@ -5994,9 +5994,9 @@ HttpTransact::is_stale_cache_response_returnable(State *s) } // See how old the document really is. We don't want create a // stale content museum of documents that are no longer available - time_t current_age = HttpTransactHeaders::calculate_document_age(s->cache_info.object_read->request_sent_time_get(), - s->cache_info.object_read->response_received_time_get(), - cached_response, cached_response->get_date(), s->current.now); + time_t current_age = HttpTransactCache::calculate_document_age(s->cache_info.object_read->request_sent_time_get(), + s->cache_info.object_read->response_received_time_get(), + cached_response, cached_response->get_date(), s->current.now); // Negative age is overflow if ((current_age < 0) || (current_age > s->txn_conf->cache_max_stale_age)) { TxnDebug("http_trans", "document age is too large %" PRId64, (int64_t)current_age); @@ -7347,8 +7347,8 @@ HttpTransact::what_is_document_freshness(State *s, HTTPHdr *client_request, HTTP fresh_limit = calculate_document_freshness_limit(s, cached_obj_response, response_date, &heuristic); ink_assert(fresh_limit >= 0); - current_age = HttpTransactHeaders::calculate_document_age(s->request_sent_time, s->response_received_time, cached_obj_response, - response_date, s->current.now); + current_age = HttpTransactCache::calculate_document_age(s->request_sent_time, s->response_received_time, cached_obj_response, + response_date, s->current.now); // First check overflow status // Second if current_age is under the max, use the smaller value diff --git a/src/proxy/http/HttpTransactHeaders.cc b/src/proxy/http/HttpTransactHeaders.cc index 944439b32d7..b3b4de8975b 100644 --- a/src/proxy/http/HttpTransactHeaders.cc +++ b/src/proxy/http/HttpTransactHeaders.cc @@ -363,74 +363,6 @@ HttpTransactHeaders::convert_to_1_1_response_header(HTTPHdr *outgoing_response, } } -/////////////////////////////////////////////////////////////////////////////// -// Name : calculate_document_age() -// Description: returns age of document -// -// Input : -// Output : ink_time_t age -// -// Details : -// Algorithm is straight out of March 1998 1.1 specs, Section 13.2.3 -// -/////////////////////////////////////////////////////////////////////////////// -ink_time_t -HttpTransactHeaders::calculate_document_age(ink_time_t request_time, ink_time_t response_time, HTTPHdr *base_response, - ink_time_t base_response_date, ink_time_t now) -{ - ink_time_t age_value = base_response->get_age(); - ink_time_t date_value = 0; - ink_time_t apparent_age = 0; - ink_time_t corrected_received_age = 0; - ink_time_t response_delay = 0; - ink_time_t corrected_initial_age = 0; - ink_time_t current_age = 0; - ink_time_t resident_time = 0; - ink_time_t now_value = 0; - - ink_time_t tmp_value = 0; - - tmp_value = base_response_date; - date_value = (tmp_value > 0) ? tmp_value : 0; - - // Deal with clock skew. Sigh. - // - // TODO solve this global clock problem - now_value = std::max(now, response_time); - - ink_assert(response_time >= 0); - ink_assert(request_time >= 0); - ink_assert(response_time >= request_time); - ink_assert(now_value >= response_time); - - if (date_value > 0) { - apparent_age = std::max(static_cast(0), (response_time - date_value)); - } - if (age_value < 0) { - current_age = -1; // Overflow from Age: header - } else { - corrected_received_age = std::max(apparent_age, age_value); - response_delay = response_time - request_time; - corrected_initial_age = corrected_received_age + response_delay; - resident_time = now_value - response_time; - current_age = corrected_initial_age + resident_time; - } - - Debug("http_age", "[calculate_document_age] age_value: %" PRId64, (int64_t)age_value); - Debug("http_age", "[calculate_document_age] date_value: %" PRId64, (int64_t)date_value); - Debug("http_age", "[calculate_document_age] response_time: %" PRId64, (int64_t)response_time); - Debug("http_age", "[calculate_document_age] now: %" PRId64, (int64_t)now); - Debug("http_age", "[calculate_document_age] now (fixed): %" PRId64, (int64_t)now_value); - Debug("http_age", "[calculate_document_age] apparent_age: %" PRId64, (int64_t)apparent_age); - Debug("http_age", "[calculate_document_age] corrected_received_age: %" PRId64, (int64_t)corrected_received_age); - Debug("http_age", "[calculate_document_age] response_delay: %" PRId64, (int64_t)response_delay); - Debug("http_age", "[calculate_document_age] corrected_initial_age: %" PRId64, (int64_t)corrected_initial_age); - Debug("http_age", "[calculate_document_age] resident_time: %" PRId64, (int64_t)resident_time); - Debug("http_age", "[calculate_document_age] current_age: %" PRId64, (int64_t)current_age); - - return current_age; -} - bool HttpTransactHeaders::does_server_allow_response_to_be_stored(HTTPHdr *resp, bool ignore_no_store_and_no_cache_directives) { @@ -658,7 +590,7 @@ HttpTransactHeaders::insert_time_and_age_headers_in_response(ink_time_t request_ ink_time_t now, HTTPHdr *base, HTTPHdr *outgoing) { ink_time_t date = base->get_date(); - ink_time_t current_age = calculate_document_age(request_sent_time, response_received_time, base, date, now); + ink_time_t current_age = HttpTransactCache::calculate_document_age(request_sent_time, response_received_time, base, date, now); outgoing->set_age(current_age); // set_age() deals with overflow properly, so pass it along