Skip to content

Commit 10564cf

Browse files
committed
Merge branch 'rustls'
* rustls: simplify generation of certificates simplify creation of tls_cfg refactor: change use-style static dispatched Stream create HTTPS server
2 parents 73360f7 + 9c3a1a5 commit 10564cf

File tree

6 files changed

+186
-64
lines changed

6 files changed

+186
-64
lines changed

Cargo.lock

Lines changed: 4 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
[package]
2-
name = "hyper-rustls-prac"
2+
name = "hyper-rustls-example"
33
version = "0.1.0"
44
authors = ["Ryo Ota <nwtgck@nwtgck.org>"]
55
edition = "2018"
66

77
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
88

99
[dependencies]
10-
hyper = { version = "0.13.0", default-features = false }
11-
tokio = { version = "0.2", features = ["full"] }
10+
hyper = "0.13.0"
11+
tokio = { version = "0.2", features = ["rt-threaded", "macros"] }
1212
rustls = "0.18"
1313
hyper-rustls = "0.21.0"
14+
futures-util = "0.3.1"
15+
tokio-rustls = "0.14.0"

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,25 @@
1-
# hyper-rustls-prac
1+
# hyper-rustls-example
2+
Simple example of [hyper-rustls](https://github.com/ctz/hyper-rustls)
3+
4+
## Run
5+
6+
Run as follows.
7+
8+
```bash
9+
cargo run
10+
```
11+
12+
Access to the server as follows.
13+
14+
```bash
15+
curl -k https://localhost:3000/
16+
```
17+
18+
## Make self-signed certificates by yourself
19+
20+
You can make certificates as follows.
21+
22+
```bash
23+
mkdir ssl_certs && cd ssl_certs && openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -sha256 -nodes --subj '/CN=localhost/' && cd -
24+
```
25+

src/main.rs

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,95 @@
1+
use futures_util::future::TryFutureExt;
2+
use futures_util::stream::{Stream, TryStreamExt};
3+
use hyper::service::{make_service_fn, service_fn};
4+
use hyper::{Body, Request, Response, Server};
15
use std::convert::Infallible;
6+
use std::io;
27
use std::net::SocketAddr;
3-
use hyper::{Body, Request, Response, Server};
4-
use hyper::service::{make_service_fn, service_fn};
8+
use tokio::net::{TcpListener, TcpStream};
9+
use tokio_rustls::server::TlsStream;
10+
use tokio_rustls::TlsAcceptor;
511

612
async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
713
Ok(Response::new("Hello, World".into()))
814
}
915

