1use crate::Router;
3use crate::get;
4use hyper::StatusCode;
5use hyper::server::{Server, conn::AddrStream};
6use hyper::service::{make_service_fn, service_fn};
7use std::net::SocketAddr;
8use std::sync::Arc;
9use std::time::{SystemTime, UNIX_EPOCH};
10use tokio::sync::Mutex;
11
12impl Router {
13 pub async fn run(mut self, host: &str, port: u16) {
15 let addr: SocketAddr = format!("{}:{}", host, port)
16 .parse()
17 .expect("invalid socket address: invalid IP address syntax");
18
19 let pin = self.random();
20 let enable_logger = self.enable_logger;
21
22 if enable_logger {
23 let outputs = self.outputs.clone();
24 self = self.route(
25 "/debug",
26 get(move |query| {
27 let value = Arc::clone(&outputs);
28 async move {
29 let value = value.lock().unwrap();
30 if let Some(ipin) = query.get("pin") {
31 if ipin.parse::<u32>().unwrap_or(1000) == pin {
32 ([], StatusCode::OK, value.clone())
33 } else {
34 ([], StatusCode::UNAUTHORIZED, "401 Unauthorized".to_string())
35 }
36 } else {
37 ([], StatusCode::UNAUTHORIZED, "401 Unauthorized".to_string())
38 }
39 }
40 }),
41 );
42 }
43
44 if enable_logger {
45 self.log(&format!("Nimble server running on http://{}", addr));
46 self.log("Press Ctrl+C to stop");
47 self.log(&format!("Debug PIN: {}", pin));
48 }
49
50 let router = Arc::new(Mutex::new(self));
51
52 let make_svc = make_service_fn(move |conn: &AddrStream| {
53 let remote_addr = conn.remote_addr(); let router = router.clone();
56
57 async move {
58 Ok::<_, hyper::Error>(service_fn(move |mut req| {
59 req.extensions_mut().insert(remote_addr);
62 let router = router.clone();
63 async move { Ok::<_, hyper::Error>(router.lock().await.handle_request(req).await) }
64 }))
65 }
66 });
67
68 let server = Server::bind(&addr).serve(make_svc);
69 if let Err(e) = server.await {
70 eprintln!("Server error: {}", e);
71 }
72 }
73
74 fn random(&self) -> u32 {
75 let nanos = SystemTime::now()
77 .duration_since(UNIX_EPOCH)
78 .unwrap()
79 .subsec_nanos();
80
81 100 + (nanos % 900)
83 }
84}