chitey_server/server/
util.rs1use std::{fs, path::PathBuf};
2
3use rustls::{Certificate, PrivateKey};
4use 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 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 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 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 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 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}