From be7e8d159bfb1abbb928ac53ee0920d135f52ab9 Mon Sep 17 00:00:00 2001 From: Glade Miller Date: Tue, 6 Mar 2018 15:26:09 -0700 Subject: [PATCH 1/2] Allow connection timeout to be set --- CHANGES.md | 4 ++++ src/client/connector.rs | 16 ++++++++++++---- src/client/pipeline.rs | 5 ++++- src/client/request.rs | 23 ++++++++++++++++++++--- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 7d823e865..67f052f8b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changes +## 0.4.5 + +* Allow connection timeout to be set + ## 0.4.4 (2018-03-04) * Allow to use Arc> as response/request body diff --git a/src/client/connector.rs b/src/client/connector.rs index 4e8ac214b..eb9dc3b0d 100644 --- a/src/client/connector.rs +++ b/src/client/connector.rs @@ -1,5 +1,6 @@ use std::{io, time}; use std::net::Shutdown; +use std::time::Duration; use actix::{fut, Actor, ActorFuture, Context, Handler, Message, ActorResponse, Supervised}; @@ -25,12 +26,18 @@ use server::IoStream; #[derive(Debug)] /// `Connect` type represents message that can be send to `ClientConnector` /// with connection request. -pub struct Connect(pub Uri); +pub struct Connect { + pub uri: Uri, + pub connection_timeout: Duration +} impl Connect { /// Create `Connect` message for specified `Uri` pub fn new(uri: U) -> Result where Uri: HttpTryFrom { - Ok(Connect(Uri::try_from(uri).map_err(|e| e.into())?)) + Ok(Connect { + uri: Uri::try_from(uri).map_err(|e| e.into())?, + connection_timeout: Duration::from_secs(1) + }) } } @@ -159,7 +166,8 @@ impl Handler for ClientConnector { type Result = ActorResponse; fn handle(&mut self, msg: Connect, _: &mut Self::Context) -> Self::Result { - let uri = &msg.0; + let uri = &msg.uri; + let connection_timeout = msg.connection_timeout; // host name is required if uri.host().is_none() { @@ -185,7 +193,7 @@ impl Handler for ClientConnector { ActorResponse::async( Connector::from_registry() - .send(ResolveConnect::host_and_port(&host, port)) + .send(ResolveConnect::host_and_port(&host, port).timeout(connection_timeout)) .into_actor(self) .map_err(|_, _, _| ClientConnectorError::Disconnected) .and_then(move |res, _act, _| { diff --git a/src/client/pipeline.rs b/src/client/pipeline.rs index baa84da9d..47e38bc8a 100644 --- a/src/client/pipeline.rs +++ b/src/client/pipeline.rs @@ -86,7 +86,10 @@ impl Future for SendRequest { match state { State::New => - self.state = State::Connect(self.conn.send(Connect(self.req.uri().clone()))), + self.state = State::Connect(self.conn.send(Connect { + uri: self.req.uri().clone(), + connection_timeout: self.req.connection_timeout() + })), State::Connect(mut conn) => match conn.poll() { Ok(Async::NotReady) => { self.state = State::Connect(conn); diff --git a/src/client/request.rs b/src/client/request.rs index 42682a30c..799ff34eb 100644 --- a/src/client/request.rs +++ b/src/client/request.rs @@ -1,5 +1,6 @@ use std::{fmt, mem}; use std::io::Write; +use std::time::Duration; use actix::{Addr, Unsync}; use cookie::{Cookie, CookieJar}; @@ -28,6 +29,7 @@ pub struct ClientRequest { response_decompress: bool, buffer_capacity: Option<(usize, usize)>, conn: ConnectionType, + connection_timeout: Duration } @@ -52,6 +54,7 @@ impl Default for ClientRequest { response_decompress: true, buffer_capacity: None, conn: ConnectionType::Default, + connection_timeout: Duration::from_secs(1) } } } @@ -102,7 +105,7 @@ impl ClientRequest { request: Some(ClientRequest::default()), err: None, cookies: None, - default_headers: true, + default_headers: true } } @@ -112,6 +115,11 @@ impl ClientRequest { &self.uri } + #[inline] + pub fn connection_timeout(&self) -> Duration { + self.connection_timeout + } + /// Set client request uri #[inline] pub fn set_uri(&mut self, uri: Uri) { @@ -236,7 +244,7 @@ pub struct ClientRequestBuilder { request: Option, err: Option, cookies: Option, - default_headers: bool, + default_headers: bool } impl ClientRequestBuilder { @@ -361,6 +369,15 @@ impl ClientRequestBuilder { self } + /// Set connection timeout + #[inline] + pub fn connection_timeout(&mut self, connection_timeout: Duration) -> &mut Self { + if let Some(ref mut request) = self.request { + request.connection_timeout = connection_timeout; + } + self + } + /// Set request's content type #[inline] pub fn content_type(&mut self, value: V) -> &mut Self @@ -562,7 +579,7 @@ impl ClientRequestBuilder { request: self.request.take(), err: self.err.take(), cookies: self.cookies.take(), - default_headers: self.default_headers, + default_headers: self.default_headers } } } From 5bf4f3be8b60e39eb42e8a4b9001b1890469f74a Mon Sep 17 00:00:00 2001 From: Glade Miller Date: Tue, 6 Mar 2018 15:43:56 -0700 Subject: [PATCH 2/2] Actix dependency needs to be updated to master --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index eeca59366..147f5d27c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ openssl = { version="0.10", optional = true } tokio-openssl = { version="0.2", optional = true } [dependencies.actix] -version = "^0.5.1" +git = "https://github.com/actix/actix.git" [dev-dependencies] env_logger = "0.5"