Skip to content

General housekeeping #17

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 8 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "tide-rustls"
version = "0.3.0"
authors = ["Jacob Rothstein <hi@jbr.me>"]
edition = "2018"
edition = "2024"
description = "tide tls listener based on async-rustls and rustls"
readme = "README.md"
repository = "https://github.com/jbr/tide-rustls"
Expand All @@ -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 }
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -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(())
})
}
```

Expand Down
2 changes: 1 addition & 1 deletion examples/hello_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async fn endpoint(req: tide::Request<()>) -> tide::Result<impl Into<tide::Respon
}

fn main() -> 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);
Expand Down
6 changes: 3 additions & 3 deletions src/custom_tls_acceptor.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
2 changes: 1 addition & 1 deletion src/tcp_connection.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use async_std::net::{SocketAddr, TcpListener};
use smol::net::{SocketAddr, TcpListener};
use std::fmt::{self, Debug, Display, Formatter};

#[derive(Debug)]
Expand Down
51 changes: 28 additions & 23 deletions src/tls_listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -88,9 +89,9 @@ impl<State> TlsListener<State> {
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(
Expand Down Expand Up @@ -143,7 +144,7 @@ fn handle_tls<State: Clone + Send + Sync + 'static>(
stream: TcpStream,
acceptor: Arc<dyn CustomTlsAcceptor>,
) {
task::spawn(async move {
smol::spawn(async move {
let local_addr = stream.local_addr().ok();
let peer_addr = stream.peer_addr().ok();

Expand Down Expand Up @@ -171,7 +172,7 @@ fn handle_tls<State: Clone + Send + Sync + 'static>(
tide::log::error!("tls error", { error: tls_error.to_string() });
}
}
});
}).detach();
}

impl<State: Clone + Send + Sync + 'static> ToListener<State> for TlsListener<State> {
Expand Down Expand Up @@ -210,7 +211,7 @@ impl<State: Clone + Send + Sync + 'static> Listener<State> for TlsListener<State
Err(error) => {
let delay = Duration::from_millis(500);
tide::log::error!("Error: {}. Pausing for {:?}.", error, delay);
task::sleep(delay).await;
smol::Timer::after(delay).await;
continue;
}

Expand Down Expand Up @@ -253,25 +254,29 @@ impl<State> Display for TlsListener<State> {
}
}

fn load_certs(path: &Path) -> io::Result<Vec<Certificate>> {
fn load_certs(path: &Path) -> io::Result<Vec<CertificateDer<'static>>> {
certs(&mut BufReader::new(File::open(path)?))
.collect::<Result<Vec<_>, _>>()
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))
}

fn load_keys(path: &Path) -> io::Result<Vec<PrivateKey>> {
fn load_keys(path: &Path) -> io::Result<Vec<PrivateKeyDer<'static>>> {
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::<Vec<_>>();
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::<Vec<_>>();
if !rsa.is_empty() {
return Ok(rsa);
}

Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
Expand Down
16 changes: 4 additions & 12 deletions src/tls_listener_builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use async_std::io;
use async_std::net::TcpListener;
use smol::io;
use smol::net::TcpListener;

use rustls::ServerConfig;

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -211,7 +203,7 @@ impl<State> TlsListenerBuilder<State> {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"need exactly one of cert + key, ServerConfig, or TLS acceptor",
))
));
}
};

Expand All @@ -222,7 +214,7 @@ impl<State> TlsListenerBuilder<State> {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"either tcp or addrs are required",
))
));
}
};

Expand Down
10 changes: 5 additions & 5 deletions src/tls_stream_wrapper.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -14,7 +14,7 @@ impl TlsStreamWrapper {
}
}

impl Read for TlsStreamWrapper {
impl AsyncRead for TlsStreamWrapper {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand All @@ -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<Result<usize>> {
Pin::new(&mut &*self.0).poll_write(cx, buf)
}
Expand Down