Skip to content

Commit 82a6873

Browse files
Merge pull request #215 from code-inflation/fix/ipv6-timeout-panic
Fix IPv6 connection timeout panic
2 parents 59256ff + 0797ed9 commit 82a6873

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ fn main() {
3030
if let Some(ref ip) = options.ipv4 {
3131
client = reqwest::blocking::Client::builder()
3232
.local_address(ip.parse::<IpAddr>().expect("Invalid IPv4 address"))
33+
.timeout(std::time::Duration::from_secs(30))
3334
.build();
3435
} else if let Some(ref ip) = options.ipv6 {
3536
client = reqwest::blocking::Client::builder()
3637
.local_address(ip.parse::<IpAddr>().expect("Invalid IPv6 address"))
38+
.timeout(std::time::Duration::from_secs(30))
3739
.build();
3840
} else {
39-
client = reqwest::blocking::Client::builder().build();
41+
client = reqwest::blocking::Client::builder()
42+
.timeout(std::time::Duration::from_secs(30))
43+
.build();
4044
}
4145
speed_test(
4246
client.expect("Failed to initialize reqwest client"),

src/speedtest.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,13 @@ impl Display for Metadata {
8383
}
8484

8585
pub fn speed_test(client: Client, options: SpeedTestCLIOptions) -> Vec<Measurement> {
86-
let metadata = fetch_metadata(&client);
86+
let metadata = match fetch_metadata(&client) {
87+
Ok(metadata) => metadata,
88+
Err(e) => {
89+
eprintln!("Error fetching metadata: {}", e);
90+
std::process::exit(1);
91+
}
92+
};
8793
if options.output_format == OutputFormat::StdOut {
8894
println!("{metadata}");
8995
}
@@ -284,21 +290,16 @@ fn print_current_speed(
284290
);
285291
}
286292

287-
pub fn fetch_metadata(client: &Client) -> Metadata {
293+
pub fn fetch_metadata(client: &Client) -> Result<Metadata, reqwest::Error> {
288294
let url = &format!("{}/{}{}", BASE_URL, DOWNLOAD_URL, 0);
289-
let headers = client
290-
.get(url)
291-
.send()
292-
.expect("failed to get response")
293-
.headers()
294-
.to_owned();
295-
Metadata {
295+
let headers = client.get(url).send()?.headers().to_owned();
296+
Ok(Metadata {
296297
city: extract_header_value(&headers, "cf-meta-city", "City N/A"),
297298
country: extract_header_value(&headers, "cf-meta-country", "Country N/A"),
298299
ip: extract_header_value(&headers, "cf-meta-ip", "IP N/A"),
299300
asn: extract_header_value(&headers, "cf-meta-asn", "ASN N/A"),
300301
colo: extract_header_value(&headers, "cf-meta-colo", "Colo N/A"),
301-
}
302+
})
302303
}
303304

304305
fn extract_header_value(
@@ -452,10 +453,22 @@ mod tests {
452453

453454
#[test]
454455
fn test_payload_size_display() {
455-
// The Display implementation uses format_bytes from measurements module
456-
// We'll test the basic functionality
457456
let size = PayloadSize::K100;
458457
let display_str = format!("{}", size);
459458
assert!(!display_str.is_empty());
460459
}
460+
461+
#[test]
462+
fn test_fetch_metadata_ipv6_timeout_error() {
463+
use std::time::Duration;
464+
465+
let client = reqwest::blocking::Client::builder()
466+
.local_address("::".parse::<std::net::IpAddr>().unwrap())
467+
.timeout(Duration::from_millis(100))
468+
.build()
469+
.unwrap();
470+
471+
let result = fetch_metadata(&client);
472+
assert!(result.is_err());
473+
}
461474
}

0 commit comments

Comments
 (0)