diff --git a/curl-sys/lib.rs b/curl-sys/lib.rs index f3767ba505..231da9c044 100644 --- a/curl-sys/lib.rs +++ b/curl-sys/lib.rs @@ -66,7 +66,10 @@ pub const CURLINFO_TYPEMASK: c_int = 0xf00000; pub const CURLINFO_EFFECTIVE_URL: CURLINFO = CURLINFO_STRING + 1; pub const CURLINFO_RESPONSE_CODE: CURLINFO = CURLINFO_LONG + 2; -pub const CURLINFO_TOTAL_TIME: CURLINFO = CURLINFO_DOUBLE + 5; +pub const CURLINFO_TOTAL_TIME: CURLINFO = CURLINFO_DOUBLE + 3; +pub const CURLINFO_CONNECT_TIME: CURLINFO = CURLINFO_DOUBLE + 5; +pub const CURLINFO_REDIRECT_COUNT: CURLINFO = CURLINFO_LONG + 20; +pub const CURLINFO_PRIMARY_IP: CURLINFO = CURLINFO_STRING + 32; pub const CURLOPTTYPE_LONG: c_int = 0; pub const CURLOPTTYPE_OBJECTPOINT: c_int = 10_000; diff --git a/src/ffi/easy.rs b/src/ffi/easy.rs index 5a9a3609b0..bfa0cda136 100644 --- a/src/ffi/easy.rs +++ b/src/ffi/easy.rs @@ -88,15 +88,32 @@ impl Easy { // Try to get the response code builder.code = try!(self.get_response_code()); + // Try to get the connect time + builder.connect_time = try!(self.get_connect_time()); + + // Try to get the redirect count + builder.redirect_count = try!(self.get_redirect_count()); + + // Try to get the total time + builder.total_time = try!(self.get_total_time()); + Ok(builder.build()) } - pub fn get_response_code(&self) -> Result { - Ok(try!(self.get_info_long(info::RESPONSE_CODE)) as u32) + pub fn get_redirect_count(&self) -> Result { + Ok(try!(self.get_info_long(info::REDIRECT_COUNT)) as i32) + } + + pub fn get_connect_time(&self) -> Result { + Ok(try!(self.get_info_double(info::CONNECT_TIME)) as f64) } - pub fn get_total_time(&self) -> Result { - Ok(try!(self.get_info_long(info::TOTAL_TIME)) as usize) + pub fn get_response_code(&self) -> Result { + Ok(try!(self.get_info_long(info::RESPONSE_CODE)) as i32) + } + + pub fn get_total_time(&self) -> Result { + Ok(try!(self.get_info_double(info::TOTAL_TIME)) as f64) } fn get_info_long(&self, key: info::Key) -> Result { @@ -111,6 +128,19 @@ impl Easy { Ok(v) } + + fn get_info_double(&self, key: info::Key) -> Result { + let v: c_double = 0.0; + let res = err::ErrCode(unsafe { + ffi::curl_easy_getinfo(self.curl as *const _, key, &v) + }); + + if !res.is_success() { + return Err(res); + } + + Ok(v) + } } #[inline] @@ -139,9 +169,13 @@ impl Drop for Easy { */ struct ResponseBuilder { - code: u32, + code: i32, hdrs: HashMap>, - body: Vec + body: Vec, + total_time: f64, + primary_ip: Vec, + connect_time: f64, + redirect_count: i32 } impl ResponseBuilder { @@ -149,7 +183,11 @@ impl ResponseBuilder { ResponseBuilder { code: 0, hdrs: HashMap::new(), - body: Vec::new() + body: Vec::new(), + total_time: 0.0, + primary_ip: Vec::new(), + connect_time: 0.0, + redirect_count: 0 } } @@ -172,8 +210,8 @@ impl ResponseBuilder { } fn build(self) -> Response { - let ResponseBuilder { code, hdrs, body } = self; - Response::new(code, hdrs, body) + let ResponseBuilder { code, hdrs, body, total_time, connect_time, redirect_count, primary_ip } = self; + Response::new(code, hdrs, body, total_time, primary_ip, connect_time, redirect_count) } } diff --git a/src/ffi/info.rs b/src/ffi/info.rs index a1c509d212..0c2f66708d 100644 --- a/src/ffi/info.rs +++ b/src/ffi/info.rs @@ -5,5 +5,7 @@ use curl_ffi as ffi; pub use curl_ffi::CURLINFO_EFFECTIVE_URL as EFFECTIVE_URL; pub use curl_ffi::CURLINFO_RESPONSE_CODE as RESPONSE_CODE; pub use curl_ffi::CURLINFO_TOTAL_TIME as TOTAL_TIME; +pub use curl_ffi::CURLINFO_REDIRECT_COUNT as REDIRECT_COUNT; +pub use curl_ffi::CURLINFO_CONNECT_TIME as CONNECT_TIME; pub type Key = ffi::CURLINFO; diff --git a/src/http/handle.rs b/src/http/handle.rs index 3a87a57c7a..515ae94391 100644 --- a/src/http/handle.rs +++ b/src/http/handle.rs @@ -42,6 +42,11 @@ impl Handle { fn configure(handle: Handle) -> Handle { handle } } + pub fn nosignal(mut self) -> Handle { + self.easy.setopt(opt::NOSIGNAL, 1).unwrap(); + self + } + pub fn timeout(mut self, ms: usize) -> Handle { self.easy.setopt(opt::TIMEOUT_MS, ms).unwrap(); self diff --git a/src/http/response.rs b/src/http/response.rs index 8a8837a08f..59dad2359c 100644 --- a/src/http/response.rs +++ b/src/http/response.rs @@ -4,21 +4,45 @@ use std::collections::HashMap; pub type Headers = HashMap>; pub struct Response { - code: u32, + code: i32, hdrs: Headers, - body: Vec + body: Vec, + total_time: f64, + primary_ip: Vec, + connect_time: f64, + redirect_count: i32 } impl Response { - pub fn new(code: u32, hdrs: Headers, body: Vec) -> Response { + pub fn new(code: i32, hdrs: Headers, body: Vec, total_time: f64, primary_ip: Vec, connect_time: f64, redirect_count: i32) -> Response { Response { code: code, hdrs: hdrs, - body: body + body: body, + total_time: total_time, + primary_ip: primary_ip, + connect_time: connect_time, + redirect_count: redirect_count } } - pub fn get_code(&self) -> u32 { + pub fn get_total_time(&self) -> f64 { + self.total_time + } + + pub fn get_primary_ip<'a>(&'a self) -> &'a [u8] { + &self.primary_ip + } + + pub fn get_connect_time(&self) -> f64 { + self.connect_time + } + + pub fn get_redirect_count(&self) -> i32 { + self.redirect_count + } + + pub fn get_code(&self) -> i32 { self.code }