1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-06-25 22:49:21 +02:00

update ssl impls

This commit is contained in:
Nikolay Kim
2019-11-18 20:40:10 +06:00
parent 9e95efcc16
commit a6a2d2f444
7 changed files with 150 additions and 120 deletions

View File

@ -20,22 +20,22 @@ use super::error::ConnectError;
use super::pool::{ConnectionPool, Protocol};
use super::Connect;
#[cfg(feature = "ssl")]
use openssl::ssl::SslConnector as OpensslConnector;
#[cfg(feature = "openssl")]
use open_ssl::ssl::SslConnector as OpensslConnector;
#[cfg(feature = "rust-tls")]
use rustls::ClientConfig;
#[cfg(feature = "rust-tls")]
#[cfg(feature = "rustls")]
use rust_tls::ClientConfig;
#[cfg(feature = "rustls")]
use std::sync::Arc;
#[cfg(any(feature = "ssl", feature = "rust-tls"))]
#[cfg(any(feature = "openssl", feature = "rustls"))]
enum SslConnector {
#[cfg(feature = "ssl")]
#[cfg(feature = "openssl")]
Openssl(OpensslConnector),
#[cfg(feature = "rust-tls")]
#[cfg(feature = "rustls")]
Rustls(Arc<ClientConfig>),
}
#[cfg(not(any(feature = "ssl", feature = "rust-tls")))]
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
type SslConnector = ();
/// Manages http client network connectivity
@ -76,9 +76,9 @@ impl Connector<(), ()> {
TcpStream,
> {
let ssl = {
#[cfg(feature = "ssl")]
#[cfg(feature = "openssl")]
{
use openssl::ssl::SslMethod;
use open_ssl::ssl::SslMethod;
let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap();
let _ = ssl
@ -86,7 +86,7 @@ impl Connector<(), ()> {
.map_err(|e| error!("Can not set alpn protocol: {:?}", e));
SslConnector::Openssl(ssl.build())
}
#[cfg(all(not(feature = "ssl"), feature = "rust-tls"))]
#[cfg(all(not(feature = "openssl"), feature = "rustls"))]
{
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
let mut config = ClientConfig::new();
@ -96,7 +96,7 @@ impl Connector<(), ()> {
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
SslConnector::Rustls(Arc::new(config))
}
#[cfg(not(any(feature = "ssl", feature = "rust-tls")))]
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
{}
};
@ -145,7 +145,8 @@ where
Request = TcpConnect<Uri>,
Response = TcpConnection<Uri, U>,
Error = actix_connect::ConnectError,
> + 'static,
> + Clone
+ 'static,
{
/// Connection timeout, i.e. max time to connect to remote host including dns name resolution.
/// Set to 1 second by default.
@ -154,14 +155,14 @@ where
self
}
#[cfg(feature = "ssl")]
#[cfg(feature = "openssl")]
/// Use custom `SslConnector` instance.
pub fn ssl(mut self, connector: OpensslConnector) -> Self {
self.ssl = SslConnector::Openssl(connector);
self
}
#[cfg(feature = "rust-tls")]
#[cfg(feature = "rustls")]
pub fn rustls(mut self, connector: Arc<ClientConfig>) -> Self {
self.ssl = SslConnector::Rustls(connector);
self
@ -217,7 +218,7 @@ where
self,
) -> impl Service<Request = Connect, Response = impl Connection, Error = ConnectError>
+ Clone {
#[cfg(not(any(feature = "ssl", feature = "rust-tls")))]
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
{
let connector = TimeoutService::new(
self.timeout,
@ -242,46 +243,49 @@ where
),
}
}
#[cfg(any(feature = "ssl", feature = "rust-tls"))]
#[cfg(any(feature = "openssl", feature = "rustls"))]
{
const H2: &[u8] = b"h2";
#[cfg(feature = "ssl")]
#[cfg(feature = "openssl")]
use actix_connect::ssl::OpensslConnector;
#[cfg(feature = "rust-tls")]
#[cfg(feature = "rustls")]
use actix_connect::ssl::RustlsConnector;
use actix_service::boxed::service;
#[cfg(feature = "rust-tls")]
use rustls::Session;
use actix_service::{boxed::service, pipeline};
#[cfg(feature = "rustls")]
use rust_tls::Session;
let ssl_service = TimeoutService::new(
self.timeout,
apply_fn(self.connector.clone(), |msg: Connect, srv| {
srv.call(TcpConnect::new(msg.uri).set_addr(msg.addr))
})
.map_err(ConnectError::from)
pipeline(
apply_fn(
UnpinWrapper(self.connector.clone()),
|msg: Connect, srv| {
srv.call(TcpConnect::new(msg.uri).set_addr(msg.addr))
},
)
.map_err(ConnectError::from),
)
.and_then(match self.ssl {
#[cfg(feature = "ssl")]
SslConnector::Openssl(ssl) => service(
OpensslConnector::service(ssl)
.map_err(ConnectError::from)
.map(|stream| {
let sock = stream.into_parts().0;
let h2 = sock
.get_ref()
.ssl()
.selected_alpn_protocol()
.map(|protos| protos.windows(2).any(|w| w == H2))
.unwrap_or(false);
if h2 {
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
} else {
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
}
}),
),
#[cfg(feature = "rust-tls")]
#[cfg(feature = "openssl")]
SslConnector::Openssl(ssl) => OpensslConnector::service(ssl)
.map(|stream| {
let sock = stream.into_parts().0;
let h2 = sock
.ssl()
.selected_alpn_protocol()
.map(|protos| protos.windows(2).any(|w| w == H2))
.unwrap_or(false);
if h2 {
(Box::new(sock) as Box<dyn Io + Unpin>, Protocol::Http2)
} else {
(Box::new(sock) as Box<dyn Io + Unpin>, Protocol::Http1)
}
})
.map_err(ConnectError::from),
#[cfg(feature = "rustls")]
SslConnector::Rustls(ssl) => service(
RustlsConnector::service(ssl)
UnpinWrapper(RustlsConnector::service(ssl))
.map_err(ConnectError::from)
.map(|stream| {
let sock = stream.into_parts().0;
@ -292,9 +296,15 @@ where
.map(|protos| protos.windows(2).any(|w| w == H2))
.unwrap_or(false);
if h2 {
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
(
Box::new(sock) as Box<dyn Io + Unpin>,
Protocol::Http2,
)
} else {
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
(
Box::new(sock) as Box<dyn Io + Unpin>,
Protocol::Http1,
)
}
}),
),
@ -307,7 +317,7 @@ where
let tcp_service = TimeoutService::new(
self.timeout,
apply_fn(self.connector.clone(), |msg: Connect, srv| {
apply_fn(UnpinWrapper(self.connector), |msg: Connect, srv| {
srv.call(TcpConnect::new(msg.uri).set_addr(msg.addr))
})
.map_err(ConnectError::from)
@ -339,11 +349,11 @@ where
}
#[derive(Clone)]
struct UnpinWrapper<T>(T);
struct UnpinWrapper<T: Clone>(T);
impl<T: Service> Unpin for UnpinWrapper<T> {}
impl<T: Clone> Unpin for UnpinWrapper<T> {}
impl<T: Service> Service for UnpinWrapper<T> {
impl<T: Service + Clone> Service for UnpinWrapper<T> {
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
@ -374,7 +384,7 @@ impl<T: Service> Future for UnpinWrapperFut<T> {
}
}
#[cfg(not(any(feature = "ssl", feature = "rust-tls")))]
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
mod connect_impl {
use std::task::{Context, Poll};
@ -439,7 +449,7 @@ mod connect_impl {
}
}
#[cfg(any(feature = "ssl", feature = "rust-tls"))]
#[cfg(any(feature = "openssl", feature = "rustls"))]
mod connect_impl {
use std::marker::PhantomData;
@ -510,11 +520,11 @@ mod connect_impl {
fn call(&mut self, req: Connect) -> Self::Future {
match req.uri.scheme_str() {
Some("https") | Some("wss") => Either::B(InnerConnectorResponseB {
Some("https") | Some("wss") => Either::Right(InnerConnectorResponseB {
fut: self.ssl_pool.call(req),
_t: PhantomData,
}),
_ => Either::A(InnerConnectorResponseA {
_ => Either::Left(InnerConnectorResponseA {
fut: self.tcp_pool.call(req),
_t: PhantomData,
}),