fix(rustproxy-http): prevent premature idle timeouts during streamed HTTP responses and ensure TLS close_notify is sent on dropped connections

This commit is contained in:
2026-03-16 08:58:11 +00:00
parent 0475e6b442
commit b3d4949225
7 changed files with 146 additions and 4 deletions

View File

@@ -39,6 +39,10 @@ use crate::upstream_selector::UpstreamSelector;
struct ConnActivity {
last_activity: Arc<AtomicU64>,
start: std::time::Instant,
/// Active-request counter from handle_io's idle watchdog. When set, CountingBody
/// increments on creation and decrements on Drop, keeping the watchdog aware that
/// a response body is still streaming after the request handler has returned.
active_requests: Option<Arc<AtomicU64>>,
}
/// Default upstream connect timeout (30 seconds).
@@ -302,7 +306,7 @@ impl HttpProxyService {
let cn = cancel_inner.clone();
let la = Arc::clone(&la_inner);
let st = start;
let ca = ConnActivity { last_activity: Arc::clone(&la_inner), start };
let ca = ConnActivity { last_activity: Arc::clone(&la_inner), start, active_requests: Some(Arc::clone(&ar_inner)) };
async move {
let result = svc.handle_request(req, peer, port, cn, ca).await;
// Mark request end — update activity timestamp before guard drops
@@ -1624,6 +1628,15 @@ impl HttpProxyService {
Direction::Out,
).with_connection_activity(Arc::clone(&conn_activity.last_activity), conn_activity.start);
// Keep active_requests > 0 while the response body streams, so the idle
// watchdog doesn't kill the connection mid-transfer (e.g. during git fetch).
// CountingBody increments on creation and decrements on Drop.
let counting_body = if let Some(ref ar) = conn_activity.active_requests {
counting_body.with_active_requests(Arc::clone(ar))
} else {
counting_body
};
let body: BoxBody<Bytes, hyper::Error> = BoxBody::new(counting_body);
Ok(response.body(body).unwrap())