1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-01-22 07:15:56 +01:00

allow to use Connection for sending client request

This commit is contained in:
Nikolay Kim 2018-02-21 22:53:23 -08:00
parent 4a07430e8e
commit 4a9c1ae894
4 changed files with 106 additions and 27 deletions

View File

@ -55,11 +55,11 @@ pub enum ClientConnectorError {
/// SSL error /// SSL error
#[cfg(feature="alpn")] #[cfg(feature="alpn")]
#[fail(display="{}", _0)] #[fail(display="{}", _0)]
SslError(OpensslError), SslError(#[cause] OpensslError),
/// Connection error /// Connection error
#[fail(display = "{}", _0)] #[fail(display = "{}", _0)]
Connector(ConnectorError), Connector(#[cause] ConnectorError),
/// Connecting took too long /// Connecting took too long
#[fail(display = "Timeout out while establishing connection")] #[fail(display = "Timeout out while establishing connection")]
@ -71,7 +71,7 @@ pub enum ClientConnectorError {
/// Connection io error /// Connection io error
#[fail(display = "{}", _0)] #[fail(display = "{}", _0)]
IoError(io::Error), IoError(#[cause] io::Error),
} }
impl From<ConnectorError> for ClientConnectorError { impl From<ConnectorError> for ClientConnectorError {
@ -98,7 +98,6 @@ impl Default for ClientConnector {
#[cfg(feature="alpn")] #[cfg(feature="alpn")]
{ {
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
builder.set_verify(SslVerifyMode::NONE);
ClientConnector { ClientConnector {
connector: builder.build() connector: builder.build()
} }
@ -269,6 +268,10 @@ impl Connection {
pub fn stream(&mut self) -> &mut IoStream { pub fn stream(&mut self) -> &mut IoStream {
&mut *self.stream &mut *self.stream
} }
pub fn from_stream<T: IoStream>(io: T) -> Connection {
Connection{stream: Box::new(io)}
}
} }
impl IoStream for Connection { impl IoStream for Connection {

View File

@ -39,6 +39,7 @@ impl From<io::Error> for SendRequestError {
enum State { enum State {
New, New,
Connect(actix::dev::Request<Unsync, ClientConnector, Connect>), Connect(actix::dev::Request<Unsync, ClientConnector, Connect>),
Connection(Connection),
Send(Box<Pipeline>), Send(Box<Pipeline>),
None, None,
} }
@ -64,6 +65,14 @@ impl SendRequest {
state: State::New, state: State::New,
conn: conn} conn: conn}
} }
pub(crate) fn with_connection(req: ClientRequest, conn: Connection) -> SendRequest
{
SendRequest{
req: req,
state: State::Connection(conn),
conn: ClientConnector::from_registry()}
}
} }
impl Future for SendRequest { impl Future for SendRequest {
@ -84,6 +93,14 @@ impl Future for SendRequest {
}, },
Ok(Async::Ready(result)) => match result { Ok(Async::Ready(result)) => match result {
Ok(stream) => { Ok(stream) => {
self.state = State::Connection(stream)
},
Err(err) => return Err(SendRequestError::Connector(err)),
},
Err(_) => return Err(SendRequestError::Connector(
ClientConnectorError::Disconnected))
},
State::Connection(stream) => {
let mut writer = HttpClientWriter::new(SharedBytes::default()); let mut writer = HttpClientWriter::new(SharedBytes::default());
writer.start(&mut self.req)?; writer.start(&mut self.req)?;
@ -105,11 +122,6 @@ impl Future for SendRequest {
}); });
self.state = State::Send(pl); self.state = State::Send(pl);
}, },
Err(err) => return Err(SendRequestError::Connector(err)),
},
Err(_) =>
return Err(SendRequestError::Connector(ClientConnectorError::Disconnected))
},
State::Send(mut pl) => { State::Send(mut pl) => {
pl.poll_write() pl.poll_write()
.map_err(|e| io::Error::new( .map_err(|e| io::Error::new(

View File

@ -13,7 +13,7 @@ use body::Body;
use error::Error; use error::Error;
use headers::ContentEncoding; use headers::ContentEncoding;
use super::pipeline::SendRequest; use super::pipeline::SendRequest;
use super::connector::ClientConnector; use super::connector::{Connection, ClientConnector};
/// An HTTP Client Request /// An HTTP Client Request
pub struct ClientRequest { pub struct ClientRequest {
@ -179,9 +179,14 @@ impl ClientRequest {
SendRequest::new(self) SendRequest::new(self)
} }
/// Send request using custom connector
pub fn with_connector(self, conn: Addr<Unsync, ClientConnector>) -> SendRequest { pub fn with_connector(self, conn: Addr<Unsync, ClientConnector>) -> SendRequest {
SendRequest::with_connector(self, conn) SendRequest::with_connector(self, conn)
}
/// Send request using existing Connection
pub fn with_connection(self, conn: Connection) -> SendRequest {
SendRequest::with_connection(self, conn)
} }
} }

59
tests/test_client.rs Normal file
View File

@ -0,0 +1,59 @@
extern crate actix;
extern crate actix_web;
extern crate bytes;
extern crate futures;
use bytes::Bytes;
use actix_web::*;
const STR: &str =
"Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World";
#[test]
fn test_simple() {
let mut srv = test::TestServer::new(
|app| app.handler(|_| httpcodes::HTTPOk.build().body(STR)));
let request = srv.get().header("x-test", "111").finish().unwrap();
let repr = format!("{:?}", request);
assert!(repr.contains("ClientRequest"));
assert!(repr.contains("x-test"));
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
let request = srv.post().finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success());
// read response
let bytes = srv.execute(response.body()).unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}