0.34.6_repo_cleanup

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-22 09:31:15 +02:00
1 parent ce1a90397c
commit 133d2f0f91
273 files changed
+5969 -6926

No files matched your search

-37
View File
@@ -1,6 +1,4 @@
{
// Web Server is an origin just like a reverse-proxy backend. It must pass
// through the same vhost cache policy, transform stage and response rules.
if handshake.is_some() {
return error(StatusCode::BAD_REQUEST,
"RustProxy: Web Server source does not support WebSocket upgrades\n");
@@ -30,20 +28,13 @@
exchange.set_cache_enabled(enabled);
exchange.set_transform_enabled(transform_settings.is_some_and(|settings| settings.enabled));
}
// The authority is already validated by effective_host. HTTP/2 and HTTP/3
// requests commonly have :authority but no Host field, which otherwise
// makes PHP-FPM omit HTTP_HOST, breaking WordPress.
request.headers_mut().insert(HOST, original_host.clone());
let request_method = request.method().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()
.map(|item| item.as_str()).unwrap_or("/").to_owned();
// H2/H3 may expose an unknown-length empty stream before its final frame.
// Reuse the bounded probe that preserves any nonempty streaming body.
let empty_body = if enabled && (request_method == Method::GET || request_method == Method::HEAD) {
match empty_for_cache(&mut request).await {
Ok(empty) => empty,
@@ -62,8 +53,6 @@
&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 key_headers = if eligible && ignore_cookie && request_headers.contains_key("cookie") {
let mut headers = request_headers.clone();
@@ -79,9 +68,6 @@
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
// 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 };
@@ -91,10 +77,7 @@
if let Some(ticket) = &cache_ticket {
if !needs_validation {
if let Some(mut hit) = state.cache.get_tiered(ticket, cache_settings).await {
// Filesystem/PHP does not have the reverse-proxy background
// revalidator. Refresh stale representations synchronously.
if hit.stale {
// Fall through and fetch from the local origin.
} else {
let conditional = crate::cache::conditional_not_modified(
&request_headers, hit.response.headers());
@@ -130,15 +113,11 @@
return error(StatusCode::GATEWAY_TIMEOUT,
"RustProxy: only-if-cached request has no usable Web Server representation\n");
}
// 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) = if cache_ticket.is_some() {
web_cache_revalidation::web_origin_request_headers(
&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();
@@ -180,8 +159,6 @@
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");
}
@@ -189,16 +166,10 @@
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);
}
}
// Do not allow a later response-header rewrite to override a private,
// explicitly uncacheable PHP/CGI origin response.
let origin_headers = response.headers();
let origin_safe = cache_ticket.is_some() && {
let explicit_origin_policy = origin_headers.contains_key("cache-control")
@@ -221,14 +192,11 @@
apply_response_rules(response.headers_mut(), &snapshot, route.frontend.as_deref(),
Some(route), false);
if response.extensions().get::<crate::pages::PageServed>().is_some() {
// A vhost header rule must not make a replaced error cacheable.
response.headers_mut().insert("cache-control", HeaderValue::from_static("no-store"));
}
response.extensions_mut().insert(ResponseRulesApplied);
response.extensions_mut().insert(StaticSourceResponse);
// Cache representation must reflect vhost response rules and transforms,
// not solely the Web Service's Cache-Control header.
let origin_eligible_plan = if origin_safe
&& !(ignore_cookie && crate::cache::varies_on(response.headers(), "cookie"))
{
@@ -288,11 +256,6 @@
cache_settings.annotate_reason(response.headers_mut(), outcome, 0, 0, reason);
let transformed = response.extensions().get::<crate::transform::Applied>().is_some();
cache_settings.annotate_transformed(response.headers_mut(), transformed);
// Register only AFTER the vhost response policy, cache and transformation
// decisions are final. Never feed synthetic transport placeholders into
// cache, compression or the transformation engine. The ordinary body
// remains the fallback on every other protocol/response and when the
// per-connection bridge has no capacity.
#[cfg(target_os = "linux")]
if !enabled && identity_request && request_method == Method::GET
&& !transform_settings.is_some_and(|settings| settings.enabled)