16+
fn error(err: String) -> std::io::Error {
17+
std::io::Error::new(std::io::ErrorKind::Other, err)
18+
}
19+
1020
#[tokio::main]
11-
async fn main() {
21+
async fn main() -> io::Result<()> {
1222
// We'll bind to 127.0.0.1:3000
1323
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
1424

25+
// Build TLS configuration.
26+
let tls_cfg = {
27+
// Load public certificate.
28+
let mut cert_reader = io::BufReader::new(std::fs::File::open("./ssl_certs/server.crt")?);
29+
let certs = rustls::internal::pemfile::certs(&mut cert_reader).unwrap();
30+
// Load private key.
31+
let mut key_reader = io::BufReader::new(std::fs::File::open("./ssl_certs/server.key")?);
32+
// Load and return a single private key.
33+
let mut keys = rustls::internal::pemfile::pkcs8_private_keys(&mut key_reader).unwrap();
34+
// Do not use client certificate authentication.
35+
let mut cfg = rustls::ServerConfig::new(rustls::NoClientAuth::new());
36+
// Select a certificate to use.
37+
cfg.set_single_cert(certs, keys.remove(0)).unwrap();
38+
// Configure ALPN to accept HTTP/2, HTTP/1.1 in that order.
39+
cfg.set_protocols(&[b"h2".to_vec(), b"http/1.1".to_vec()]);
40+
std::sync::Arc::new(cfg)
41+
};
42+
43+
// Create a TCP listener via tokio.
44+
let mut tcp = TcpListener::bind(&addr).await?;
45+
let tls_acceptor = TlsAcceptor::from(tls_cfg);
46+
// Prepare a long-running future stream to accept and serve clients.
47+
let incoming_tls_stream = tcp
48+
.incoming()
49+
.map_err(|e| error(format!("Incoming failed: {:?}", e)))
50+
.and_then(move |s| {
51+
tls_acceptor.accept(s).map_err(|e| {
52+
println!("[!] Voluntary server halt due to client-connection error...");
53+
// Errors could be handled here, instead of server aborting.
54+
// Ok(None)
55+
error(format!("TLS Error: {:?}", e))
56+
})
57+
});
58+
1559
// A `Service` is needed for every connection, so this
1660
// creates one from our `hello_world` function.
1761
let make_svc = make_service_fn(|_conn| async {
1862
// service_fn converts our function into a `Service`
1963
Ok::<_, Infallible>(service_fn(hello_world))
2064
});
2165

22-
let server = Server::bind(&addr).serve(make_svc);
66+
let server = Server::builder(HyperAcceptor {
67+
acceptor: Box::pin(incoming_tls_stream),
68+
})
69+
.serve(make_svc);
2370

2471
// Run this server for... forever!
2572
if let Err(e) = server.await {
2673
eprintln!("server error: {}", e);
2774
}
75+
Ok(())
76+
}
77+
78+
struct HyperAcceptor<S> {
79+
acceptor: core::pin::Pin<Box<S>>,
80+
}
81+
82+
impl<S> hyper::server::accept::Accept for HyperAcceptor<S>
83+
where
84+
S: Stream<Item = Result<TlsStream<TcpStream>, io::Error>>,
85+
{
86+
type Conn = TlsStream<TcpStream>;
87+
type Error = io::Error;
88+
89+
fn poll_accept(
90+
mut self: core::pin::Pin<&mut Self>,
91+
cx: &mut core::task::Context,
92+
) -> core::task::Poll<Option<Result<Self::Conn, Self::Error>>> {
93+
self.acceptor.as_mut().poll_next(cx)
94+
}
2895
}

ssl_certs/server.crt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIFCTCCAvGgAwIBAgIUQmZTN5CEHIxNl5vqjCc3MuCPduswDQYJKoZIhvcNAQEL
3+
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIwMDgyNDEyMjczNloXDTIxMDgy
4+
NDEyMjczNlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
5+
AAOCAg8AMIICCgKCAgEAyxZFBEhSLGP7hDMx1QDl3PZCUAdDYYw/DFUYjQ+uLSfZ
6+
izkJJASUozn1+fVqC6u9On8jPxeVA9JgrNhj/GJVSdWtm8E6uJAHiKLq0OzHIaSd
7+
zXWD3XxFNtcMr7Zl5T/qpujxG0gpx8h3SFhMS96wMRwt7F5DI/6db2laOjo1rwFP
8+
tqWij9ZSsdsyOjm9FrCEWZd6IvMxZWNU4E3MetZGlHzle1GhDG891GuswYaait3Z
9+
HFLRihRKwYQKb7xSzCtfX8G6fuuBI/9F7GkpLYHcUyFYdEfWPSbQupJp2p10+NQC
10+
x7IaEFIaAK274xiRX4aDeddUm1IZb0Muhf2QLfSpFa6gnlhdrDNpx5I/KZT3ENMv
11+
FBOdUrsqOfxXhoY7Gze0BlQtfKUJnjZkD5bAX7U+5kEc5yH6tRpVvIJGJavaZGIr
12+
H9v2slEYEl8SpjZ9JP58EFqAUQVwNn5oTwUm+E1MN7U6N/JkPgGc77aQwtUYO6bc
13+
yHry90kmVf5gO5YZIMl4Sk16G+/vPciNRGJBa4qPXfE2mPhKl8z6qMrX10aI2MxR
14+
iuCMGuK+h5T04VQazr7km2pd37U1YcY0vKoAgxnbvD7nEex44ping7z7Sep5zN4o
15+
1jPVNNLLQlMSkK9lIBH+P0I6LMkccoXHqt6I5owaP2gdp97MXA/DisZXsDOXXEUC
16+
AwEAAaNTMFEwHQYDVR0OBBYEFEzLSxAwMQ3mZ+CanTTnLClaoGqZMB8GA1UdIwQY
17+
MBaAFEzLSxAwMQ3mZ+CanTTnLClaoGqZMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
18+
hvcNAQELBQADggIBAJYpP/1W2ZKwNxXUhqNfICzDtJklQsvuWCAMLwKmNpuIbLbt
19+
37ginllGXul/I/eWu3lNLsDadkfOMjPTUQprT9kEEN+rXQ8wohMUTfCXyd3ThQUJ
20+
/9aJe41idP2LHEptXLROWXNRGnVew3BecVAao5tHjiRlbVU/c+rO++0Cn6e16zhM
21+
o9U9se0T+Ce5Q3OAV0F/oWC0sdEC9EBS3EVbo+xDRLIWzfSyOKEEr4XRySgMRTme
22+
tYCs0OYKvdCe3iYqSY+OAauEGb01T5D6URqDMCoi3mkffBqWnVKEZ+MR2BfznV3Y
23+
N0kF9FxNy+D+1jpJ33e0TV1+zrUKs6n4hqD/inVWO4d+OP3OEZGvvpxVsxfcPo3d
24+
Q0BBMw0c/qcgnukR5TH9I8/RmkLG9bgfcq2s2sgwli2jXrDwqLIVsIRejpjC+aNI
25+
mClWTZ92+mI1l7wPIhdh1kM6oKjxUHgOrF+YRuVWnBH4edstq5Q67Mg5JYOIqEvZ
26+
a+G+LSCCY0d9cQ3RBLg/nlhlvxzHzh8ThEq1uVyXdqpzkQ1aCNR3lwPXwVOTSQuT
27+
pz8hVGPTKRIuv+VZU0Dgcd+T4zStWBHf26vYEn/d5Sw5lAj1enO2AQ9simJjH0QD
28+
VJhBKColzck4G7k+mvZr+aIntojbnUsEcFwqtlZ2pL5BRc6MXxD5RLt9jmPD
29+
-----END CERTIFICATE-----

ssl_certs/server.key

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-----BEGIN PRIVATE KEY-----
2+
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
51+
ILFkgCCKfn/6BJGkLTf/dT4ekHP5OOc=
52+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)