Introduce Request::timeout to override agent's config
This commit is contained in:
@@ -40,6 +40,7 @@ pub struct Request {
|
|||||||
error_on_non_2xx: bool,
|
error_on_non_2xx: bool,
|
||||||
headers: Vec<Header>,
|
headers: Vec<Header>,
|
||||||
query_params: Vec<(String, String)>,
|
query_params: Vec<(String, String)>,
|
||||||
|
timeout: Option<time::Duration>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Urlish {
|
impl fmt::Display for Urlish {
|
||||||
@@ -70,6 +71,7 @@ impl Request {
|
|||||||
headers: vec![],
|
headers: vec![],
|
||||||
error_on_non_2xx: true,
|
error_on_non_2xx: true,
|
||||||
query_params: vec![],
|
query_params: vec![],
|
||||||
|
timeout: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,9 +83,17 @@ impl Request {
|
|||||||
headers: vec![],
|
headers: vec![],
|
||||||
error_on_non_2xx: true,
|
error_on_non_2xx: true,
|
||||||
query_params: vec![],
|
query_params: vec![],
|
||||||
|
timeout: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
/// Sets overall timeout for the request, overriding agent's configuration if any.
|
||||||
|
pub fn timeout(mut self, timeout: time::Duration) -> Self {
|
||||||
|
self.timeout = Some(timeout);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends the request with no body and blocks the caller until done.
|
/// Sends the request with no body and blocks the caller until done.
|
||||||
///
|
///
|
||||||
/// Use this with GET, HEAD, OPTIONS or TRACE. It sends neither
|
/// Use this with GET, HEAD, OPTIONS or TRACE. It sends neither
|
||||||
@@ -116,7 +126,7 @@ impl Request {
|
|||||||
for (name, value) in self.query_params.clone() {
|
for (name, value) in self.query_params.clone() {
|
||||||
url.query_pairs_mut().append_pair(&name, &value);
|
url.query_pairs_mut().append_pair(&name, &value);
|
||||||
}
|
}
|
||||||
let deadline = match self.agent.config.timeout {
|
let deadline = match self.timeout.or(self.agent.config.timeout) {
|
||||||
None => None,
|
None => None,
|
||||||
Some(timeout) => {
|
Some(timeout) => {
|
||||||
let now = time::Instant::now();
|
let now = time::Instant::now();
|
||||||
|
|||||||
@@ -124,6 +124,27 @@ fn overall_timeout_during_headers() {
|
|||||||
.expect("expected timeout but got something else");
|
.expect("expected timeout but got something else");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn overall_timeout_override_during_headers() {
|
||||||
|
// Start a test server on an available port, that dribbles out a response at 1 write per 10ms.
|
||||||
|
let server = TestServer::new(dribble_headers_respond);
|
||||||
|
let url = format!("http://localhost:{}/", server.port);
|
||||||
|
let agent = builder().timeout(Duration::from_secs(90000)).build();
|
||||||
|
let result = agent.get(&url).timeout(Duration::from_millis(500)).call();
|
||||||
|
match result {
|
||||||
|
Ok(_) => Err("successful response".to_string()),
|
||||||
|
Err(e) if e.kind() == ErrorKind::Io => {
|
||||||
|
let ioe: Option<&io::Error> = e.source().and_then(|s| s.downcast_ref());
|
||||||
|
match ioe {
|
||||||
|
Some(e) if e.kind() == io::ErrorKind::TimedOut => Ok(()),
|
||||||
|
_ => Err(format!("wrong error type {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => Err(format!("Unexpected error type: {:?}", e)),
|
||||||
|
}
|
||||||
|
.expect("expected timeout but got something else");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
fn overall_timeout_reading_json() {
|
fn overall_timeout_reading_json() {
|
||||||
|
|||||||
Reference in New Issue
Block a user