]> git.lizzy.rs Git - connect-rs.git/blob - examples/tls-client/src/main.rs
c0b9280a91b45947483a3c30d03ca171800582be
[connect-rs.git] / examples / tls-client / src / main.rs
1 use connect::tls::rustls::ClientConfig;
2 use connect::{ConnectDatagram, Connection, SinkExt, StreamExt};
3 use log::*;
4 use std::env;
5
6 #[async_std::main]
7 async fn main() -> anyhow::Result<()> {
8     env_logger::init();
9
10     // get ip address and domain from cmd line args
11     let (ip_addr, domain, cafile_path) = parse_args();
12
13     // construct `rustls` client config
14     let cafile = std::fs::read(cafile_path)?;
15
16     let mut client_pem = std::io::Cursor::new(cafile);
17
18     let mut client_config = ClientConfig::new();
19     client_config
20         .root_store
21         .add_pem_file(&mut client_pem)
22         .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidInput, "invalid cert"))?;
23
24     // create a client connection to the server
25     let mut conn = Connection::tls_client(ip_addr, &domain, client_config.into()).await?;
26
27     // send a message to the server
28     let msg = String::from("Hello world");
29     info!("Sending message: {}", msg);
30
31     let envelope = ConnectDatagram::new(65535, msg.into_bytes())?;
32     conn.writer().send(envelope).await?;
33
34     // wait for the server to reply with an ack
35     if let Some(mut reply) = conn.reader().next().await {
36         info!("Received message");
37
38         let data = reply.take_data().unwrap();
39         let msg = String::from_utf8(data)?;
40
41         info!("Unpacked reply: {}", msg);
42     }
43
44     Ok(())
45 }
46
47 fn parse_args() -> (String, String, String) {
48     let args: Vec<String> = env::args().collect();
49
50     let ip_address = match args.get(1) {
51         Some(addr) => addr,
52         None => {
53             error!("Need to pass IP address to connect to as first command line argument");
54             panic!();
55         }
56     };
57
58     let domain = match args.get(2) {
59         Some(d) => d,
60         None => {
61             error!("Need to pass domain name as second command line argument");
62             panic!();
63         }
64     };
65
66     let cafile_path = match args.get(3) {
67         Some(d) => d,
68         None => {
69             error!("Need to pass path to cafile as third command line argument");
70             panic!();
71         }
72     };
73
74     (
75         ip_address.to_string(),
76         domain.to_string(),
77         cafile_path.to_string(),
78     )
79 }