Skip to content

Commit c58a6cc

Browse files
Use CURLOPT_TIMEOUT if timeout too big (#495)
If the time that was converted into millisecond is more than the capacity of c_long, it will overflow, thus we need to convert it into seconds and use CURLOPT_TIMEOUT.
1 parent f10612b commit c58a6cc

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/easy/handler.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,10 +1925,15 @@ impl<H> Easy2<H> {
19251925
/// By default this option is not set and corresponds to
19261926
/// `CURLOPT_TIMEOUT_MS`.
19271927
pub fn timeout(&mut self, timeout: Duration) -> Result<(), Error> {
1928-
// TODO: checked arithmetic and casts
1929-
// TODO: use CURLOPT_TIMEOUT if the timeout is too great
1930-
let ms = timeout.as_secs() * 1000 + timeout.subsec_millis() as u64;
1931-
self.setopt_long(curl_sys::CURLOPT_TIMEOUT_MS, ms as c_long)
1928+
let ms = timeout.as_millis();
1929+
match c_long::try_from(ms) {
1930+
Ok(amt) => self.setopt_long(curl_sys::CURLOPT_TIMEOUT_MS, amt),
1931+
Err(_) => {
1932+
let amt = c_long::try_from(ms / 1000)
1933+
.map_err(|_| Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT))?;
1934+
self.setopt_long(curl_sys::CURLOPT_TIMEOUT, amt)
1935+
}
1936+
}
19321937
}
19331938

19341939
/// Set the low speed limit in bytes per second.

tests/easy.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,3 +1000,33 @@ fn test_connect_timeout() {
10001000
.unwrap()
10011001
);
10021002
}
1003+
1004+
#[test]
1005+
fn test_timeout() {
1006+
use curl::easy::Handler;
1007+
struct Collector(Vec<u8>);
1008+
1009+
impl Handler for Collector {
1010+
fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
1011+
self.0.extend_from_slice(data);
1012+
Ok(data.len())
1013+
}
1014+
}
1015+
let mut easy2 = Easy2::new(Collector(Vec::new()));
1016+
1017+
// Overflow value test must return an Error
1018+
assert_eq!(
1019+
Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT),
1020+
easy2
1021+
.timeout(Duration::from_secs(std::u64::MAX))
1022+
.unwrap_err()
1023+
);
1024+
1025+
// Valid value
1026+
assert_eq!(
1027+
(),
1028+
easy2
1029+
.timeout(Duration::from_millis(i32::MAX as u64))
1030+
.unwrap()
1031+
);
1032+
}

0 commit comments

Comments
 (0)