tokio-rustls/examples/server.rs

105 lines
3.1 KiB
Rust
Raw Normal View History

use argh::FromArgs;
[DRAFT] update `tokio-rustls` to `rustls` 0.20.x (#64) * update to rustls 0.20 Signed-off-by: Eliza Weisman <eliza@buoyant.io> * track simple renamings in rustls Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use reader/writer methods Signed-off-by: Eliza Weisman <eliza@buoyant.io> * fix find and replace Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use rustls-pemfile crate for pem file parsing Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update misc api breakage Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update client example with api changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update server example with new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update test_stream test Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update tests to use new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * rm unused imports Signed-off-by: Eliza Weisman <eliza@buoyant.io> * handle rustls `WouldBlock` on eof Signed-off-by: Eliza Weisman <eliza@buoyant.io> * expect rustls to return wouldblock in tests Signed-off-by: Eliza Weisman <eliza@buoyant.io> * i think this is *actually* the right EOF behavior Signed-off-by: Eliza Weisman <eliza@buoyant.io> * bump version Signed-off-by: Eliza Weisman <eliza@buoyant.io> * okay that seems to fix it Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update to track builder API changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * actually shutdown read side on close notify Signed-off-by: Eliza Weisman <eliza@buoyant.io> * Further updates to rustls 0.20 (#68) * Adapt to RootCertStore API changes * Handle UnexpectedEof errors * Rename would_block to io_pending * Try to make badssl test failures more verbose * Rebuild AsyncRead impl * Upgrade to current rustls * Revert to using assert!() * Update to rustls 0.20 * Forward rustls features Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2021-09-28 17:01:37 +00:00
use rustls_pemfile::{certs, rsa_private_keys};
2019-05-21 16:54:10 +00:00
use std::fs::File;
use std::io::{self, BufReader};
use std::net::ToSocketAddrs;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tokio::io::{copy, sink, split, AsyncWriteExt};
2019-11-27 16:11:02 +00:00
use tokio::net::TcpListener;
[DRAFT] update `tokio-rustls` to `rustls` 0.20.x (#64) * update to rustls 0.20 Signed-off-by: Eliza Weisman <eliza@buoyant.io> * track simple renamings in rustls Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use reader/writer methods Signed-off-by: Eliza Weisman <eliza@buoyant.io> * fix find and replace Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use rustls-pemfile crate for pem file parsing Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update misc api breakage Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update client example with api changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update server example with new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update test_stream test Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update tests to use new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * rm unused imports Signed-off-by: Eliza Weisman <eliza@buoyant.io> * handle rustls `WouldBlock` on eof Signed-off-by: Eliza Weisman <eliza@buoyant.io> * expect rustls to return wouldblock in tests Signed-off-by: Eliza Weisman <eliza@buoyant.io> * i think this is *actually* the right EOF behavior Signed-off-by: Eliza Weisman <eliza@buoyant.io> * bump version Signed-off-by: Eliza Weisman <eliza@buoyant.io> * okay that seems to fix it Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update to track builder API changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * actually shutdown read side on close notify Signed-off-by: Eliza Weisman <eliza@buoyant.io> * Further updates to rustls 0.20 (#68) * Adapt to RootCertStore API changes * Handle UnexpectedEof errors * Rename would_block to io_pending * Try to make badssl test failures more verbose * Rebuild AsyncRead impl * Upgrade to current rustls * Revert to using assert!() * Update to rustls 0.20 * Forward rustls features Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2021-09-28 17:01:37 +00:00
use tokio_rustls::rustls::{self, Certificate, PrivateKey};
2019-05-21 16:54:10 +00:00
use tokio_rustls::TlsAcceptor;
/// Tokio Rustls server example
#[derive(FromArgs)]
2019-05-21 16:54:10 +00:00
struct Options {
/// bind addr
#[argh(positional)]
2019-05-21 16:54:10 +00:00
addr: String,
/// cert file
#[argh(option, short = 'c')]
2019-05-21 16:54:10 +00:00
cert: PathBuf,
/// key file
#[argh(option, short = 'k')]
2019-05-21 16:54:10 +00:00
key: PathBuf,
/// echo mode
#[argh(switch, short = 'e')]
echo_mode: bool,
}
2019-05-21 16:54:10 +00:00
fn load_certs(path: &Path) -> io::Result<Vec<Certificate>> {
certs(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid cert"))
[DRAFT] update `tokio-rustls` to `rustls` 0.20.x (#64) * update to rustls 0.20 Signed-off-by: Eliza Weisman <eliza@buoyant.io> * track simple renamings in rustls Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use reader/writer methods Signed-off-by: Eliza Weisman <eliza@buoyant.io> * fix find and replace Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use rustls-pemfile crate for pem file parsing Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update misc api breakage Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update client example with api changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update server example with new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update test_stream test Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update tests to use new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * rm unused imports Signed-off-by: Eliza Weisman <eliza@buoyant.io> * handle rustls `WouldBlock` on eof Signed-off-by: Eliza Weisman <eliza@buoyant.io> * expect rustls to return wouldblock in tests Signed-off-by: Eliza Weisman <eliza@buoyant.io> * i think this is *actually* the right EOF behavior Signed-off-by: Eliza Weisman <eliza@buoyant.io> * bump version Signed-off-by: Eliza Weisman <eliza@buoyant.io> * okay that seems to fix it Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update to track builder API changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * actually shutdown read side on close notify Signed-off-by: Eliza Weisman <eliza@buoyant.io> * Further updates to rustls 0.20 (#68) * Adapt to RootCertStore API changes * Handle UnexpectedEof errors * Rename would_block to io_pending * Try to make badssl test failures more verbose * Rebuild AsyncRead impl * Upgrade to current rustls * Revert to using assert!() * Update to rustls 0.20 * Forward rustls features Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2021-09-28 17:01:37 +00:00
.map(|mut certs| certs.drain(..).map(Certificate).collect())
}
2019-05-21 16:54:10 +00:00
fn load_keys(path: &Path) -> io::Result<Vec<PrivateKey>> {
rsa_private_keys(&mut BufReader::new(File::open(path)?))
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "invalid key"))
[DRAFT] update `tokio-rustls` to `rustls` 0.20.x (#64) * update to rustls 0.20 Signed-off-by: Eliza Weisman <eliza@buoyant.io> * track simple renamings in rustls Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use reader/writer methods Signed-off-by: Eliza Weisman <eliza@buoyant.io> * fix find and replace Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use rustls-pemfile crate for pem file parsing Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update misc api breakage Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update client example with api changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update server example with new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update test_stream test Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update tests to use new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * rm unused imports Signed-off-by: Eliza Weisman <eliza@buoyant.io> * handle rustls `WouldBlock` on eof Signed-off-by: Eliza Weisman <eliza@buoyant.io> * expect rustls to return wouldblock in tests Signed-off-by: Eliza Weisman <eliza@buoyant.io> * i think this is *actually* the right EOF behavior Signed-off-by: Eliza Weisman <eliza@buoyant.io> * bump version Signed-off-by: Eliza Weisman <eliza@buoyant.io> * okay that seems to fix it Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update to track builder API changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * actually shutdown read side on close notify Signed-off-by: Eliza Weisman <eliza@buoyant.io> * Further updates to rustls 0.20 (#68) * Adapt to RootCertStore API changes * Handle UnexpectedEof errors * Rename would_block to io_pending * Try to make badssl test failures more verbose * Rebuild AsyncRead impl * Upgrade to current rustls * Revert to using assert!() * Update to rustls 0.20 * Forward rustls features Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2021-09-28 17:01:37 +00:00
.map(|mut keys| keys.drain(..).map(PrivateKey).collect())
}
#[tokio::main]
async fn main() -> io::Result<()> {
let options: Options = argh::from_env();
let addr = options
.addr
.to_socket_addrs()?
2019-05-21 16:54:10 +00:00
.next()
.ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?;
let certs = load_certs(&options.cert)?;
let mut keys = load_keys(&options.key)?;
let flag_echo = options.echo_mode;
[DRAFT] update `tokio-rustls` to `rustls` 0.20.x (#64) * update to rustls 0.20 Signed-off-by: Eliza Weisman <eliza@buoyant.io> * track simple renamings in rustls Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use reader/writer methods Signed-off-by: Eliza Weisman <eliza@buoyant.io> * fix find and replace Signed-off-by: Eliza Weisman <eliza@buoyant.io> * use rustls-pemfile crate for pem file parsing Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update misc api breakage Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update client example with api changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update server example with new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update test_stream test Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update tests to use new APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * rm unused imports Signed-off-by: Eliza Weisman <eliza@buoyant.io> * handle rustls `WouldBlock` on eof Signed-off-by: Eliza Weisman <eliza@buoyant.io> * expect rustls to return wouldblock in tests Signed-off-by: Eliza Weisman <eliza@buoyant.io> * i think this is *actually* the right EOF behavior Signed-off-by: Eliza Weisman <eliza@buoyant.io> * bump version Signed-off-by: Eliza Weisman <eliza@buoyant.io> * okay that seems to fix it Signed-off-by: Eliza Weisman <eliza@buoyant.io> * update to track builder API changes Signed-off-by: Eliza Weisman <eliza@buoyant.io> * actually shutdown read side on close notify Signed-off-by: Eliza Weisman <eliza@buoyant.io> * Further updates to rustls 0.20 (#68) * Adapt to RootCertStore API changes * Handle UnexpectedEof errors * Rename would_block to io_pending * Try to make badssl test failures more verbose * Rebuild AsyncRead impl * Upgrade to current rustls * Revert to using assert!() * Update to rustls 0.20 * Forward rustls features Co-authored-by: Dirkjan Ochtman <dirkjan@ochtman.nl>
2021-09-28 17:01:37 +00:00
let config = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(certs, keys.remove(0))
2019-05-21 16:54:10 +00:00
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
let acceptor = TlsAcceptor::from(Arc::new(config));
let listener = TcpListener::bind(&addr).await?;
2019-05-21 16:54:10 +00:00
loop {
let (stream, peer_addr) = listener.accept().await?;
let acceptor = acceptor.clone();
2019-05-21 16:54:10 +00:00
let fut = async move {
let mut stream = acceptor.accept(stream).await?;
2019-05-21 16:54:10 +00:00
if flag_echo {
let (mut reader, mut writer) = split(stream);
let n = copy(&mut reader, &mut writer).await?;
writer.flush().await?;
println!("Echo: {} - {}", peer_addr, n);
} else {
let mut output = sink();
stream
.write_all(
2019-05-21 16:54:10 +00:00
&b"HTTP/1.0 200 ok\r\n\
Connection: close\r\n\
Content-length: 12\r\n\
\r\n\
Hello world!"[..],
)
.await?;
stream.shutdown().await?;
copy(&mut stream, &mut output).await?;
println!("Hello: {}", peer_addr);
}
Ok(()) as io::Result<()>
};
tokio::spawn(async move {
if let Err(err) = fut.await {
eprintln!("{:?}", err);
}
});
}
}