struct Lease { _permit: OwnedSemaphorePermit, metrics: Arc, } impl Drop for Lease { fn drop(&mut self) { self.metrics .http3_active_connections .fetch_sub(1, Ordering::Relaxed); self.metrics .active_connections .fetch_sub(1, Ordering::Relaxed); } } #[allow(clippy::too_many_arguments)] fn log_protocol_error( state: &App, kind: &'static str, detail: impl std::fmt::Display, peer: SocketAddr, local: SocketAddr, status: u16, authority: Option, host: Option, sni: Option, ) { let resolved = state.config.load().resolve_logging_vhost( local, true, None, authority.as_deref(), host.as_deref(), sni.as_deref(), ); let (vhost, matched_by) = resolved .map(|resolved| (Some(resolved.vhost), resolved.matched_by)) .unwrap_or((None, "none")); state.logs.push_protocol_error_attributed( kind, detail, peer, local, "quic", "3", status, sni, authority.or(host), vhost, matched_by, ); } /// Service-level breadcrumbs for a full HTTP/3 GET / navigation. User-provided /// query strings, headers and error details must not reach this diagnostic. #[allow(clippy::too_many_arguments)] fn log_root_navigation( stage: &'static str, peer: SocketAddr, local: SocketAddr, sni: &Option, stream_id: &str, phase: &'static str, response_status: u16, body_bytes_sent: u64, cancelled: bool, ) { match stage { "started" => tracing::info!( peer=%peer, local=%local, sni=?sni, stream_id=%stream_id, method="GET", path="/", "http3_navigation_started" ), "complete" => tracing::info!( peer=%peer, local=%local, sni=?sni, stream_id=%stream_id, method="GET", path="/", response_status, body_bytes_sent, "http3_navigation_complete" ), "interrupted" => tracing::warn!( peer=%peer, local=%local, sni=?sni, stream_id=%stream_id, method="GET", path="/", phase, response_status, body_bytes_sent, cancelled, "http3_navigation_interrupted" ), _ => {} } } fn log_h3_response_complete(peer: SocketAddr, stream_id: &str, response_status: u16, body_bytes_sent: u64) { tracing::debug!( peer=%peer, stream_id=%stream_id, response_status, body_bytes_sent, "HTTP/3 response completed" ); }