@@ -11,12 +11,14 @@ use reqwest::{blocking::Client, StatusCode};
1111use serde:: Serialize ;
1212use std:: {
1313 fmt:: Display ,
14+ sync:: atomic:: { AtomicBool , Ordering } ,
1415 time:: { Duration , Instant } ,
1516} ;
1617
1718const BASE_URL : & str = "https://speed.cloudflare.com" ;
1819const DOWNLOAD_URL : & str = "__down?bytes=" ;
1920const UPLOAD_URL : & str = "__up" ;
21+ static WARNED_NEGATIVE_LATENCY : AtomicBool = AtomicBool :: new ( false ) ;
2022
2123#[ derive( Clone , Copy , Debug , Hash , Serialize , Eq , PartialEq ) ]
2224pub enum TestType {
@@ -180,29 +182,37 @@ pub fn test_latency(client: &Client) -> f64 {
180182 let req_builder = client. get ( url) ;
181183
182184 let start = Instant :: now ( ) ;
183- let response = req_builder. send ( ) . expect ( "failed to get response" ) ;
185+ let mut response = req_builder. send ( ) . expect ( "failed to get response" ) ;
184186 let _status_code = response. status ( ) ;
185- let duration = start. elapsed ( ) . as_secs_f64 ( ) * 1_000.0 ;
187+ // Drain body to complete the request; ignore errors.
188+ let _ = std:: io:: copy ( & mut response, & mut std:: io:: sink ( ) ) ;
189+ let total_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1_000.0 ;
186190
187191 let re = Regex :: new ( r"cfRequestDuration;dur=([\d.]+)" ) . unwrap ( ) ;
192+ let server_timing = response
193+ . headers ( )
194+ . get ( "Server-Timing" )
195+ . expect ( "No Server-Timing in response header" )
196+ . to_str ( )
197+ . unwrap ( ) ;
188198 let cf_req_duration: f64 = re
189- . captures (
190- response
191- . headers ( )
192- . get ( "Server-Timing" )
193- . expect ( "No Server-Timing in response header" )
194- . to_str ( )
195- . unwrap ( ) ,
196- )
199+ . captures ( server_timing)
197200 . unwrap ( )
198201 . get ( 1 )
199202 . unwrap ( )
200203 . as_str ( )
201204 . parse ( )
202205 . unwrap ( ) ;
203- let mut req_latency = duration - cf_req_duration;
206+ let mut req_latency = total_ms - cf_req_duration;
207+ log:: debug!(
208+ "latency debug: total_ms={total_ms:.3} cf_req_duration_ms={cf_req_duration:.3} req_latency_total={req_latency:.3} server_timing={server_timing}"
209+ ) ;
204210 if req_latency < 0.0 {
205- // TODO investigate negative latency values
211+ if !WARNED_NEGATIVE_LATENCY . swap ( true , Ordering :: Relaxed ) {
212+ log:: warn!(
213+ "negative latency after server timing subtraction; clamping to 0.0 (total_ms={total_ms:.3} cf_req_duration_ms={cf_req_duration:.3})"
214+ ) ;
215+ }
206216 req_latency = 0.0
207217 }
208218 req_latency
0 commit comments