This commit is contained in:
Mateusz Gruszczyński committed 2026-10-05 19:05:55 +02:00
1 parent ddc5c6593f
commit b9d137eee1
63 files changed
+1232 -445

No files matched your search

+59 -12
View File
@@ -88,6 +88,61 @@ pub struct Transport {
pub tls: bool,
}
#[allow(clippy::too_many_arguments)]
fn log_protocol_error_with_identity(
state: Option<&Arc<App>>,
kind: &'static str,
detail: impl std::fmt::Display,
peer: SocketAddr,
local: SocketAddr,
transport: &'static str,
http_version: &'static str,
status: u16,
authority: Option<String>,
host: Option<String>,
tls_sni: Option<String>,
) {
if let Some(state) = state {
let resolved = state.config.load().resolve_logging_vhost(
local,
matches!(transport, "tls" | "quic"),
None,
authority.as_deref(),
host.as_deref(),
tls_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,
transport,
http_version,
status,
tls_sni,
authority.or(host),
vhost,
matched_by,
);
}
}
fn request_log_identity<B>(request: &Request<B>) -> (Option<String>, Option<String>) {
let authority = request
.uri()
.authority()
.map(|value| value.as_str().to_owned());
let host = request
.headers()
.get(http::header::HOST)
.and_then(|value| value.to_str().ok())
.map(str::to_owned);
(authority, host)
}
fn log_protocol_error(
state: Option<&Arc<App>>,
kind: &'static str,
@@ -99,18 +154,10 @@ fn log_protocol_error(
status: u16,
tls_sni: Option<String>,
) {
if let Some(state) = state {
state.logs.push_protocol_error(
kind,
detail,
peer,
local,
transport,
http_version,
status,
tls_sni,
);
}
log_protocol_error_with_identity(
state, kind, detail, peer, local, transport, http_version, status, None, None,
tls_sni,
);
}
#[derive(Clone)]
pub struct ServerShutdown(pub CancellationToken);
+3 -2
View File
@@ -5,6 +5,7 @@ async fn http2_connection<I>(
peer: SocketAddr,
local: SocketAddr,
transport: Transport,
tls_sni: Option<String>,
extended_connect: bool,
frontend_state: Option<Arc<App>>,
lease: Arc<ConnectionLease>,
@@ -69,7 +70,7 @@ async fn http2_connection<I>(
if let Err(error) = result {
log_protocol_error(
frontend_state.as_ref(), "http2_connection_error", &error, peer, local,
if transport.tls { "tls" } else { "tcp" }, "2", 0, None,
if transport.tls { "tls" } else { "tcp" }, "2", 0, tls_sni.clone(),
);
tracing::debug!(%error, "HTTP/2 connection closed");
}
@@ -108,7 +109,7 @@ async fn http2_connection<I>(
if transport.tls { "tls" } else { "tcp" },
"2",
0,
None,
tls_sni.clone(),
);
tracing::debug!(?cause, %error, "HTTP/2 graceful shutdown ended with protocol error")
}
+2
View File
@@ -100,7 +100,9 @@ mod h2c_tests {
peer,
local,
Transport { tls: false },
None,
false,
None,
lease,
server_stop,
Duration::from_secs(5),
+16 -3
View File
@@ -125,6 +125,7 @@ async fn serve_inner(
peer,
local,
Transport { tls: true },
host.clone(),
h2,
extended_connect,
false,
@@ -168,6 +169,7 @@ async fn serve_inner(
peer,
local,
Transport { tls: false },
None,
false,
false,
false,
@@ -197,6 +199,7 @@ async fn serve_inner(
peer,
local,
Transport { tls: true },
None,
h2,
false,
false,
@@ -245,6 +248,7 @@ async fn serve_inner(
peer,
local,
Transport { tls: false },
None,
prior_h2,
extended_connect,
h2c && !prior_h2,
@@ -276,6 +280,7 @@ async fn connection<I>(
peer: SocketAddr,
local: SocketAddr,
transport: Transport,
tls_sni: Option<String>,
h2: bool,
extended_connect: bool,
h2c_upgrade: bool,
@@ -294,6 +299,7 @@ async fn connection<I>(
peer,
local,
transport,
tls_sni.clone(),
extended_connect,
frontend_state.clone(),
lease,
@@ -322,7 +328,8 @@ async fn connection<I>(
if h2c_attempt(&request) {
if !h2c_upgrade {
log_protocol_error(
let (authority, host) = request_log_identity(&request);
log_protocol_error_with_identity(
upgrade_state.as_ref(),
"h2c_upgrade_rejected",
"h2c upgrade is disabled on this listener",
@@ -331,6 +338,8 @@ async fn connection<I>(
"tcp",
"1.1",
400,
authority,
host,
None,
);
return Ok::<_, Infallible>(
@@ -344,7 +353,8 @@ async fn connection<I>(
let injected_headers = match h2_headers_frame(&request) {
Ok(frame) => frame,
Err(message) => {
log_protocol_error(
let (authority, host) = request_log_identity(&request);
log_protocol_error_with_identity(
upgrade_state.as_ref(),
"h2c_upgrade_invalid",
message,
@@ -353,6 +363,8 @@ async fn connection<I>(
"tcp",
"1.1",
400,
authority,
host,
None,
);
return Ok::<_, Infallible>(
@@ -389,6 +401,7 @@ async fn connection<I>(
peer,
local,
Transport { tls: false },
None,
extended_connect,
upgrade_state_for_task.clone(),
upgrade_lease,
@@ -448,7 +461,7 @@ async fn connection<I>(
if let Err(error) = result {
log_protocol_error(
frontend_state.as_ref(), "http1_connection_error", &error, peer, local,
if transport.tls { "tls" } else { "tcp" }, "1.1", 400, None,
if transport.tls { "tls" } else { "tcp" }, "1.1", 400, tls_sni.clone(),
);
tracing::debug!(%error, "HTTP/1 connection closed");
}