WEB + Apple iOS Fallback Cache fixed

Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
Alexey
2026-08-23 18:05:12 +03:00
parent 1bd85535f4
commit 3188c8e417
2 changed files with 40 additions and 1 deletions
+10 -1
View File
@@ -17,6 +17,7 @@ use crate::config::{WebRuntimeDecoy, WebRuntimeVhost};
use crate::web::manager::WebProcessRuntime;
/// Serves the configured ordinary site after optionally removing carrier material.
/// Transport-sanitized static fallbacks remain uncacheable after query removal.
pub(super) async fn serve_decoy<B>(
mut request: Request<B>,
vhost: Arc<WebRuntimeVhost>,
@@ -41,7 +42,15 @@ where
};
let request = Request::from_parts(parts, body);
match &vhost.decoy {
WebRuntimeDecoy::StaticDirectory(site) => serve_static(request, site),
WebRuntimeDecoy::StaticDirectory(site) => {
let mut response = serve_static(request, site);
if sanitize_transport {
response
.headers_mut()
.insert(header::CACHE_CONTROL, HeaderValue::from_static("no-store"));
}
response
}
WebRuntimeDecoy::HttpUpstream { addr, authority } => {
proxy_to_upstream(
request,
+30
View File
@@ -209,6 +209,36 @@ async fn https_carrier_bootstraps_and_closes_one_session() {
replacement.stop_background_tasks().await;
}
#[tokio::test]
async fn rejected_bridge_bootstrap_falls_back_to_uncacheable_static_index() {
let capability = [15u8; 32];
let generation = test_runtime_generation(1, runtime_config(capability, WebCarrier::Https));
let active_runtime = Arc::new(ArcSwap::from(Arc::clone(&generation)));
let runtime = WebProcessRuntime::start(active_runtime);
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let encoded = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(capability);
let bridge_request = || {
format!(
"GET /?bridge={encoded} HTTP/1.1\r\nHost: proxy.example.com\r\nX-Forwarded-For: 192.0.2.10\r\nConnection: close\r\n\r\n"
)
.into_bytes()
};
let first_response = request(&listener, &runtime, bridge_request()).await;
let (_, first_body) = split_response(&first_response);
assert!(first_body.windows(11).any(|value| value == b"bootstrap='"));
let fallback_response = request(&listener, &runtime, bridge_request()).await;
let (fallback_headers, fallback_body) = split_response(&fallback_response);
assert!(fallback_headers.starts_with(b"HTTP/1.1 200"));
assert_eq!(response_header(fallback_headers, "cache-control"), "no-store");
assert_eq!(fallback_body, b"<!doctype html><title>decoy</title>");
runtime.shutdown().await;
generation.stop_sessions().await;
generation.stop_background_tasks().await;
}
#[tokio::test]
async fn bootstrap_survives_client_address_family_change() {
let capability = [8u8; 32];