chitey_server/server/
util.rs

1use std::{fs, path::PathBuf};
2
3use rustls::{Certificate, PrivateKey};
4// use tracing::info;
5
6use crate::web_server::{Certs, ChiteyError};
7
8#[derive(Clone)]
9pub struct TlsCertsKey {
10    pub certs: Vec<Certificate>,
11    pub key: PrivateKey,
12}
13
14pub fn get_certs_and_key(certs: Certs) -> Result<TlsCertsKey, Box<dyn std::error::Error>> {
15    let Certs { cert, key } = certs;
16
17    if cert.extension().unwrap() == "pem" {
18        // info!("cert file is pem file");
19        Ok(TlsCertsKey {
20            certs: load_certs(cert)?,
21            key: load_private_key(key)?,
22        })
23    } else {
24        Ok(TlsCertsKey {
25            certs: vec![Certificate(std::fs::read(cert)?)],
26            key: PrivateKey(std::fs::read(key)?),
27        })
28    }
29}
30
31pub fn load_certs(filepath: PathBuf) -> std::io::Result<Vec<rustls::Certificate>> {
32    // Open certificate file.
33    let certfile = fs::File::open(filepath.clone()).map_err(|e| {
34        ChiteyError::InternalServerError(format!(
35            "failed to open {}: {}",
36            filepath.to_string_lossy(),
37            e
38        ))
39    }).unwrap();
40    let mut reader = std::io::BufReader::new(certfile);
41
42    // Load and return certificate.
43    let certs = rustls_pemfile::certs(&mut reader)
44        .map_err(|_| ChiteyError::InternalServerError("failed to load certificate".into())).unwrap();
45    Ok(certs.into_iter().map(rustls::Certificate).collect())
46}
47
48pub fn load_private_key(filepath: PathBuf) -> std::io::Result<rustls::PrivateKey> {
49    // Open keyfile.
50    let keyfile = fs::File::open(filepath.clone()).map_err(|e| {
51        ChiteyError::InternalServerError(format!(
52            "failed to open {}: {}",
53            filepath.to_string_lossy(),
54            e
55        ))
56    }).unwrap();
57    let mut reader = std::io::BufReader::new(keyfile);
58
59    // Load and return a single private key.
60    let keys = rustls_pemfile::pkcs8_private_keys(&mut reader)
61        .map_err(|_| ChiteyError::InternalServerError("failed to load private key".into())).unwrap();
62    if keys.len() != 1 {
63        return Err(ChiteyError::InternalServerError("expected a single private key".into())).unwrap();
64    }
65    Ok(rustls::PrivateKey(keys[0].clone()))
66}
67
68#[inline]
69pub fn process_result<T, R: std::fmt::Display>(result: Result<T, R>) -> Option<T> {
70    match result {
71        Ok(value) => Some(value),
72        Err(error) => {
73            tracing::error!("Error: {}", error);
74            None
75        }
76    }
77}
78
79#[inline]
80pub fn throw_chitey_internal_server_error<T, E>(res: Result<T, E>) -> Result<T, ChiteyError>
81where
82    E: std::error::Error,
83{
84    match res {
85        Ok(v) => Ok(v),
86        Err(e) =>Err(ChiteyError::InternalServerError(e.to_string())),
87    }
88}
89
90#[inline]
91pub fn cors_builder() -> http::response::Builder {
92    let builder = hyper::Response::builder();
93    let builder = builder.header("Access-Control-Allow-Origin", "*");
94    builder
95}