v0.25.1
This commit is contained in:
1 parent
87e571c170
commit
fa7abc9e53
308 files changed
+49746
-50237
No files matched your search
@@ -0,0 +1,197 @@
|
||||
{
|
||||
// A backend 304 validates the stored representation. Merge the new
|
||||
// metadata into the cached object and answer the client's original
|
||||
// condition locally, just like Varnish's conditional delivery path.
|
||||
if response.status() == StatusCode::NOT_MODIFIED && revalidation_sent {
|
||||
if let (Some(ticket), Some(cached)) =
|
||||
(cache_ticket.as_ref(), cached_revalidation.as_ref())
|
||||
{
|
||||
let merged = cached.merge_validation_headers(response.headers());
|
||||
let client_not_modified =
|
||||
crate::cache::conditional_not_modified(&client_conditionals, &merged);
|
||||
let mut revalidated = if let Some(mut hit) = state.cache.publish_revalidated(
|
||||
ticket.clone(),
|
||||
cached,
|
||||
merged.clone(),
|
||||
&origin_validation_headers,
|
||||
cache_settings,
|
||||
upstream_started.elapsed(),
|
||||
) {
|
||||
if !client_not_modified {
|
||||
if let crate::cache::RangeSelection::Single(range) = range_selection {
|
||||
hit = hit.apply_range(range, if_range.as_ref());
|
||||
}
|
||||
}
|
||||
let resident_age = hit.resident_age_seconds;
|
||||
let mut response = hit.response;
|
||||
cache_settings.annotate_reason(
|
||||
response.headers_mut(),
|
||||
"HIT",
|
||||
hit.hits,
|
||||
hit.remaining_ttl,
|
||||
"cache_revalidated",
|
||||
);
|
||||
cache_settings
|
||||
.annotate_transformed(response.headers_mut(), hit.transformed);
|
||||
if hit.transformed {
|
||||
state.transform_metrics.record_cache_hit(scope);
|
||||
}
|
||||
cache_settings.annotate_resident_age(response.headers_mut(), resident_age);
|
||||
Some(response)
|
||||
} else if state.cache.ticket_current(ticket) {
|
||||
// The validation succeeded but the refreshed representation is no
|
||||
// longer eligible for shared storage (for example new no-store).
|
||||
// Serve it once, then discard the stored copy.
|
||||
state.cache.discard(ticket);
|
||||
let mut response = if !client_not_modified {
|
||||
if let crate::cache::RangeSelection::Single(range) = range_selection {
|
||||
cached.response_with_range(merged, range, if_range.as_ref())
|
||||
} else {
|
||||
cached.response(merged)
|
||||
}
|
||||
} else {
|
||||
cached.response(merged)
|
||||
};
|
||||
cache_settings.annotate_reason(
|
||||
response.headers_mut(),
|
||||
"HIT",
|
||||
0,
|
||||
0,
|
||||
"cache_revalidated_uncached",
|
||||
);
|
||||
cache_settings
|
||||
.annotate_transformed(response.headers_mut(), cached.transformed());
|
||||
if cached.transformed() {
|
||||
state.transform_metrics.record_cache_hit(scope);
|
||||
}
|
||||
Some(response)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(mut revalidated) = revalidated.take() {
|
||||
if client_not_modified {
|
||||
revalidated = crate::cache::make_not_modified(revalidated);
|
||||
}
|
||||
revalidated.extensions_mut().insert(ResponseRulesApplied);
|
||||
revalidated
|
||||
.extensions_mut()
|
||||
.insert(OriginTiming(upstream_started.elapsed()));
|
||||
revalidated
|
||||
.extensions_mut()
|
||||
.insert(OriginBackend(active_backend.id.clone()));
|
||||
if let Some(exchange) = &exchange {
|
||||
exchange.cache_status.store(1, Ordering::Relaxed);
|
||||
*exchange
|
||||
.cache_reason
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner()) = "cache_revalidated";
|
||||
}
|
||||
state.cache.record(scope, &host, "HIT", "cache_revalidated");
|
||||
return revalidated;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Both origin and transformed policies must be cacheable; hiding a
|
||||
// Set-Cookie/private header never authorizes storage of private content.
|
||||
let transformed_plan =
|
||||
if ignore_static_cookie && crate::cache::varies_on(response.headers(), "cookie") {
|
||||
None
|
||||
} else {
|
||||
crate::cache::plan(
|
||||
response.status(),
|
||||
response.headers(),
|
||||
cache_settings,
|
||||
upstream_started.elapsed(),
|
||||
)
|
||||
};
|
||||
let outcome = if cache_ticket.is_some() {
|
||||
"MISS"
|
||||
} else {
|
||||
"BYPASS"
|
||||
};
|
||||
let reason = effective_reason
|
||||
.or(origin_reason)
|
||||
.or(revalidation_reason)
|
||||
.or(freshness_revalidation_reason)
|
||||
.unwrap_or_else(|| {
|
||||
if cache_ticket.is_some() && transformed_plan.is_none() {
|
||||
"response_headers_policy"
|
||||
} else if cache_ticket.is_some() {
|
||||
"cache_miss"
|
||||
} else {
|
||||
"configuration_changed"
|
||||
}
|
||||
});
|
||||
if outcome == "MISS" && !miss_recorded {
|
||||
state.cache.record(scope, &host, "MISS", reason);
|
||||
if let Some(exchange) = &exchange {
|
||||
exchange.cache_status.store(2, Ordering::Relaxed);
|
||||
}
|
||||
} else if outcome == "MISS" && reason != "cache_miss" {
|
||||
state.cache.record_reason(scope, &host, reason);
|
||||
}
|
||||
if let Some(exchange) = &exchange {
|
||||
*exchange
|
||||
.cache_reason
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner()) = reason;
|
||||
}
|
||||
if let (Some(ticket), Some(plan), Some(transformed)) =
|
||||
(cache_ticket, origin_plan, transformed_plan)
|
||||
{
|
||||
let plan = if response
|
||||
.extensions()
|
||||
.get::<crate::transform::CanonicalIdentity>()
|
||||
.is_some()
|
||||
{
|
||||
plan.without_vary("accept-encoding")
|
||||
} else {
|
||||
plan
|
||||
};
|
||||
let plan = plan.restrict(transformed);
|
||||
let proactive_remaining_ttl = plan.remaining_ttl();
|
||||
let proactive_ticket = ticket.clone();
|
||||
response = state.cache.wrap_with_fill(
|
||||
response,
|
||||
ticket,
|
||||
plan,
|
||||
cache_settings,
|
||||
fill_leader.take(),
|
||||
);
|
||||
if cache_settings.proactive_refresh_enabled && proactive_remaining_ttl > 0 {
|
||||
schedule_proactive_refresh(
|
||||
CacheRefreshContext {
|
||||
state: state.clone(),
|
||||
snapshot: snapshot.clone(),
|
||||
backend: active_backend.clone(),
|
||||
cache_settings: cache_settings.clone(),
|
||||
transform: transform_settings.cloned(),
|
||||
uri: active_uri.clone(),
|
||||
public_suffix: public_suffix.clone(),
|
||||
host: host.clone(),
|
||||
path: path.clone(),
|
||||
scope: scope.to_owned(),
|
||||
timeout: frontend
|
||||
.and_then(|frontend| frontend.proxy_timeouts.response_header_timeout())
|
||||
.unwrap_or(state.header_timeout),
|
||||
local: local.0,
|
||||
tls,
|
||||
base_headers: proactive_base_headers.clone(),
|
||||
},
|
||||
proactive_ticket,
|
||||
proactive_remaining_ttl,
|
||||
);
|
||||
}
|
||||
}
|
||||
let transformed = response
|
||||
.extensions()
|
||||
.get::<crate::transform::Applied>()
|
||||
.is_some()
|
||||
|| response
|
||||
.extensions()
|
||||
.get::<crate::transform::CachedTransformed>()
|
||||
.is_some();
|
||||
cache_settings.annotate_reason(response.headers_mut(), outcome, 0, 0, reason);
|
||||
cache_settings.annotate_transformed(response.headers_mut(), transformed);
|
||||
response
|
||||
}
|
||||
Reference in new issue
Block a user