1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
mod certs;
pub use certs::generate_cert;
use core::task::{Context, Poll};
use fs::File;
use futures_util::stream::Stream;
use rustls::internal::pemfile;
use rustls::{NoClientAuth, ServerConfig};
use std::path::PathBuf;
use std::pin::Pin;
use std::sync::Arc;
use std::vec::Vec;
use std::{fs, io};
use tokio::net::TcpStream;
use tokio_rustls::{server::TlsStream, TlsAcceptor};
use crate::settings::get_wrangler_home_dir;
pub(super) fn get_tls_acceptor() -> Result<TlsAcceptor, failure::Error> {
let home = get_wrangler_home_dir()?.join("config");
let cert = home.join("dev-cert.pem");
let privkey = home.join("dev-privkey.rsa");
let certs = load_certs(cert)?;
let key = load_private_key(privkey)?;
let mut cfg = ServerConfig::new(NoClientAuth::new());
cfg.set_single_cert(certs, key)
.map_err(|e| io_error(format!("{}", e)))?;
Ok(TlsAcceptor::from(Arc::new(cfg)))
}
pub(super) fn io_error(err: String) -> io::Error {
io::Error::new(io::ErrorKind::Other, err)
}
pub(super) struct HyperAcceptor<'a> {
pub(super) acceptor:
Pin<Box<dyn Stream<Item = Result<TlsStream<TcpStream>, io::Error>> + Send + 'a>>,
}
impl hyper::server::accept::Accept for HyperAcceptor<'_> {
type Conn = TlsStream<TcpStream>;
type Error = io::Error;
fn poll_accept(
mut self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
Pin::new(&mut self.acceptor).poll_next(cx)
}
}
fn get_tls_file(file: PathBuf) -> Result<File, io::Error> {
File::open(&file)
}
fn load_certs(file: PathBuf) -> io::Result<Vec<rustls::Certificate>> {
let certfile = get_tls_file(file)?;
let mut reader = io::BufReader::new(certfile);
pemfile::certs(&mut reader).map_err(|_| io_error("failed to load certificate".into()))
}
fn load_private_key(file: PathBuf) -> io::Result<rustls::PrivateKey> {
let keyfile = get_tls_file(file)?;
let mut reader = io::BufReader::new(keyfile);
let keys = pemfile::pkcs8_private_keys(&mut reader)
.map_err(|_| io_error("failed to load private key".into()))?;
if keys.len() != 1 {
return Err(io_error("expected a single private key".into()));
}
Ok(keys[0].clone())
}