This commit is contained in:
Mateusz Gruszczyński committed 2026-10-17 11:57:16 +02:00
1 parent 6b937aaf85
commit 87c8393d86
79 files changed
+6727 -297

No files matched your search

+48 -38
View File
@@ -28,7 +28,9 @@
// makes PHP-FPM omit HTTP_HOST, breaking WordPress.
request.headers_mut().insert(HOST, original_host.clone());
let request_method = request.method().clone();
let request_headers = request.headers().clone();
// This branch owns local-origin delivery. Move its headers instead of
// cloning them; the request remains only for exchange/body extensions.
let mut request_headers = std::mem::take(request.headers_mut());
let request_uri = request.uri().clone();
let request_version = request.version();
let public_suffix = request_uri.path_and_query()
@@ -41,32 +43,33 @@
Err(_) => return error(StatusCode::BAD_REQUEST,
"RustProxy: invalid or incomplete request body\n"),
}
} else { request.body().is_end_stream() };
let force_cache = enabled && route.frontend.as_ref().is_some_and(|frontend|
frontend.force_cache.matches(&path, &public_suffix));
let policy = if enabled {
if force_cache {
crate::cache::forced_request_policy(&request_method, &request_headers, empty_body)
} else {
crate::cache::request_policy(
&request_method, &request_headers, empty_body, &path,
request_uri.query().is_some(), cache_settings)
}
} else {
crate::cache::RequestPolicy::Bypass("cache_disabled")
};
} else { enabled && request.body().is_end_stream() };
let cache_plan = cache_plan::CachePlan::new(
(!enabled).then_some("cache_disabled"), cache_settings, &path,
|| route.frontend.as_ref().is_some_and(|frontend|
frontend.force_cache.matches(&path, &public_suffix)),
);
let force_cache = cache_plan.force_cache();
let ignore_cookie = cache_plan.ignore_cookie();
let policy = cache_plan.request_policy(
&request_method, &request_headers, empty_body, &path,
request_uri.query().is_some(), cache_settings,
);
// HEAD can use an existing GET representation but may not fill a cache
// entry with its empty downstream body.
let eligible = enabled && policy.bypass_reason().is_none();
let mut key_headers = request_headers.clone();
let ignore_cookie = !force_cache && cache_settings.ignore_cookie_for_path(&path);
if ignore_cookie { key_headers.remove("cookie"); }
let key_headers = if eligible && ignore_cookie && request_headers.contains_key("cookie") {
let mut headers = request_headers.clone();
headers.remove("cookie");
Some(headers)
} else { None };
let cache_ticket = if eligible {
state.cache.ticket_scoped(state.cache.revision(), scope, context.scheme,
original_host.to_str().unwrap_or(""), &route.id, &public_suffix, &key_headers)
original_host.to_str().unwrap_or(""), &route.id, &public_suffix,
key_headers.as_ref().unwrap_or(&request_headers))
} else { None };
let range = crate::cache::request_range(&request_method, &request_headers);
let if_range = request_headers.get("if-range").cloned();
let range = cache_plan::range_selection(eligible, &request_method, &request_headers);
let if_range = if eligible { request_headers.get("if-range").cloned() } else { None };
let range_requested = !matches!(range, crate::cache::RangeSelection::None);
// Unlike the original Web Server path, retain stale and client-forced
// revalidation candidates. A local 304 can refresh them without replacing
@@ -122,9 +125,14 @@
// 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) =
let (origin_request_headers, revalidation_sent) = if cache_ticket.is_some() {
web_cache_revalidation::web_origin_request_headers(
&request_headers, cached_revalidation.as_ref());
&request_headers, cached_revalidation.as_ref())
} else {
// No cache result can need the original conditionals later. Preserve
// all origin HTTP semantics by handing over the untouched header map.
(std::mem::take(&mut request_headers), false)
};
let started = Instant::now();
let response = crate::web_server::serve(service, request_method.clone(),
origin_request_headers, request_uri, &service_path, static_body,
@@ -181,25 +189,27 @@
state.cache.discard(ticket);
}
}
let origin_headers = response.headers().clone();
let original_plan = crate::cache::plan(response.status(), &origin_headers,
cache_settings, started.elapsed());
// Do not allow a later response-header rewrite to override a private,
// explicitly uncacheable PHP/CGI origin response.
let explicit_origin_policy = origin_headers.contains_key("cache-control")
|| origin_headers.contains_key("expires")
|| origin_headers.contains_key("set-cookie")
|| origin_headers.contains_key("vary");
let origin_safe = !explicit_origin_policy || original_plan.is_some();
let no_transform = crate::transform::no_transform(&origin_headers);
let skip_compression = crate::compression::no_transform(&origin_headers);
let origin_headers = response.headers();
let origin_safe = cache_ticket.is_some() && {
let explicit_origin_policy = origin_headers.contains_key("cache-control")
|| origin_headers.contains_key("expires")
|| origin_headers.contains_key("set-cookie")
|| origin_headers.contains_key("vary");
!explicit_origin_policy || crate::cache::plan(response.status(), origin_headers,
cache_settings, started.elapsed()).is_some()
};
let no_transform = crate::transform::no_transform(origin_headers);
let skip_compression = crate::compression::no_transform(origin_headers);
let origin_validators = crate::transform::OriginValidators {
etag: origin_headers.get("etag").cloned(),
last_modified: origin_headers.get("last-modified").cloned(),
};
if skip_compression || range_requested {
response.extensions_mut().insert(crate::compression::Skip);
}
response.extensions_mut().insert(crate::transform::OriginValidators {
etag: origin_headers.get("etag").cloned(),
last_modified: origin_headers.get("last-modified").cloned(),
});
response.extensions_mut().insert(origin_validators);
apply_response_rules(response.headers_mut(), &snapshot, route.frontend.as_deref(),
Some(route), false);
if response.extensions().get::<crate::pages::PageServed>().is_some() {
@@ -271,4 +281,4 @@
let transformed = response.extensions().get::<crate::transform::Applied>().is_some();
cache_settings.annotate_transformed(response.headers_mut(), transformed);
response
}
}