v0.32.2
This commit is contained in:
1 parent
101df02a5f
commit
bb025dcf44
27 files changed
+541
-85
No files matched your search
@@ -68,7 +68,15 @@
|
||||
let range = crate::cache::request_range(&request_method, &request_headers);
|
||||
let if_range = request_headers.get("if-range").cloned();
|
||||
let range_requested = !matches!(range, crate::cache::RangeSelection::None);
|
||||
let needs_validation = policy.revalidation_reason().is_some();
|
||||
// Unlike the original Web Server path, retain stale and client-forced
|
||||
// revalidation candidates. A local 304 can refresh them without replacing
|
||||
// the cached body or resetting X-Cache-Hits (same as Reverse Proxy).
|
||||
let cached_revalidation = if let Some(ticket) = cache_ticket.as_ref() {
|
||||
state.cache.revalidation_tiered(ticket).await
|
||||
} else { None };
|
||||
let needs_validation = policy.revalidation_reason().is_some()
|
||||
|| cached_revalidation.as_ref().is_some_and(|cached|
|
||||
!cached.reusable_for_request(&request_headers));
|
||||
if let Some(ticket) = &cache_ticket {
|
||||
if !needs_validation {
|
||||
if let Some(mut hit) = state.cache.get_tiered(ticket, cache_settings).await {
|
||||
@@ -114,9 +122,12 @@
|
||||
// Neither the Request nor the streaming Body is held across a borrowed
|
||||
// await: the filesystem/PHP source owns the body for its full lifetime.
|
||||
let static_body = std::mem::replace(request.body_mut(), Body::empty());
|
||||
let (origin_request_headers, revalidation_sent) =
|
||||
web_cache_revalidation::web_origin_request_headers(
|
||||
&request_headers, cached_revalidation.as_ref());
|
||||
let started = Instant::now();
|
||||
let response = crate::web_server::serve(service, request_method.clone(),
|
||||
request_headers.clone(), request_uri, &service_path, static_body,
|
||||
origin_request_headers, request_uri, &service_path, static_body,
|
||||
crate::web_server::RequestContext {
|
||||
client_ip: context.client_ip,
|
||||
client_port: Some(peer.0.port()),
|
||||
@@ -131,6 +142,45 @@
|
||||
).await { return fallback; }
|
||||
|
||||
let mut response = intercept_route_origin_error(response, route, &snapshot);
|
||||
if revalidation_sent && response.status() == StatusCode::NOT_MODIFIED {
|
||||
if let (Some(ticket), Some(cached)) =
|
||||
(cache_ticket.as_ref(), cached_revalidation.as_ref())
|
||||
{
|
||||
let revalidated = web_cache_revalidation::finish_web_revalidation(
|
||||
&state.cache, ticket, cached, response.headers(), cache_settings,
|
||||
started.elapsed(), &request_headers, &request_method,
|
||||
ignore_cookie, force_cache,
|
||||
|headers| apply_response_rules(headers, &snapshot,
|
||||
route.frontend.as_deref(), Some(route), false),
|
||||
);
|
||||
if let Some(mut hit) = revalidated {
|
||||
state.cache.record(scope, &host, "HIT", hit.reason);
|
||||
if hit.transformed { state.transform_metrics.record_cache_hit(scope); }
|
||||
if let Some(exchange) = request.extensions().get::<Arc<Exchange>>() {
|
||||
exchange.cache_status.store(1, Ordering::Relaxed);
|
||||
*exchange.cache_reason.lock().unwrap_or_else(|e| e.into_inner()) = hit.reason;
|
||||
}
|
||||
hit.response.extensions_mut().insert(ResponseRulesApplied);
|
||||
hit.response.extensions_mut().insert(StaticSourceResponse);
|
||||
return intercept_route_origin_error(hit.response, route, &snapshot);
|
||||
}
|
||||
// A simultaneous PURGE/config change invalidated the ticket. Do
|
||||
// not accidentally return an origin 304 without a reusable body.
|
||||
return error(StatusCode::SERVICE_UNAVAILABLE,
|
||||
"RustProxy: Web Server cache entry invalidated during revalidation\n");
|
||||
}
|
||||
}
|
||||
if cached_revalidation.is_some() && response.status() != StatusCode::NOT_MODIFIED
|
||||
&& response.status().as_u16() < 500
|
||||
{
|
||||
// A changed response (including a 206, 404 or an uncacheable 200)
|
||||
// supersedes the old object. Also discard when the old entry has no
|
||||
// validators and therefore must be fetched unconditionally. A complete
|
||||
// cacheable GET below can refill the entry.
|
||||
if let Some(ticket) = cache_ticket.as_ref() {
|
||||
state.cache.discard(ticket);
|
||||
}
|
||||
}
|
||||
let origin_headers = response.headers().clone();
|
||||
let original_plan = crate::cache::plan(response.status(), &origin_headers,
|
||||
cache_settings, started.elapsed());
|
||||
|
||||
Reference in new issue
Block a user