diff --git a/Cargo.toml b/Cargo.toml index b1c1c08..1df7077 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "tide-rustls" version = "0.3.0" authors = ["Jacob Rothstein "] -edition = "2018" +edition = "2024" description = "tide tls listener based on async-rustls and rustls" readme = "README.md" repository = "https://github.com/jbr/tide-rustls" @@ -12,9 +12,10 @@ keywords = ["tide", "https", "tls"] categories = ["web-programming::http-server", "web-programming"] [dependencies] -async-std = "1.9.0" -tide = { version = "0.16.0", default-features = false } -async-rustls = "0.2.0" -rustls = "0.19.0" -async-h1 = "2.3.2" -async-dup = "1.2.2" +async-dup = "1.2" +async-h1 = "2.3" +futures-rustls = "0.26" +rustls = "0.23" +rustls-pemfile = "2.2" +smol = "2.0" +tide = { version = "0.16", default-features = false } diff --git a/README.md b/README.md index 04831b2..ca5ab10 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Tide rustls listener -## tls listener for [tide](https://github.com/http-rs/tide) based on [async-rustls](https://github.com/smol-rs/async-rustls) +A TLS listener for [tide](https://github.com/http-rs/tide), based on `futures-rustls`. * [CI ![CI][ci-badge]][ci] * [API Docs][docs] [![docs.rs docs][docs-badge]][docs] @@ -21,18 +21,19 @@ $ cargo add tide-rustls ## Using with tide ```rust -#[async_std::main] -async fn main() -> tide::Result<()> { - let mut app = tide::new(); - app.at("/").get(|_| async { Ok("Hello TLS") }); - app.listen( - TlsListener::build() - .addrs("localhost:4433") - .cert(std::env::var("TIDE_CERT_PATH").unwrap()) - .key(std::env::var("TIDE_KEY_PATH").unwrap()), - ) - .await?; - Ok(()) +fn main() -> tide::Result<()> { + smol::block_on(async { + let mut app = tide::new(); + app.at("/").get(|_| async { Ok("Hello TLS") }); + app.listen( + TlsListener::build() + .addrs("localhost:4433") + .cert(std::env::var("TIDE_CERT_PATH").unwrap()) + .key(std::env::var("TIDE_KEY_PATH").unwrap()), + ) + .await?; + Ok(()) + }) } ``` diff --git a/examples/hello_tls.rs b/examples/hello_tls.rs index dda97fa..0064c48 100644 --- a/examples/hello_tls.rs +++ b/examples/hello_tls.rs @@ -11,7 +11,7 @@ async fn endpoint(req: tide::Request<()>) -> tide::Result std::io::Result<()> { - async_std::task::block_on(async { + smol::block_on(async { let mut app = tide::new(); app.at("*").all(endpoint); app.at("/").all(endpoint); diff --git a/src/custom_tls_acceptor.rs b/src/custom_tls_acceptor.rs index 37e0d07..edcd455 100644 --- a/src/custom_tls_acceptor.rs +++ b/src/custom_tls_acceptor.rs @@ -1,5 +1,5 @@ -use async_rustls::server::TlsStream; -use async_std::net::TcpStream; +use futures_rustls::server::TlsStream; +use smol::net::TcpStream; /// The CustomTlsAcceptor trait provides a custom implementation of accepting /// TLS connections from a [`TcpStream`]. tide-rustls will call the @@ -21,7 +21,7 @@ pub trait CustomTlsAcceptor: Send + Sync { /// Crate-private adapter to make `async_rustls::TlsAcceptor` implement /// `CustomTlsAcceptor`, without creating a conflict between the two `accept` /// methods. -pub(crate) struct StandardTlsAcceptor(pub(crate) async_rustls::TlsAcceptor); +pub(crate) struct StandardTlsAcceptor(pub(crate) futures_rustls::TlsAcceptor); #[tide::utils::async_trait] impl CustomTlsAcceptor for StandardTlsAcceptor { diff --git a/src/lib.rs b/src/lib.rs index 6c7907c..bcc594f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ //! # Example //! ```rust //! # use tide_rustls::TlsListener; -//! # fn main() -> tide::Result<()> { async_std::task::block_on(async { +//! # fn main() -> tide::Result<()> { smol::block_on(async { //! let mut app = tide::new(); //! app.at("/").get(|_| async { Ok("Hello tls") }); //! # if false { @@ -42,5 +42,5 @@ pub use custom_tls_acceptor::CustomTlsAcceptor; pub use tls_listener::TlsListener; pub use tls_listener_builder::TlsListenerBuilder; -pub use async_rustls; +pub use futures_rustls; pub use rustls; diff --git a/src/tcp_connection.rs b/src/tcp_connection.rs index 11d09ca..e45b036 100644 --- a/src/tcp_connection.rs +++ b/src/tcp_connection.rs @@ -1,4 +1,4 @@ -use async_std::net::{SocketAddr, TcpListener}; +use smol::net::{SocketAddr, TcpListener}; use std::fmt::{self, Debug, Display, Formatter}; #[derive(Debug)] diff --git a/src/tls_listener.rs b/src/tls_listener.rs index 1fdac5c..720acda 100644 --- a/src/tls_listener.rs +++ b/src/tls_listener.rs @@ -3,17 +3,18 @@ use crate::{ CustomTlsAcceptor, TcpConnection, TlsListenerBuilder, TlsListenerConfig, TlsStreamWrapper, }; +use tide::Server; use tide::listener::ListenInfo; use tide::listener::{Listener, ToListener}; -use tide::Server; -use async_std::net::{TcpListener, TcpStream}; -use async_std::prelude::*; -use async_std::{io, task}; +use smol; +use smol::net::{TcpListener, TcpStream}; +use smol::{io, prelude::*}; -use async_rustls::TlsAcceptor; -use rustls::internal::pemfile::{certs, pkcs8_private_keys, rsa_private_keys}; -use rustls::{Certificate, NoClientAuth, PrivateKey, ServerConfig}; +use futures_rustls::TlsAcceptor; +use rustls::ServerConfig; +use rustls::pki_types::{CertificateDer, PrivateKeyDer}; +use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys}; use std::fmt::{self, Debug, Display, Formatter}; use std::fs::File; @@ -88,9 +89,9 @@ impl TlsListener { TlsListenerConfig::Paths { cert, key } => { let certs = load_certs(&cert)?; let mut keys = load_keys(&key)?; - let mut config = ServerConfig::new(NoClientAuth::new()); - config - .set_single_cert(certs, keys.remove(0)) + let config = ServerConfig::builder() + .with_no_client_auth() + .with_single_cert(certs, keys.remove(0)) .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?; TlsListenerConfig::Acceptor(Arc::new(StandardTlsAcceptor(TlsAcceptor::from( @@ -143,7 +144,7 @@ fn handle_tls( stream: TcpStream, acceptor: Arc, ) { - task::spawn(async move { + smol::spawn(async move { let local_addr = stream.local_addr().ok(); let peer_addr = stream.peer_addr().ok(); @@ -171,7 +172,7 @@ fn handle_tls( tide::log::error!("tls error", { error: tls_error.to_string() }); } } - }); + }).detach(); } impl ToListener for TlsListener { @@ -210,7 +211,7 @@ impl Listener for TlsListener { let delay = Duration::from_millis(500); tide::log::error!("Error: {}. Pausing for {:?}.", error, delay); - task::sleep(delay).await; + smol::Timer::after(delay).await; continue; } @@ -253,25 +254,29 @@ impl Display for TlsListener { } } -fn load_certs(path: &Path) -> io::Result> { +fn load_certs(path: &Path) -> io::Result>> { certs(&mut BufReader::new(File::open(path)?)) + .collect::, _>>() .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert")) } -fn load_keys(path: &Path) -> io::Result> { +fn load_keys(path: &Path) -> io::Result>> { let mut bufreader = BufReader::new(File::open(path)?); - if let Ok(pkcs8) = pkcs8_private_keys(&mut bufreader) { - if !pkcs8.is_empty() { - return Ok(pkcs8); - } + + let pkcs8 = pkcs8_private_keys(&mut bufreader) + .filter_map(|pk| Some(PrivateKeyDer::Pkcs8(pk.ok()?))) + .collect::>(); + if !pkcs8.is_empty() { + return Ok(pkcs8); } bufreader.seek(SeekFrom::Start(0))?; - if let Ok(rsa) = rsa_private_keys(&mut bufreader) { - if !rsa.is_empty() { - return Ok(rsa); - } + let rsa = rsa_private_keys(&mut bufreader) + .filter_map(|pk| Some(PrivateKeyDer::Pkcs1(pk.ok()?))) + .collect::>(); + if !rsa.is_empty() { + return Ok(rsa); } Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid key")) diff --git a/src/tls_listener_builder.rs b/src/tls_listener_builder.rs index 373e7e0..8a70ca1 100644 --- a/src/tls_listener_builder.rs +++ b/src/tls_listener_builder.rs @@ -1,5 +1,5 @@ -use async_std::io; -use async_std::net::TcpListener; +use smol::io; +use smol::net::TcpListener; use rustls::ServerConfig; @@ -31,14 +31,6 @@ use std::sync::Arc; /// ```rust /// # use tide_rustls::TlsListener; /// let listener = TlsListener::<()>::build() -/// .tcp(std::net::TcpListener::bind("localhost:4433").unwrap()) -/// .config(rustls::ServerConfig::new(rustls::NoClientAuth::new())) -/// .finish(); -/// ``` -/// -/// ```rust -/// # use tide_rustls::TlsListener; -/// let listener = TlsListener::<()>::build() /// .addrs("localhost:4433") /// .cert("./tls/localhost-4433.cert") /// .key("./tls/localhost-4433.key") @@ -211,7 +203,7 @@ impl TlsListenerBuilder { return Err(io::Error::new( io::ErrorKind::InvalidInput, "need exactly one of cert + key, ServerConfig, or TLS acceptor", - )) + )); } }; @@ -222,7 +214,7 @@ impl TlsListenerBuilder { return Err(io::Error::new( io::ErrorKind::InvalidInput, "either tcp or addrs are required", - )) + )); } }; diff --git a/src/tls_stream_wrapper.rs b/src/tls_stream_wrapper.rs index 27d73b9..fc35299 100644 --- a/src/tls_stream_wrapper.rs +++ b/src/tls_stream_wrapper.rs @@ -1,7 +1,7 @@ use async_dup::{Arc, Mutex}; -use async_rustls::server::TlsStream; -use async_std::io::{Read, Result, Write}; -use async_std::net::TcpStream; +use futures_rustls::server::TlsStream; +use smol::io::{AsyncRead, AsyncWrite, Result}; +use smol::net::TcpStream; use std::pin::Pin; use std::task::{Context, Poll}; @@ -14,7 +14,7 @@ impl TlsStreamWrapper { } } -impl Read for TlsStreamWrapper { +impl AsyncRead for TlsStreamWrapper { fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, @@ -24,7 +24,7 @@ impl Read for TlsStreamWrapper { } } -impl Write for TlsStreamWrapper { +impl AsyncWrite for TlsStreamWrapper { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { Pin::new(&mut &*self.0).poll_write(cx, buf) }