Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add native tls support for actix_tls::connect module #295

Merged
merged 6 commits into from
Mar 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add native tisl support for actix_tls::connect module
  • Loading branch information
fakeshadow authored and robjtede committed Mar 26, 2021
commit 7f8b4529eb8d92c97d44fc34c35548d4b17ab033
8 changes: 3 additions & 5 deletions actix-router/src/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,11 @@ impl Quoter {
idx += 1;
}

if let Some(data) = cloned {
cloned.map(|data| {
// Unsafe: we get data from http::Uri, which does utf-8 checks already
// this code only decodes valid pct encoded values
Some(unsafe { String::from_utf8_unchecked(data) })
} else {
None
}
unsafe { String::from_utf8_unchecked(data) }
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion actix-server/src/test_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ impl TestServer {
let port = addr.port();

TestServerRuntime {
system,
addr,
host,
port,
system,
}
}

Expand Down
2 changes: 1 addition & 1 deletion actix-service/src/map_err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ where
F: Fn(A::Error) -> E,
{
fn new(fut: A::Future, f: F) -> Self {
MapErrServiceFuture { f, fut }
MapErrServiceFuture { fut, f }
}
}

Expand Down
3 changes: 3 additions & 0 deletions actix-tls/src/connect/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ pub mod openssl;

#[cfg(feature = "rustls")]
pub mod rustls;

#[cfg(feature = "native-tls")]
pub mod nativetls;
robjtede marked this conversation as resolved.
Show resolved Hide resolved
88 changes: 88 additions & 0 deletions actix-tls/src/connect/ssl/nativetls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use std::io;

use actix_rt::net::ActixStream;
use actix_service::{Service, ServiceFactory};
use futures_core::future::LocalBoxFuture;
use log::trace;
use tokio_native_tls::{TlsConnector as TokioNativetlsConnector, TlsStream};

pub use tokio_native_tls::native_tls::TlsConnector;

use crate::connect::{Address, Connection};

/// Native-tls connector factory and service
pub struct NativetlsConnector {
connector: TokioNativetlsConnector,
}

impl NativetlsConnector {
pub fn new(connector: TlsConnector) -> Self {
Self {
connector: TokioNativetlsConnector::from(connector),
}
}
}

impl NativetlsConnector {
pub fn service(connector: TlsConnector) -> Self {
Self::new(connector)
}
}

impl Clone for NativetlsConnector {
fn clone(&self) -> Self {
Self {
connector: self.connector.clone(),
}
}
}

impl<T: Address, U> ServiceFactory<Connection<T, U>> for NativetlsConnector
where
U: ActixStream,
{
type Response = Connection<T, TlsStream<U>>;
type Error = io::Error;
type Config = ();
type Service = Self;
type InitError = ();
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;

fn new_service(&self, _: ()) -> Self::Future {
let connector = self.clone();
Box::pin(async { Ok(connector) })
}
}

// NativetlsConnector is both it's ServiceFactory and Service impl type.
// As the factory and service share the same type and state.
impl<T, U> Service<Connection<T, U>> for NativetlsConnector
where
T: Address,
U: ActixStream,
{
type Response = Connection<T, TlsStream<U>>;
type Error = io::Error;
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

actix_service::always_ready!();

fn call(&self, stream: Connection<T, U>) -> Self::Future {
let (io, stream) = stream.replace_io(());
let connector = self.connector.clone();
Box::pin(async move {
trace!("SSL Handshake start for: {:?}", stream.host());
connector
.connect(stream.host(), io)
.await
.map(|res| {
trace!("SSL Handshake success: {:?}", stream.host());
stream.replace_io(res).1
})
.map_err(|e| {
trace!("SSL Handshake error: {:?}", e);
io::Error::new(io::ErrorKind::Other, format!("{}", e))
})
})
}
}