Skip to content

Commit

Permalink
Add native tls support for actix_tls::connect module (#295)
Browse files Browse the repository at this point in the history
Co-authored-by: Rob Ede <robjtede@icloud.com>
  • Loading branch information
fakeshadow and robjtede committed Mar 27, 2021
1 parent f9262db commit bb27bac
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 9 deletions.
10 changes: 4 additions & 6 deletions actix-router/src/url.rs
Expand Up @@ -170,13 +170,11 @@ impl Quoter {
idx += 1;
}

if let Some(data) = cloned {
// Unsafe: we get data from http::Uri, which does utf-8 checks already
cloned.map(|data| {
// SAFETY: 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
3 changes: 3 additions & 0 deletions actix-server/CHANGES.md
@@ -1,6 +1,9 @@
# Changes

## Unreleased - 2021-xx-xx
* Prevent panic when shutdown_timeout is very large. [f9262db]

[f9262db]: https://github.com/actix/actix-net/commit/f9262db


## 2.0.0-beta.3 - 2021-02-06
Expand Down
2 changes: 1 addition & 1 deletion actix-server/src/test_server.rs
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
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
4 changes: 4 additions & 0 deletions actix-tls/CHANGES.md
Expand Up @@ -5,10 +5,14 @@
generation failed instead of panic. [#296]
* Remove `connect::ssl::openssl::OpensslConnectServiceFactory`. [#297]
* Remove `connect::ssl::openssl::OpensslConnectService`. [#297]
* Add `connect::ssl::native_tls` module for native tls support. [#295]
* Rename `accept::{nativetls => native_tls}`. [#295]

[#295]: https://github.com/actix/actix-net/pull/295
[#296]: https://github.com/actix/actix-net/pull/296
[#297]: https://github.com/actix/actix-net/pull/297


## 3.0.0-beta.4 - 2021-02-24
* Rename `accept::openssl::{SslStream => TlsStream}`.
* Add `connect::Connect::set_local_addr` to attach local `IpAddr`. [#282]
Expand Down
2 changes: 1 addition & 1 deletion actix-tls/src/accept/mod.rs
Expand Up @@ -16,7 +16,7 @@ pub mod openssl;
pub mod rustls;

#[cfg(feature = "native-tls")]
pub mod nativetls;
pub mod native_tls;

pub(crate) static MAX_CONN: AtomicUsize = AtomicUsize::new(256);

Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions actix-tls/src/connect/ssl/mod.rs
Expand Up @@ -5,3 +5,6 @@ pub mod openssl;

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

#[cfg(feature = "native-tls")]
pub mod native_tls;
88 changes: 88 additions & 0 deletions actix-tls/src/connect/ssl/native_tls.rs
@@ -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 + 'static,
{
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 + 'static,
{
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))
})
})
}
}

0 comments on commit bb27bac

Please sign in to comment.