fix(protocol-cache): Include requested_host in protocol detection cache key to avoid cache oscillation when multiple frontend domains share the same backend
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
//! Bounded, TTL-based protocol detection cache for HTTP/2 auto-detection.
|
||||
//!
|
||||
//! Caches the ALPN-negotiated protocol (H1 or H2) per backend endpoint (host:port).
|
||||
//! Prevents repeated ALPN probes for backends whose protocol is already known.
|
||||
//! Caches the ALPN-negotiated protocol (H1 or H2) per backend endpoint and requested
|
||||
//! domain (host:port + requested_host). This prevents cache oscillation when multiple
|
||||
//! frontend domains share the same backend but differ in HTTP/2 support.
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
@@ -27,11 +28,14 @@ pub enum DetectedProtocol {
|
||||
H2,
|
||||
}
|
||||
|
||||
/// Key for the protocol cache: (host, port).
|
||||
/// Key for the protocol cache: (host, port, requested_host).
|
||||
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct ProtocolCacheKey {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
/// The incoming request's domain (Host header / :authority).
|
||||
/// Distinguishes protocol detection when multiple domains share the same backend.
|
||||
pub requested_host: Option<String>,
|
||||
}
|
||||
|
||||
/// A cached protocol detection result with a timestamp.
|
||||
@@ -73,7 +77,7 @@ impl ProtocolCache {
|
||||
pub fn get(&self, key: &ProtocolCacheKey) -> Option<DetectedProtocol> {
|
||||
let entry = self.cache.get(key)?;
|
||||
if entry.detected_at.elapsed() < PROTOCOL_CACHE_TTL {
|
||||
debug!("Protocol cache hit: {:?} for {}:{}", entry.protocol, key.host, key.port);
|
||||
debug!("Protocol cache hit: {:?} for {}:{} (requested: {:?})", entry.protocol, key.host, key.port, key.requested_host);
|
||||
Some(entry.protocol)
|
||||
} else {
|
||||
// Expired — remove and return None to trigger re-probe
|
||||
|
||||
Reference in New Issue
Block a user