mirror of
https://github.com/actix/actix-web.git
synced 2025-02-07 23:02:20 +00:00
add per request timeout
This commit is contained in:
parent
058b1d56e6
commit
744d82431d
4 changed files with 47 additions and 8 deletions
|
@ -1,17 +1,18 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## [0.1.0-alpha.2] - 2019-03-xx
|
## [0.1.0-alpha.2] - 2019-03-29
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
* Request timeout.
|
* Per request and session wide request timeout.
|
||||||
|
|
||||||
* Re-export `actix_http::client::Connector`.
|
|
||||||
|
|
||||||
* Session wide headers.
|
* Session wide headers.
|
||||||
|
|
||||||
* Session wide basic and bearer auth.
|
* Session wide basic and bearer auth.
|
||||||
|
|
||||||
|
* Re-export `actix_http::client::Connector`.
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
* Export `ws` sub-module with websockets related types
|
* Export `ws` sub-module with websockets related types
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl ClientBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add default header. Headers adds byt this method
|
/// Add default header. Headers added by this method
|
||||||
/// get added to every request.
|
/// get added to every request.
|
||||||
pub fn header<K, V>(mut self, key: K, value: V) -> Self
|
pub fn header<K, V>(mut self, key: K, value: V) -> Self
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use bytes::{BufMut, Bytes, BytesMut};
|
use bytes::{BufMut, Bytes, BytesMut};
|
||||||
#[cfg(feature = "cookies")]
|
#[cfg(feature = "cookies")]
|
||||||
|
@ -62,6 +63,7 @@ pub struct ClientRequest {
|
||||||
cookies: Option<CookieJar>,
|
cookies: Option<CookieJar>,
|
||||||
default_headers: bool,
|
default_headers: bool,
|
||||||
response_decompress: bool,
|
response_decompress: bool,
|
||||||
|
timeout: Option<Duration>,
|
||||||
config: Rc<ClientConfig>,
|
config: Rc<ClientConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +88,7 @@ impl ClientRequest {
|
||||||
config,
|
config,
|
||||||
#[cfg(feature = "cookies")]
|
#[cfg(feature = "cookies")]
|
||||||
cookies: None,
|
cookies: None,
|
||||||
|
timeout: None,
|
||||||
default_headers: true,
|
default_headers: true,
|
||||||
response_decompress: true,
|
response_decompress: true,
|
||||||
}
|
}
|
||||||
|
@ -309,6 +312,15 @@ impl ClientRequest {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set request timeout. Overrides client wide timeout setting.
|
||||||
|
///
|
||||||
|
/// Request timeout is the total time before a response must be received.
|
||||||
|
/// Default value is 5 seconds.
|
||||||
|
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||||
|
self.timeout = Some(timeout);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// This method calls provided closure with builder reference if
|
/// This method calls provided closure with builder reference if
|
||||||
/// value is `true`.
|
/// value is `true`.
|
||||||
pub fn if_true<F>(mut self, value: bool, f: F) -> Self
|
pub fn if_true<F>(mut self, value: bool, f: F) -> Self
|
||||||
|
@ -443,10 +455,10 @@ impl ClientRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let config = slf.config;
|
||||||
let response_decompress = slf.response_decompress;
|
let response_decompress = slf.response_decompress;
|
||||||
|
|
||||||
let fut = slf
|
let fut = config
|
||||||
.config
|
|
||||||
.connector
|
.connector
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.send_request(head, body.into())
|
.send_request(head, body.into())
|
||||||
|
@ -461,7 +473,7 @@ impl ClientRequest {
|
||||||
});
|
});
|
||||||
|
|
||||||
// set request timeout
|
// set request timeout
|
||||||
if let Some(timeout) = slf.config.timeout {
|
if let Some(timeout) = slf.timeout.or_else(|| config.timeout.clone()) {
|
||||||
Either::B(Either::A(Timeout::new(fut, timeout).map_err(|e| {
|
Either::B(Either::A(Timeout::new(fut, timeout).map_err(|e| {
|
||||||
if let Some(e) = e.into_inner() {
|
if let Some(e) = e.into_inner() {
|
||||||
e
|
e
|
||||||
|
|
|
@ -83,6 +83,32 @@ fn test_timeout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_timeout_override() {
|
||||||
|
let mut srv = TestServer::new(|| {
|
||||||
|
HttpService::new(App::new().service(web::resource("/").route(web::to_async(
|
||||||
|
|| {
|
||||||
|
tokio_timer::sleep(Duration::from_millis(200))
|
||||||
|
.then(|_| Ok::<_, Error>(HttpResponse::Ok().body(STR)))
|
||||||
|
},
|
||||||
|
))))
|
||||||
|
});
|
||||||
|
|
||||||
|
let client = srv.execute(|| {
|
||||||
|
awc::Client::build()
|
||||||
|
.timeout(Duration::from_millis(50000))
|
||||||
|
.finish()
|
||||||
|
});
|
||||||
|
let request = client
|
||||||
|
.get(srv.url("/"))
|
||||||
|
.timeout(Duration::from_millis(50))
|
||||||
|
.send();
|
||||||
|
match srv.block_on(request) {
|
||||||
|
Err(SendRequestError::Timeout) => (),
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn test_connection_close() {
|
// fn test_connection_close() {
|
||||||
// let mut srv =
|
// let mut srv =
|
||||||
|
|
Loading…
Reference in a new issue