| Index: net/http/http_response_headers.cc
|
| diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc
|
| index 9574b03bc851209f6d53797d7019690fcfd8d76b..61bb092756cc8d3e9b2df99a2985d942d62657e4 100644
|
| --- a/net/http/http_response_headers.cc
|
| +++ b/net/http/http_response_headers.cc
|
| @@ -944,37 +944,73 @@ bool HttpResponseHeaders::IsRedirectResponseCode(int response_code) {
|
| response_code == 308);
|
| }
|
|
|
| -// From RFC 2616 section 13.2.4:
|
| +// We calculate and return |corrected_response_time|, defined by:
|
| //
|
| -// The calculation to determine if a response has expired is quite simple:
|
| +// current_age = now - corrected_response_time
|
| //
|
| -// response_is_fresh = (freshness_lifetime > current_age)
|
| +// So a caller can store an ExpirationTimes object and use it to determine
|
| +// freshness throughout the objects lifetime.
|
| //
|
| // Of course, there are other factors that can force a response to always be
|
| // validated or re-fetched.
|
| -//
|
| -// From RFC 5861 section 3, a stale response may be used while revalidation is
|
| -// performed in the background if
|
| -//
|
| -// freshness_lifetime + stale_while_revalidate > current_age
|
| -//
|
| -ValidationType HttpResponseHeaders::RequiresValidation(
|
| +HttpResponseHeaders::ExpirationTimes HttpResponseHeaders::GetExpirationTimes(
|
| const Time& request_time,
|
| - const Time& response_time,
|
| - const Time& current_time) const {
|
| - FreshnessLifetimes lifetimes = GetFreshnessLifetimes(response_time);
|
| - if (lifetimes.freshness.is_zero() && lifetimes.staleness.is_zero())
|
| - return VALIDATION_SYNCHRONOUS;
|
| + const Time& response_time) const {
|
| + // From RFC 2616 section 13.2.3:
|
| + //
|
| + // Summary of age calculation algorithm, when a cache receives a response:
|
| + //
|
| + // /*
|
| + // * age_value
|
| + // * is the value of Age: header received by the cache with
|
| + // * this response.
|
| + // * date_value
|
| + // * is the value of the origin server's Date: header
|
| + // * request_time
|
| + // * is the (local) time when the cache made the request
|
| + // * that resulted in this cached response
|
| + // * response_time
|
| + // * is the (local) time when the cache received the
|
| + // * response
|
| + // * now
|
| + // * is the current (local) time
|
| + // */
|
| + // apparent_age = max(0, response_time - date_value);
|
| + // corrected_received_age = max(apparent_age, age_value);
|
| + // response_delay = response_time - request_time;
|
| + // corrected_initial_age = corrected_received_age + response_delay;
|
| + // resident_time = now - response_time;
|
| + // current_age = corrected_initial_age + resident_time;
|
|
|
| - TimeDelta age = GetCurrentAge(request_time, response_time, current_time);
|
| + // If there is no Date header, then assume that the server response was
|
| + // generated at the time when we received the response.
|
| + Time date_value;
|
| + if (!GetDateValue(&date_value))
|
| + date_value = response_time;
|
|
|
| - if (lifetimes.freshness > age)
|
| - return VALIDATION_NONE;
|
| + // If there is no Age header, then assume age is zero. GetAgeValue does not
|
| + // modify its out param if the value does not exist.
|
| + TimeDelta age_value;
|
| + GetAgeValue(&age_value);
|
|
|
| - if (lifetimes.freshness + lifetimes.staleness > age)
|
| - return VALIDATION_ASYNCHRONOUS;
|
| + TimeDelta apparent_age = std::max(TimeDelta(), response_time - date_value);
|
| + TimeDelta corrected_received_age = std::max(apparent_age, age_value);
|
| + TimeDelta response_delay = response_time - request_time;
|
| + TimeDelta corrected_initial_age = corrected_received_age + response_delay;
|
|
|
| - return VALIDATION_SYNCHRONOUS;
|
| + // From the age calculation algorithm above, we can derive the corrected
|
| + // response time, the |now| for which |current_age == 0|. Substituting into
|
| + // the RFC 2616 13.2.3 equations above, and simplyfing:
|
| + //
|
| + // corrected_initial_age + resident_time == 0
|
| + // corrected_initial_age + corrected_response_time - response_time == 0
|
| + // corrected_response_time == response_time - corrected_initial_age
|
| +
|
| + ExpirationTimes expirations;
|
| + expirations.corrected_response_time = response_time - corrected_initial_age;
|
| + CalculateLifetimes(response_time, &expirations.freshness_lifetime,
|
| + &expirations.staleness_lifetime);
|
| + return expirations;
|
| }
|
|
|
| // From RFC 2616 section 13.2.4:
|
| @@ -1000,9 +1036,13 @@ ValidationType HttpResponseHeaders::RequiresValidation(
|
| // If the stale-while-revalidate directive is present, then it is used to set
|
| // the |staleness| time, unless it overridden by another directive.
|
| //
|
| -HttpResponseHeaders::FreshnessLifetimes
|
| -HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
|
| - FreshnessLifetimes lifetimes;
|
| +void HttpResponseHeaders::CalculateLifetimes(
|
| + const Time& response_time,
|
| + TimeDelta* out_freshness_lifetime,
|
| + TimeDelta* out_staleness_lifetime) const {
|
| + *out_freshness_lifetime = TimeDelta();
|
| + *out_staleness_lifetime = TimeDelta();
|
| +
|
| // Check for headers that force a response to never be fresh. For backwards
|
| // compat, we treat "Pragma: no-cache" as a synonym for "Cache-Control:
|
| // no-cache" even though RFC 2616 does not specify it.
|
| @@ -1011,22 +1051,23 @@ HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
|
| HasHeaderValue("pragma", "no-cache") ||
|
| // Vary: * is never usable: see RFC 2616 section 13.6.
|
| HasHeaderValue("vary", "*")) {
|
| - return lifetimes;
|
| + return;
|
| }
|
|
|
| // Cache-Control directive must_revalidate overrides stale-while-revalidate.
|
| bool must_revalidate = HasHeaderValue("cache-control", "must-revalidate");
|
|
|
| - if (must_revalidate || !GetStaleWhileRevalidateValue(&lifetimes.staleness)) {
|
| - DCHECK_EQ(TimeDelta(), lifetimes.staleness);
|
| + if (must_revalidate ||
|
| + !GetStaleWhileRevalidateValue(out_staleness_lifetime)) {
|
| + DCHECK_EQ(TimeDelta(), *out_staleness_lifetime);
|
| }
|
|
|
| // NOTE: "Cache-Control: max-age" overrides Expires, so we only check the
|
| // Expires header after checking for max-age in GetFreshnessLifetimes. This
|
| // is important since "Expires: <date in the past>" means not fresh, but
|
| // it should not trump a max-age value.
|
| - if (GetMaxAgeValue(&lifetimes.freshness))
|
| - return lifetimes;
|
| + if (GetMaxAgeValue(out_freshness_lifetime))
|
| + return;
|
|
|
| // If there is no Date header, then assume that the server response was
|
| // generated at the time when we received the response.
|
| @@ -1038,12 +1079,12 @@ HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
|
| if (GetExpiresValue(&expires_value)) {
|
| // The expires value can be a date in the past!
|
| if (expires_value > date_value) {
|
| - lifetimes.freshness = expires_value - date_value;
|
| - return lifetimes;
|
| + *out_freshness_lifetime = expires_value - date_value;
|
| + return;
|
| }
|
|
|
| - DCHECK_EQ(TimeDelta(), lifetimes.freshness);
|
| - return lifetimes;
|
| + DCHECK_EQ(TimeDelta(), *out_freshness_lifetime);
|
| + return;
|
| }
|
|
|
| // From RFC 2616 section 13.4:
|
| @@ -1077,8 +1118,8 @@ HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
|
| if (GetLastModifiedValue(&last_modified_value)) {
|
| // The last-modified value can be a date in the future!
|
| if (last_modified_value <= date_value) {
|
| - lifetimes.freshness = (date_value - last_modified_value) / 10;
|
| - return lifetimes;
|
| + *out_freshness_lifetime = (date_value - last_modified_value) / 10;
|
| + return;
|
| }
|
| }
|
| }
|
| @@ -1086,66 +1127,16 @@ HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
|
| // These responses are implicitly fresh (unless otherwise overruled):
|
| if (response_code_ == 300 || response_code_ == 301 || response_code_ == 308 ||
|
| response_code_ == 410) {
|
| - lifetimes.freshness = TimeDelta::Max();
|
| - lifetimes.staleness = TimeDelta(); // It should never be stale.
|
| - return lifetimes;
|
| + *out_freshness_lifetime = TimeDelta::Max();
|
| + *out_staleness_lifetime = TimeDelta(); // It should never be stale.
|
| + return;
|
| }
|
|
|
| // Our heuristic freshness estimate for this resource is 0 seconds, in
|
| // accordance with common browser behaviour. However, stale-while-revalidate
|
| // may still apply.
|
| - DCHECK_EQ(TimeDelta(), lifetimes.freshness);
|
| - return lifetimes;
|
| -}
|
| -
|
| -// From RFC 2616 section 13.2.3:
|
| -//
|
| -// Summary of age calculation algorithm, when a cache receives a response:
|
| -//
|
| -// /*
|
| -// * age_value
|
| -// * is the value of Age: header received by the cache with
|
| -// * this response.
|
| -// * date_value
|
| -// * is the value of the origin server's Date: header
|
| -// * request_time
|
| -// * is the (local) time when the cache made the request
|
| -// * that resulted in this cached response
|
| -// * response_time
|
| -// * is the (local) time when the cache received the
|
| -// * response
|
| -// * now
|
| -// * is the current (local) time
|
| -// */
|
| -// apparent_age = max(0, response_time - date_value);
|
| -// corrected_received_age = max(apparent_age, age_value);
|
| -// response_delay = response_time - request_time;
|
| -// corrected_initial_age = corrected_received_age + response_delay;
|
| -// resident_time = now - response_time;
|
| -// current_age = corrected_initial_age + resident_time;
|
| -//
|
| -TimeDelta HttpResponseHeaders::GetCurrentAge(const Time& request_time,
|
| - const Time& response_time,
|
| - const Time& current_time) const {
|
| - // If there is no Date header, then assume that the server response was
|
| - // generated at the time when we received the response.
|
| - Time date_value;
|
| - if (!GetDateValue(&date_value))
|
| - date_value = response_time;
|
| -
|
| - // If there is no Age header, then assume age is zero. GetAgeValue does not
|
| - // modify its out param if the value does not exist.
|
| - TimeDelta age_value;
|
| - GetAgeValue(&age_value);
|
| -
|
| - TimeDelta apparent_age = std::max(TimeDelta(), response_time - date_value);
|
| - TimeDelta corrected_received_age = std::max(apparent_age, age_value);
|
| - TimeDelta response_delay = response_time - request_time;
|
| - TimeDelta corrected_initial_age = corrected_received_age + response_delay;
|
| - TimeDelta resident_time = current_time - response_time;
|
| - TimeDelta current_age = corrected_initial_age + resident_time;
|
| -
|
| - return current_age;
|
| + DCHECK_EQ(TimeDelta(), *out_freshness_lifetime);
|
| + return;
|
| }
|
|
|
| bool HttpResponseHeaders::GetMaxAgeValue(TimeDelta* result) const {
|
|
|