Skip to content

Commit f10612b

Browse files
Use CURLOPT_CONNECTTIMEOUT if timeout too big (#497)
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_CONNECTTIMEOUT.
1 parent 5d7b44c commit f10612b

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

src/easy/handler.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::cell::RefCell;
2+
use std::convert::TryFrom;
23
use std::ffi::{CStr, CString};
34
use std::fmt;
45
use std::io::{self, SeekFrom, Write};
@@ -2048,8 +2049,15 @@ impl<H> Easy2<H> {
20482049
/// By default this value is 300 seconds and corresponds to
20492050
/// `CURLOPT_CONNECTTIMEOUT_MS`.
20502051
pub fn connect_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
2051-
let ms = timeout.as_secs() * 1000 + timeout.subsec_millis() as u64;
2052-
self.setopt_long(curl_sys::CURLOPT_CONNECTTIMEOUT_MS, ms as c_long)
2052+
let ms = timeout.as_millis();
2053+
match c_long::try_from(ms) {
2054+
Ok(amt) => self.setopt_long(curl_sys::CURLOPT_CONNECTTIMEOUT_MS, amt),
2055+
Err(_) => {
2056+
let amt = c_long::try_from(ms / 1000)
2057+
.map_err(|_| Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT))?;
2058+
self.setopt_long(curl_sys::CURLOPT_CONNECTTIMEOUT, amt)
2059+
}
2060+
}
20532061
}
20542062

20552063
/// Specify which IP protocol version to use

tests/easy.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ macro_rules! t {
1313
};
1414
}
1515

16-
use curl::easy::{Easy, List, ReadError, Transfer, WriteError};
17-
use curl::Version;
16+
use curl::easy::{Easy, Easy2, List, ReadError, Transfer, WriteError};
17+
use curl::{Error, Version};
1818

1919
use crate::server::Server;
2020
mod server;
@@ -970,3 +970,33 @@ fn path_as_is() {
970970
assert_eq!(t!(h.response_code()), 200);
971971
assert_eq!(t!(h.effective_url()), Some(&addr[..]));
972972
}
973+
974+
#[test]
975+
fn test_connect_timeout() {
976+
use curl::easy::Handler;
977+
struct Collector(Vec<u8>);
978+
979+
impl Handler for Collector {
980+
fn write(&mut self, data: &[u8]) -> Result<usize, WriteError> {
981+
self.0.extend_from_slice(data);
982+
Ok(data.len())
983+
}
984+
}
985+
let mut easy2 = Easy2::new(Collector(Vec::new()));
986+
987+
// Overflow value test must return an Error
988+
assert_eq!(
989+
Error::new(curl_sys::CURLE_BAD_FUNCTION_ARGUMENT),
990+
easy2
991+
.connect_timeout(Duration::from_secs(std::u64::MAX))
992+
.unwrap_err()
993+
);
994+
995+
// Valid value
996+
assert_eq!(
997+
(),
998+
easy2
999+
.connect_timeout(Duration::from_millis(i32::MAX as u64))
1000+
.unwrap()
1001+
);
1002+
}

0 commit comments

Comments
 (0)