diff --git a/CHANGELOG.md b/CHANGELOG.md index e43b2cf8..4639fdfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If - Tasks cannot be deleted in OSS builds. - Directory: Per-domain external directory resolution fails. - DNS updater: Keep external `TXT` records when updating RRSet. +- HTTP: Reject requests from blocked IPs when `Keep-Alive` is enabled. ## [0.16.6] - 2026-05-20 diff --git a/crates/http/src/request.rs b/crates/http/src/request.rs index b405b0f8..37b5f31e 100644 --- a/crates/http/src/request.rs +++ b/crates/http/src/request.rs @@ -699,22 +699,6 @@ async fn handle_session(inner: Arc, session: SessionDat .and_then(|h| h.parse::().ok()) }) { - // Check if the forwarded IP has been blocked - if server.is_ip_blocked(forwarded_for) { - trc::event!( - Security(trc::SecurityEvent::IpBlocked), - ListenerId = instance.id.clone(), - RemoteIp = forwarded_for, - SpanId = session.session_id, - ); - - return Ok::<_, hyper::Error>( - JsonProblemResponse(StatusCode::FORBIDDEN) - .into_http_response() - .build(), - ); - } - trc::event!( Http(trc::HttpEvent::RequestUrl), SpanId = session.session_id, @@ -731,6 +715,22 @@ async fn handle_session(inner: Arc, session: SessionDat session.remote_ip }; + // Check if the remote IP has been blocked + if server.is_ip_blocked(remote_ip) { + trc::event!( + Security(trc::SecurityEvent::IpBlocked), + ListenerId = instance.id.clone(), + RemoteIp = remote_ip, + SpanId = session.session_id, + ); + + return Ok::<_, hyper::Error>( + JsonProblemResponse(StatusCode::FORBIDDEN) + .into_http_response() + .build(), + ); + } + // Parse HTTP request let response = match Box::pin(server.parse_http_request( req,