tokio-rustls/tokio-rustls/examples/server/src/main.rs

100 lines
3.1 KiB
Rust
Raw Normal View History

2019-05-21 16:54:10 +00:00
use std::fs::File;
use std::sync::Arc;
use std::net::ToSocketAddrs;
2019-05-21 16:54:10 +00:00
use std::path::{ PathBuf, Path };
use std::io::{ self, BufReader };
2019-11-27 16:11:02 +00:00
use futures_util::future::TryFutureExt;
2019-05-21 16:54:10 +00:00
use structopt::StructOpt;
2019-11-27 16:11:02 +00:00
use tokio::runtime;
use tokio::net::TcpListener;
use tokio::io::{ AsyncWriteExt, copy, split };
2019-05-21 16:54:10 +00:00
use tokio_rustls::rustls::{ Certificate, NoClientAuth, PrivateKey, ServerConfig };
use tokio_rustls::rustls::internal::pemfile::{ certs, rsa_private_keys };
use tokio_rustls::TlsAcceptor;
#[derive(StructOpt)]
struct Options {
addr: String,
/// cert file
#[structopt(short="c", long="cert", parse(from_os_str))]
cert: PathBuf,
/// key file
#[structopt(short="k", long="key", parse(from_os_str))]
key: PathBuf,
/// echo mode
#[structopt(short="e", long="echo-mode")]
echo: 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"))
}
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"))
}
2019-05-21 16:54:10 +00:00
fn main() -> io::Result<()> {
let options = Options::from_args();
2019-05-21 16:54:10 +00:00
let addr = options.addr.to_socket_addrs()?
.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;
2019-11-27 16:11:02 +00:00
let mut runtime = runtime::Builder::new()
.threaded_scheduler()
.enable_io()
.build()?;
let handle = runtime.handle().clone();
let mut config = ServerConfig::new(NoClientAuth::new());
2019-05-21 16:54:10 +00:00
config.set_single_cert(certs, keys.remove(0))
.map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
let acceptor = TlsAcceptor::from(Arc::new(config));
let fut = async {
2019-11-27 16:11:02 +00:00
let mut listener = TcpListener::bind(&addr).await?;
2019-05-21 16:54:10 +00:00
2019-11-27 16:11:02 +00:00
loop {
let (stream, peer_addr) = listener.accept().await?;
2019-05-21 16:54:10 +00:00
let acceptor = acceptor.clone();
let fut = async move {
let mut stream = acceptor.accept(stream).await?;
if flag_echo {
2019-11-27 16:11:02 +00:00
let (mut reader, mut writer) = split(stream);
let n = copy(&mut reader, &mut writer).await?;
writer.flush().await?;
2019-05-21 16:54:10 +00:00
println!("Echo: {} - {}", peer_addr, n);
} else {
stream.write_all(
&b"HTTP/1.0 200 ok\r\n\
Connection: close\r\n\
Content-length: 12\r\n\
\r\n\
Hello world!"[..]
).await?;
stream.flush().await?;
println!("Hello: {}", peer_addr);
}
Ok(()) as io::Result<()>
};
2019-11-27 16:11:02 +00:00
handle.spawn(fut.unwrap_or_else(|err| eprintln!("{:?}", err)));
2019-05-21 16:54:10 +00:00
}
};
2019-11-27 16:11:02 +00:00
runtime.block_on(fut)
}