diff --git a/apps/monitor/src/runner.rs b/apps/monitor/src/runner.rs index 6f671e9..a95707c 100644 --- a/apps/monitor/src/runner.rs +++ b/apps/monitor/src/runner.rs @@ -127,18 +127,9 @@ async fn run_check(client: &reqwest::Client, monitor: &Monitor, scheduled_at: Op Ok::<_, reqwest::Error>((status, headers, body)) }).await; - // Collect cert result — give it up to 2s after the main request finishes, - // then abort. This way a fast site still gets cert info, but a hung cert - // check never blocks the ping result. - let cert_expiry_days = match cert_handle { - Some(handle) => { - match tokio::time::timeout(std::time::Duration::from_secs(2), handle).await { - Ok(Ok(Ok(Ok(days)))) => days, - _ => None, - } - }, - None => None, - }; + // Cert check runs after the main request completes — only if the site responded. + // This prevents a separate TCP SYN to a hung host from blocking the timeout. + let cert_expiry_days: Option = None; // populated below after successful response let latency_ms = start.elapsed().as_millis() as u64; @@ -164,6 +155,20 @@ async fn run_check(client: &reqwest::Client, monitor: &Monitor, scheduled_at: Op Ok((status_raw, headers, body)) => { let status = status_raw.as_u16(); + // Only attempt cert check if the site actually responded — avoids a second + // hung TCP connect to a down host. + let cert_expiry_days = if is_https { + match tokio::time::timeout( + std::time::Duration::from_secs(5), + check_cert_expiry(&url_clone), + ).await { + Ok(Ok(days)) => days, + _ => None, + } + } else { + cert_expiry_days + }; + // Evaluate query if present let (up, query_error) = if let Some(q) = &monitor.query { let response = Response {