impl Cache { pub async fn get_tiered(&self, ticket: &Ticket, settings: &Settings) -> Option { if let Some(hit) = self.get_hot(ticket, false) { return Some(hit); } if let Some(hit) = self.get_cold(ticket, settings).await { return Some(hit); } self.counters.misses.fetch_add(1, Ordering::Relaxed); None } pub fn publish_revalidated( &self, ticket: Ticket, cached: &Revalidation, mut headers: HeaderMap, validation_headers: &HeaderMap, settings: &Settings, response_delay: Duration, ) -> Option { let plan = plan(StatusCode::OK, &headers, settings, response_delay)?; if cached.body.len() > settings.max_object_bytes { return None; } if !headers.contains_key("date") { if let Ok(value) = httpdate::fmt_http_date(SystemTime::now()).parse() { headers.insert("date", value); } } for name in [ "x-request-id", "x-cache", "x-cache-hits", "x-cache-status", "x-cache-reason", "cache-status", ] { headers.remove(name); } let hits = cached.hits.saturating_add(1); let age = plan.initial_age.as_secs(); let remaining_ttl = plan.ttl.saturating_sub(age); let vary = plan.vary.clone(); let tags = cache_tags(&headers); let origin_etag = validation_headers .get("etag") .cloned() .or_else(|| cached.origin_etag.clone()); let origin_last_modified = validation_headers .get("last-modified") .cloned() .or_else(|| cached.origin_last_modified.clone()); let cost = hot_entry_cost( cached.body_allocated, &headers, &vary, &ticket.scope, &ticket.scheme, &ticket.authority, &ticket.domain, &ticket.path, &ticket.target, &tags, origin_etag.as_ref(), origin_last_modified.as_ref(), ); let storage_key = variant_key(&ticket.key, &vary, &ticket.request_headers); let resident_age = cached.resident_age_at_lookup.saturating_add(response_delay); let entry = Entry { base_key: ticket.key, vary, scope: ticket.scope.clone(), scheme: ticket.scheme.clone(), authority: ticket.authority.clone(), domain: ticket.domain.clone(), path: ticket.path.clone(), target: ticket.target.clone(), tags, created_at: ticket.created_at, headers: headers.clone(), body: cached.body.clone(), body_allocated: cached.body_allocated, received: plan.received, last_access: Instant::now(), resident_since: Instant::now(), resident_age_base: resident_age, initial_age: plan.initial_age, ttl: plan.ttl, stale_while_revalidate: plan.stale_while_revalidate, stale_if_error: plan.stale_if_error, must_revalidate: plan.must_revalidate, proxy_revalidate: plan.proxy_revalidate, origin_etag, origin_last_modified, cost, sequence: 0, hits, transformed: cached.transformed, skip_compression: cached.skip_compression, requires_revalidation: plan.requires_revalidation, }; if !self.insert(ticket, entry, settings) { return None; } if cached.storage_key != storage_key { self.discard_storage_key(&cached.storage_key); } self.counters.hits.fetch_add(1, Ordering::Relaxed); let mut response = cached.response(headers); response.headers_mut().insert( "age", HeaderValue::from_str(&age.to_string()).expect("integer header"), ); Some(Hit { response, body: cached.body.clone(), hits, transformed: cached.transformed, remaining_ttl, resident_age_seconds: resident_age.as_secs(), stale: false, background_revalidate: false, }) } pub fn wrap( self: &Arc, response: Response, ticket: Ticket, plan: Plan, settings: &Settings, ) -> Response { self.wrap_with_fill(response, ticket, plan, settings, None) } pub fn wrap_with_fill( self: &Arc, response: Response, ticket: Ticket, plan: Plan, settings: &Settings, fill_leader: Option, ) -> Response { let fill_size = plan.expected_length.unwrap_or(settings.max_object_bytes); let permits = if fill_size > 64 * 1024 * 1024 { FILL_SLOTS as u32 } else if fill_size > 16 * 1024 * 1024 { 4 } else if fill_size > 4 * 1024 * 1024 { 2 } else { 1 }; let permit = self.fills.clone().try_acquire_many_owned(permits); let Ok(permit) = permit else { self.counters.rejected_fills.fetch_add(1, Ordering::Relaxed); return response; }; let (parts, body) = response.into_parts(); let headers = parts.headers.clone(); let origin_validators = parts .extensions .get::() .cloned(); let origin_etag = match origin_validators.as_ref() { Some(validators) => validators.etag.clone(), None => headers.get("etag").cloned(), }; let origin_last_modified = match origin_validators.as_ref() { Some(validators) => validators.last_modified.clone(), None => headers.get("last-modified").cloned(), }; let transformed = parts.extensions.get::().is_some(); // A transformed, fully buffered body normally arrives as one owned // frame. Do not allocate a second fill buffer before inspecting it. let initial_capacity = if transformed { 0 } else { fill_size.min(64 * 1024) }; let Some(mut fill_gauge) = FillGauge::new(self.clone(), initial_capacity, settings) else { self.counters.rejected_fills.fetch_add(1, Ordering::Relaxed); self.record_reason(&ticket.scope, &ticket.domain, "hot_memory_pressure"); return Response::from_parts(parts, body); }; let data = Vec::with_capacity(initial_capacity); let actual_capacity = data.capacity(); if actual_capacity > initial_capacity && !fill_gauge.grow(actual_capacity - initial_capacity, settings) { self.counters.rejected_fills.fetch_add(1, Ordering::Relaxed); self.record_reason(&ticket.scope, &ticket.domain, "fill_allocator_overshoot"); return Response::from_parts(parts, body); } let candidate = Candidate { cache: self.clone(), ticket, plan, headers, data, shared: None, shared_allocated: 0, fill_gauge, settings: settings.clone(), skip_compression: parts.extensions.get::().is_some(), origin_etag, origin_last_modified, transformed, _permit: permit, _fill_leader: fill_leader, }; // A genuinely finished body (including an empty local file) may never // be polled by Hyper. EOS is the proof here, not Content-Length alone; // finish still enforces expected length, privacy and ticket validity. if body.is_end_stream() { candidate.finish(); return Response::from_parts(parts, body); } Response::from_parts( parts, Body::new(FillBody { inner: body, candidate: Some(candidate), done: false, }), ) } }