计算资源的有效时间
HttpResponseHeaders::GetFreshnessLifetimes(const Time& response_time) const {
FreshnessLifetimes lifetimes;
if (HasHeaderValue("cache-control", "no-cache") ||
HasHeaderValue("cache-control", "no-store") ||
HasHeaderValue("pragma", "no-cache")) {
return lifetimes;
}
bool must_revalidate = HasHeaderValue("cache-control", "must-revalidate");
lifetimes.staleness =
must_revalidate
? base::TimeDelta()
: GetStaleWhileRevalidateValue().value_or(base::TimeDelta());
std::optional<base::TimeDelta> max_age_value = GetMaxAgeValue();
if (max_age_value) {
lifetimes.freshness = max_age_value.value();
return lifetimes;
}
Time date_value = GetDateValue().value_or(response_time);
std::optional<Time> expires_value = GetExpiresValue();
if (expires_value) {
// The expires value can be a date in the past!
if (expires_value > date_value) {
lifetimes.freshness = expires_value.value() - date_value;
return lifetimes;
}
DCHECK_EQ(base::TimeDelta(), lifetimes.freshness);
return lifetimes;
}
1、对于设置了"cache-control":"no-cache","cache-control":"no-store","pragma":"no-cache"请求头的资源,有效期为0
2、获取资源过期后仍可使用的时间
3、如果存在max-age,有效期为max-age的值
4、如果存在Expires,有效期为Expires - Date
计算资源的已缓存时间
base::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 = GetDateValue().value_or(response_time);
// If there is no Age header, then assume age is zero.
base::TimeDelta age_value = GetAgeValue().value_or(base::TimeDelta());
base::TimeDelta apparent_age =
std::max(base::TimeDelta(), response_time - date_value);
base::TimeDelta response_delay = response_time - request_time;
base::TimeDelta corrected_age_value = age_value + response_delay;
base::TimeDelta corrected_initial_age =
std::max(apparent_age, corrected_age_value);
base::TimeDelta resident_time = current_time - response_time;
base::TimeDelta current_age = corrected_initial_age + resident_time;
return current_age;
}
1、已缓存时间1:响应时间 - Date和1微秒取最大值
2、已缓存时间2:响应时间 - 请求时间 + 缓存服务器已缓存时间
3、(当前时间-响应时间) + (时间1和时间2的较大值)
响应是否过期,确定缓存验证方式
ValidationType HttpResponseHeaders::RequiresValidation(
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;
base::TimeDelta age =
GetCurrentAge(request_time, response_time, current_time);
if (lifetimes.freshness > age)
return VALIDATION_NONE;
if (lifetimes.freshness + lifetimes.staleness > age)
return VALIDATION_ASYNCHRONOUS;
return VALIDATION_SYNCHRONOUS;
}
1、如果资源有效期是0并且过期后能使用时间为0,需要同步验证
2、如果资源的已缓存时间小于资源的有效时间,可以使用缓存
3、如果资源的有效期 + 资源过期还能使用时间 > 资源缓存时间,可以进行异步的验证
4、上面不匹配,需要进行同步验证
- VALIDATION_NONE 代表资源缓存可以使用,不需要进行验证
- VALIDATION_SYNCHRONOUS 代表资源已过期,需要同步在源服务器验证资源是否过期
- VALIDATION_ASYNCHRONOUS 代表资源已过期,但是可以先使用缓存,在验证更新缓存
ValidationType HttpCache::Transaction::RequiresValidation() {
if (!(effective_load_flags_ & LOAD_SKIP_VARY_CHECK) &&
response_.vary_data.is_valid() &&
!response_.vary_data.MatchesRequest(*request_,
*response_.headers.get())) {
vary_mismatch_ = true;
return VALIDATION_SYNCHRONOUS;
}
if (method_ == "PUT" || method_ == "DELETE" || method_ == "PATCH") {
return VALIDATION_SYNCHRONOUS;
}
bool validate_flag = effective_load_flags_ & LOAD_VALIDATE_CACHE;
ValidationType validation_required_by_headers =
validate_flag ? VALIDATION_SYNCHRONOUS
: response_.headers->RequiresValidation(
response_.request_time, response_.response_time,
cache_->clock_->Now());
if (validation_required_by_headers == VALIDATION_ASYNCHRONOUS) {
// Asynchronous revalidation is only supported for GET methods.
if (request_->method != "GET") {
return VALIDATION_SYNCHRONOUS;
}
// If the timeout on the staleness revalidation is set don't hand out
// a resource that hasn't been async validated.
if (!response_.stale_revalidate_timeout.is_null() &&
response_.stale_revalidate_timeout < cache_->clock_->Now()) {
return VALIDATION_SYNCHRONOUS;
}
}
return validation_required_by_headers;
}
1、判断请求的vary是否一致,如果vary不一致,需要进行同步验证
2、PUT、DELETE、PATCH请求,需要进行同步验证
3、如果是异步验证并且请求方法不是get,转为同步验证,如果设置了接受已过期的资源,但是已经超时,转为同步验证
4、使用validation_required_by_headers的值