mirror of
https://github.com/actix/actix-extras.git
synced 2025-06-29 19:24:58 +02:00
add rustls
This commit is contained in:
@ -310,3 +310,46 @@ impl IoStream for TlsStream<TcpStream> {
|
||||
self.get_mut().get_mut().set_linger(dur)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use rustls::{ClientSession, ServerSession};
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use tokio_rustls::TlsStream;
|
||||
|
||||
#[cfg(feature = "rust-tls")]
|
||||
impl IoStream for TlsStream<TcpStream, ClientSession> {
|
||||
#[inline]
|
||||
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
|
||||
let _ = <Self as AsyncWrite>::shutdown(self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
self.get_mut().0.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().0.set_linger(dur)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rust-tls")]
|
||||
impl IoStream for TlsStream<TcpStream, ServerSession> {
|
||||
#[inline]
|
||||
fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
|
||||
let _ = <Self as AsyncWrite>::shutdown(self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
self.get_mut().0.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().0.set_linger(dur)
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ use native_tls::TlsAcceptor;
|
||||
#[cfg(feature = "alpn")]
|
||||
use openssl::ssl::{AlpnError, SslAcceptorBuilder};
|
||||
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use rustls::ServerConfig;
|
||||
|
||||
use super::channel::{HttpChannel, WrapperStream};
|
||||
use super::settings::{ServerSettings, WorkerSettings};
|
||||
use super::worker::{Conn, SocketInfo, StopWorker, StreamHandlerType, Worker};
|
||||
@ -42,6 +45,14 @@ fn configure_alpn(builder: &mut SslAcceptorBuilder) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rust-tls", not(feature = "alpn")))]
|
||||
fn configure_alpn(builder: &mut Arc<ServerConfig>) -> io::Result<()> {
|
||||
Arc::<ServerConfig>::get_mut(builder)
|
||||
.unwrap()
|
||||
.set_protocols(&vec!["h2".to_string(), "http/1.1".to_string()]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// An HTTP Server
|
||||
pub struct HttpServer<H>
|
||||
where
|
||||
@ -265,6 +276,26 @@ where
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rust-tls", not(feature = "alpn")))]
|
||||
/// Use listener for accepting incoming tls connection requests
|
||||
///
|
||||
/// This method sets alpn protocols to "h2" and "http/1.1"
|
||||
pub fn listen_ssl(
|
||||
mut self, lst: net::TcpListener, mut builder: Arc<ServerConfig>,
|
||||
) -> io::Result<Self> {
|
||||
// alpn support
|
||||
if !self.no_http2 {
|
||||
configure_alpn(&mut builder)?;
|
||||
}
|
||||
let addr = lst.local_addr().unwrap();
|
||||
self.sockets.push(Socket {
|
||||
addr,
|
||||
lst,
|
||||
tp: StreamHandlerType::Rustls(builder.clone()),
|
||||
});
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn bind2<S: net::ToSocketAddrs>(&mut self, addr: S) -> io::Result<Vec<Socket>> {
|
||||
let mut err = None;
|
||||
let mut succ = false;
|
||||
@ -343,6 +374,26 @@ where
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rust-tls", not(feature = "alpn")))]
|
||||
/// Start listening for incoming tls connections.
|
||||
///
|
||||
/// This method sets alpn protocols to "h2" and "http/1.1"
|
||||
pub fn bind_ssl<S: net::ToSocketAddrs>(
|
||||
mut self, addr: S, mut builder: Arc<ServerConfig>,
|
||||
) -> io::Result<Self> {
|
||||
// alpn support
|
||||
if !self.no_http2 {
|
||||
configure_alpn(&mut builder)?;
|
||||
}
|
||||
|
||||
let sockets = self.bind2(addr)?;
|
||||
self.sockets.extend(sockets.into_iter().map(|mut s| {
|
||||
s.tp = StreamHandlerType::Rustls(builder.clone());
|
||||
s
|
||||
}));
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn start_workers(
|
||||
&mut self, settings: &ServerSettings, sockets: &Slab<SocketInfo>,
|
||||
) -> Vec<(usize, mpsc::UnboundedSender<Conn<net::TcpStream>>)> {
|
||||
|
@ -8,7 +8,7 @@ use tokio::executor::current_thread;
|
||||
use tokio_reactor::Handle;
|
||||
use tokio_tcp::TcpStream;
|
||||
|
||||
#[cfg(any(feature = "tls", feature = "alpn"))]
|
||||
#[cfg(any(feature = "tls", feature = "alpn", feature = "rust-tls"))]
|
||||
use futures::future;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
@ -21,6 +21,13 @@ use openssl::ssl::SslAcceptor;
|
||||
#[cfg(feature = "alpn")]
|
||||
use tokio_openssl::SslAcceptorExt;
|
||||
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use rustls::{ServerConfig, Session};
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use std::sync::Arc;
|
||||
#[cfg(feature = "rust-tls")]
|
||||
use tokio_rustls::ServerConfigExt;
|
||||
|
||||
use actix::msgs::StopArbiter;
|
||||
use actix::{Actor, Arbiter, AsyncContext, Context, Handler, Message, Response};
|
||||
|
||||
@ -170,6 +177,8 @@ pub(crate) enum StreamHandlerType {
|
||||
Tls(TlsAcceptor),
|
||||
#[cfg(feature = "alpn")]
|
||||
Alpn(SslAcceptor),
|
||||
#[cfg(feature = "rust-tls")]
|
||||
Rustls(Arc<ServerConfig>),
|
||||
}
|
||||
|
||||
impl StreamHandlerType {
|
||||
@ -237,6 +246,36 @@ impl StreamHandlerType {
|
||||
},
|
||||
));
|
||||
}
|
||||
#[cfg(feature = "rust-tls")]
|
||||
StreamHandlerType::Rustls(ref acceptor) => {
|
||||
let Conn { io, peer, .. } = msg;
|
||||
let _ = io.set_nodelay(true);
|
||||
let io = TcpStream::from_std(io, &Handle::default())
|
||||
.expect("failed to associate TCP stream");
|
||||
|
||||
current_thread::spawn(ServerConfigExt::accept_async(acceptor, io).then(
|
||||
move |res| {
|
||||
match res {
|
||||
Ok(io) => {
|
||||
let http2 = if let Some(p) =
|
||||
io.get_ref().1.get_alpn_protocol()
|
||||
{
|
||||
p.len() == 2 && &p == &"h2"
|
||||
} else {
|
||||
false
|
||||
};
|
||||
current_thread::spawn(HttpChannel::new(
|
||||
h, io, peer, http2,
|
||||
));
|
||||
}
|
||||
Err(err) => {
|
||||
trace!("Error during handling tls connection: {}", err)
|
||||
}
|
||||
};
|
||||
future::result(Ok(()))
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,6 +286,8 @@ impl StreamHandlerType {
|
||||
StreamHandlerType::Tls(_) => "https",
|
||||
#[cfg(feature = "alpn")]
|
||||
StreamHandlerType::Alpn(_) => "https",
|
||||
#[cfg(feature = "rust-tls")]
|
||||
StreamHandlerType::Rustls(_) => "https",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user