edgee_proxy/
monitor.rs

1use crate::config;
2use bytes::Bytes;
3use http::{Request, Response, StatusCode};
4use http_body_util::{combinators::BoxBody, BodyExt, Empty};
5use hyper::{body::Incoming, service::service_fn};
6use hyper_util::{
7    rt::{TokioExecutor, TokioIo},
8    server::conn::auto::Builder,
9};
10use std::{convert::Infallible, net::SocketAddr};
11use tokio::net::TcpListener;
12use tracing::{debug, error, info};
13
14pub async fn start() -> anyhow::Result<()> {
15    match &config::get().monitor {
16        Some(cfg) => {
17            info!(address = cfg.address, "Starting monitor");
18            let addr: SocketAddr = cfg.address.parse()?;
19            let listener = TcpListener::bind(addr)
20                .await
21                .expect("Should bind to socket addr");
22
23            loop {
24                let (stream, addr) = match listener.accept().await {
25                    Ok(a) => a,
26                    Err(err) => {
27                        error!(?err, "Failed to accepts connection");
28                        continue;
29                    }
30                };
31
32                if let Err(err) = Builder::new(TokioExecutor::new())
33                    .serve_connection(TokioIo::new(stream), service_fn(handle_request))
34                    .await
35                {
36                    error!(?err, ?addr, "Failed to serve connections");
37                }
38            }
39        }
40        None => Ok(()),
41    }
42}
43
44async fn handle_request(
45    req: Request<Incoming>,
46) -> Result<Response<BoxBody<Bytes, Infallible>>, Infallible> {
47    match req.uri().path() {
48        "/healthz" => {
49            let res = Response::builder()
50                .status(StatusCode::NO_CONTENT)
51                .body(
52                    Empty::<Bytes>::new()
53                        .map_err(|never| match never {})
54                        .boxed(),
55                )
56                .expect("Should build body");
57            debug!("monitor responded ok");
58            Ok(res)
59        }
60        _ => {
61            let res = Response::builder()
62                .status(StatusCode::NOT_FOUND)
63                .body(
64                    Empty::<Bytes>::new()
65                        .map_err(|never| match never {})
66                        .boxed(),
67                )
68                .expect("Should build body");
69            debug!("monitor responded not found");
70            Ok(res)
71        }
72    }
73}