bws_web_server/monitoring/
certificates.rs1use log::{error, info, warn};
2use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
3use std::path::Path;
4use tokio::sync::mpsc;
5
6pub struct CertificateWatcher {
7 cert_dir: String,
8 domains: Vec<String>,
9 _watcher: Option<RecommendedWatcher>, }
11
12impl CertificateWatcher {
13 pub fn new(cert_dir: String, domains: Vec<String>) -> Self {
14 Self {
15 cert_dir,
16 domains,
17 _watcher: None,
18 }
19 }
20
21 pub fn start_watching(&mut self) -> Result<(), Box<dyn std::error::Error>> {
22 let (tx, mut rx) = mpsc::unbounded_channel();
23
24 let mut watcher = RecommendedWatcher::new(
25 move |res: Result<Event, notify::Error>| match res {
26 Ok(event) => {
27 if let Err(e) = tx.send(event) {
28 error!("Failed to send file watcher event: {e}");
29 }
30 }
31 Err(e) => {
32 error!("File watcher error: {e}");
33 }
34 },
35 notify::Config::default(),
36 )?;
37
38 watcher.watch(Path::new(&self.cert_dir), RecursiveMode::Recursive)?;
40 info!(
41 "Certificate watcher started for directory: {}",
42 self.cert_dir
43 );
44
45 self._watcher = Some(watcher);
47
48 let domains = self.domains.clone();
49 let cert_dir = self.cert_dir.clone();
50
51 tokio::spawn(async move {
52 while let Some(event) = rx.recv().await {
53 match event.kind {
54 EventKind::Create(_) | EventKind::Modify(_) => {
55 for path in event.paths {
56 if let Some(filename) = path.file_name() {
57 if let Some(filename_str) = filename.to_str() {
58 for domain in &domains {
60 let cert_file = format!("{domain}.crt");
61 let key_file = format!("{domain}.key");
62
63 if filename_str == cert_file || filename_str == key_file {
64 info!("Certificate file changed: {path:?}");
65
66 let cert_path = Path::new(&cert_dir).join(&cert_file);
68 let key_path = Path::new(&cert_dir).join(&key_file);
69
70 if cert_path.exists() && key_path.exists() {
71 info!("Both certificate and key files exist for domain: {domain}");
72 warn!("🔄 HTTPS UPGRADE AVAILABLE!");
73 warn!(
74 "To enable HTTPS for {domain}, restart the server:"
75 );
76 warn!(" pkill -f bws");
77 warn!(" ./target/x86_64-unknown-linux-musl/release/bws --config config-auto-acme.toml");
78 }
79 }
80 }
81 }
82 }
83 }
84 }
85 _ => {}
86 }
87 }
88 info!("Certificate watcher task terminated");
89 });
90
91 Ok(())
92 }
93}