192f3ab15Sopenharmony_ciuse std::io::{Read, Write};
292f3ab15Sopenharmony_ciuse std::net::{SocketAddr, TcpListener, TcpStream};
392f3ab15Sopenharmony_ciuse std::thread::{self, JoinHandle};
492f3ab15Sopenharmony_ci
592f3ab15Sopenharmony_ciuse crate::ssl::{Ssl, SslContext, SslContextBuilder, SslFiletype, SslMethod, SslRef, SslStream};
692f3ab15Sopenharmony_ci
792f3ab15Sopenharmony_cipub struct Server {
892f3ab15Sopenharmony_ci    handle: Option<JoinHandle<()>>,
992f3ab15Sopenharmony_ci    addr: SocketAddr,
1092f3ab15Sopenharmony_ci}
1192f3ab15Sopenharmony_ci
1292f3ab15Sopenharmony_ciimpl Drop for Server {
1392f3ab15Sopenharmony_ci    fn drop(&mut self) {
1492f3ab15Sopenharmony_ci        if !thread::panicking() {
1592f3ab15Sopenharmony_ci            self.handle.take().unwrap().join().unwrap();
1692f3ab15Sopenharmony_ci        }
1792f3ab15Sopenharmony_ci    }
1892f3ab15Sopenharmony_ci}
1992f3ab15Sopenharmony_ci
2092f3ab15Sopenharmony_ciimpl Server {
2192f3ab15Sopenharmony_ci    pub fn builder() -> Builder {
2292f3ab15Sopenharmony_ci        let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
2392f3ab15Sopenharmony_ci        ctx.set_certificate_chain_file("test/cert.pem").unwrap();
2492f3ab15Sopenharmony_ci        ctx.set_private_key_file("test/key.pem", SslFiletype::PEM)
2592f3ab15Sopenharmony_ci            .unwrap();
2692f3ab15Sopenharmony_ci
2792f3ab15Sopenharmony_ci        Builder {
2892f3ab15Sopenharmony_ci            ctx,
2992f3ab15Sopenharmony_ci            ssl_cb: Box::new(|_| {}),
3092f3ab15Sopenharmony_ci            io_cb: Box::new(|_| {}),
3192f3ab15Sopenharmony_ci            should_error: false,
3292f3ab15Sopenharmony_ci        }
3392f3ab15Sopenharmony_ci    }
3492f3ab15Sopenharmony_ci
3592f3ab15Sopenharmony_ci    pub fn client(&self) -> ClientBuilder {
3692f3ab15Sopenharmony_ci        ClientBuilder {
3792f3ab15Sopenharmony_ci            ctx: SslContext::builder(SslMethod::tls()).unwrap(),
3892f3ab15Sopenharmony_ci            addr: self.addr,
3992f3ab15Sopenharmony_ci        }
4092f3ab15Sopenharmony_ci    }
4192f3ab15Sopenharmony_ci
4292f3ab15Sopenharmony_ci    pub fn connect_tcp(&self) -> TcpStream {
4392f3ab15Sopenharmony_ci        TcpStream::connect(self.addr).unwrap()
4492f3ab15Sopenharmony_ci    }
4592f3ab15Sopenharmony_ci}
4692f3ab15Sopenharmony_ci
4792f3ab15Sopenharmony_cipub struct Builder {
4892f3ab15Sopenharmony_ci    ctx: SslContextBuilder,
4992f3ab15Sopenharmony_ci    ssl_cb: Box<dyn FnMut(&mut SslRef) + Send>,
5092f3ab15Sopenharmony_ci    io_cb: Box<dyn FnMut(SslStream<TcpStream>) + Send>,
5192f3ab15Sopenharmony_ci    should_error: bool,
5292f3ab15Sopenharmony_ci}
5392f3ab15Sopenharmony_ci
5492f3ab15Sopenharmony_ciimpl Builder {
5592f3ab15Sopenharmony_ci    pub fn ctx(&mut self) -> &mut SslContextBuilder {
5692f3ab15Sopenharmony_ci        &mut self.ctx
5792f3ab15Sopenharmony_ci    }
5892f3ab15Sopenharmony_ci
5992f3ab15Sopenharmony_ci    pub fn ssl_cb<F>(&mut self, cb: F)
6092f3ab15Sopenharmony_ci    where
6192f3ab15Sopenharmony_ci        F: 'static + FnMut(&mut SslRef) + Send,
6292f3ab15Sopenharmony_ci    {
6392f3ab15Sopenharmony_ci        self.ssl_cb = Box::new(cb);
6492f3ab15Sopenharmony_ci    }
6592f3ab15Sopenharmony_ci
6692f3ab15Sopenharmony_ci    pub fn io_cb<F>(&mut self, cb: F)
6792f3ab15Sopenharmony_ci    where
6892f3ab15Sopenharmony_ci        F: 'static + FnMut(SslStream<TcpStream>) + Send,
6992f3ab15Sopenharmony_ci    {
7092f3ab15Sopenharmony_ci        self.io_cb = Box::new(cb);
7192f3ab15Sopenharmony_ci    }
7292f3ab15Sopenharmony_ci
7392f3ab15Sopenharmony_ci    pub fn should_error(&mut self) {
7492f3ab15Sopenharmony_ci        self.should_error = true;
7592f3ab15Sopenharmony_ci    }
7692f3ab15Sopenharmony_ci
7792f3ab15Sopenharmony_ci    pub fn build(self) -> Server {
7892f3ab15Sopenharmony_ci        let ctx = self.ctx.build();
7992f3ab15Sopenharmony_ci        let socket = TcpListener::bind("127.0.0.1:0").unwrap();
8092f3ab15Sopenharmony_ci        let addr = socket.local_addr().unwrap();
8192f3ab15Sopenharmony_ci        let mut ssl_cb = self.ssl_cb;
8292f3ab15Sopenharmony_ci        let mut io_cb = self.io_cb;
8392f3ab15Sopenharmony_ci        let should_error = self.should_error;
8492f3ab15Sopenharmony_ci
8592f3ab15Sopenharmony_ci        let handle = thread::spawn(move || {
8692f3ab15Sopenharmony_ci            let socket = socket.accept().unwrap().0;
8792f3ab15Sopenharmony_ci            let mut ssl = Ssl::new(&ctx).unwrap();
8892f3ab15Sopenharmony_ci            ssl_cb(&mut ssl);
8992f3ab15Sopenharmony_ci            let r = ssl.accept(socket);
9092f3ab15Sopenharmony_ci            if should_error {
9192f3ab15Sopenharmony_ci                r.unwrap_err();
9292f3ab15Sopenharmony_ci            } else {
9392f3ab15Sopenharmony_ci                let mut socket = r.unwrap();
9492f3ab15Sopenharmony_ci                socket.write_all(&[0]).unwrap();
9592f3ab15Sopenharmony_ci                io_cb(socket);
9692f3ab15Sopenharmony_ci            }
9792f3ab15Sopenharmony_ci        });
9892f3ab15Sopenharmony_ci
9992f3ab15Sopenharmony_ci        Server {
10092f3ab15Sopenharmony_ci            handle: Some(handle),
10192f3ab15Sopenharmony_ci            addr,
10292f3ab15Sopenharmony_ci        }
10392f3ab15Sopenharmony_ci    }
10492f3ab15Sopenharmony_ci}
10592f3ab15Sopenharmony_ci
10692f3ab15Sopenharmony_cipub struct ClientBuilder {
10792f3ab15Sopenharmony_ci    ctx: SslContextBuilder,
10892f3ab15Sopenharmony_ci    addr: SocketAddr,
10992f3ab15Sopenharmony_ci}
11092f3ab15Sopenharmony_ci
11192f3ab15Sopenharmony_ciimpl ClientBuilder {
11292f3ab15Sopenharmony_ci    pub fn ctx(&mut self) -> &mut SslContextBuilder {
11392f3ab15Sopenharmony_ci        &mut self.ctx
11492f3ab15Sopenharmony_ci    }
11592f3ab15Sopenharmony_ci
11692f3ab15Sopenharmony_ci    pub fn build(self) -> Client {
11792f3ab15Sopenharmony_ci        Client {
11892f3ab15Sopenharmony_ci            ctx: self.ctx.build(),
11992f3ab15Sopenharmony_ci            addr: self.addr,
12092f3ab15Sopenharmony_ci        }
12192f3ab15Sopenharmony_ci    }
12292f3ab15Sopenharmony_ci
12392f3ab15Sopenharmony_ci    pub fn connect(self) -> SslStream<TcpStream> {
12492f3ab15Sopenharmony_ci        self.build().builder().connect()
12592f3ab15Sopenharmony_ci    }
12692f3ab15Sopenharmony_ci
12792f3ab15Sopenharmony_ci    pub fn connect_err(self) {
12892f3ab15Sopenharmony_ci        self.build().builder().connect_err();
12992f3ab15Sopenharmony_ci    }
13092f3ab15Sopenharmony_ci}
13192f3ab15Sopenharmony_ci
13292f3ab15Sopenharmony_cipub struct Client {
13392f3ab15Sopenharmony_ci    ctx: SslContext,
13492f3ab15Sopenharmony_ci    addr: SocketAddr,
13592f3ab15Sopenharmony_ci}
13692f3ab15Sopenharmony_ci
13792f3ab15Sopenharmony_ciimpl Client {
13892f3ab15Sopenharmony_ci    pub fn builder(&self) -> ClientSslBuilder {
13992f3ab15Sopenharmony_ci        ClientSslBuilder {
14092f3ab15Sopenharmony_ci            ssl: Ssl::new(&self.ctx).unwrap(),
14192f3ab15Sopenharmony_ci            addr: self.addr,
14292f3ab15Sopenharmony_ci        }
14392f3ab15Sopenharmony_ci    }
14492f3ab15Sopenharmony_ci}
14592f3ab15Sopenharmony_ci
14692f3ab15Sopenharmony_cipub struct ClientSslBuilder {
14792f3ab15Sopenharmony_ci    ssl: Ssl,
14892f3ab15Sopenharmony_ci    addr: SocketAddr,
14992f3ab15Sopenharmony_ci}
15092f3ab15Sopenharmony_ci
15192f3ab15Sopenharmony_ciimpl ClientSslBuilder {
15292f3ab15Sopenharmony_ci    pub fn ssl(&mut self) -> &mut SslRef {
15392f3ab15Sopenharmony_ci        &mut self.ssl
15492f3ab15Sopenharmony_ci    }
15592f3ab15Sopenharmony_ci
15692f3ab15Sopenharmony_ci    pub fn connect(self) -> SslStream<TcpStream> {
15792f3ab15Sopenharmony_ci        let socket = TcpStream::connect(self.addr).unwrap();
15892f3ab15Sopenharmony_ci        let mut s = self.ssl.connect(socket).unwrap();
15992f3ab15Sopenharmony_ci        s.read_exact(&mut [0]).unwrap();
16092f3ab15Sopenharmony_ci        s
16192f3ab15Sopenharmony_ci    }
16292f3ab15Sopenharmony_ci
16392f3ab15Sopenharmony_ci    pub fn connect_err(self) {
16492f3ab15Sopenharmony_ci        let socket = TcpStream::connect(self.addr).unwrap();
16592f3ab15Sopenharmony_ci        self.ssl.connect(socket).unwrap_err();
16692f3ab15Sopenharmony_ci    }
16792f3ab15Sopenharmony_ci}
168