about summary refs log tree commit diff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs256
1 files changed, 0 insertions, 256 deletions
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index eb70885..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,256 +0,0 @@
-use log::{debug, error, info};
-use std::{convert::Infallible, env, time::Duration};
-use url::Url;
-use warp::{Filter, host::Authority};
-
-#[tokio::main]
-async fn main() {
-    // TODO turn into a feature so I can enable and disable it
-    #[cfg(debug_assertions)]
-    console_subscriber::init();
-
-    // TODO use tracing instead of log
-    let logger_env = env_logger::Env::new().filter_or("RUST_LOG", "info");
-    env_logger::init_from_env(logger_env);
-
-    info!("Starting the kittybox server...");
-
-    let backend_uri: String = match env::var("BACKEND_URI") {
-        Ok(val) => {
-            debug!("Backend URI: {}", val);
-            val
-        }
-        Err(_) => {
-            error!("BACKEND_URI is not set, cannot find a database");
-            std::process::exit(1);
-        }
-    };
-    let token_endpoint: Url = match env::var("TOKEN_ENDPOINT") {
-        Ok(val) => {
-            debug!("Token endpoint: {}", val);
-            match Url::parse(&val) {
-                Ok(val) => val,
-                _ => {
-                    error!("Token endpoint URL cannot be parsed, aborting.");
-                    std::process::exit(1)
-                }
-            }
-        }
-        Err(_) => {
-            error!("TOKEN_ENDPOINT is not set, will not be able to authorize users!");
-            std::process::exit(1)
-        }
-    };
-    let authorization_endpoint: Url = match env::var("AUTHORIZATION_ENDPOINT") {
-        Ok(val) => {
-            debug!("Auth endpoint: {}", val);
-            match Url::parse(&val) {
-                Ok(val) => val,
-                _ => {
-                    error!("Authorization endpoint URL cannot be parsed, aborting.");
-                    std::process::exit(1)
-                }
-            }
-        }
-        Err(_) => {
-            error!("AUTHORIZATION_ENDPOINT is not set, will not be able to confirm token and ID requests using IndieAuth!");
-            std::process::exit(1)
-        }
-    };
-
-    //let internal_token: Option<String> = env::var("KITTYBOX_INTERNAL_TOKEN").ok();
-
-    /*let cookie_secret: String = match env::var("COOKIE_SECRET").ok() {
-        Some(value) => value,
-        None => {
-            if let Ok(filename) = env::var("COOKIE_SECRET_FILE") {
-                use tokio::io::AsyncReadExt;
-
-                let mut file = tokio::fs::File::open(filename).await.map_err(|e| {
-                    error!("Couldn't open the cookie secret file: {}", e);
-                    std::process::exit(1);
-                }).unwrap();
-                let mut temp_string = String::new();
-                file.read_to_string(&mut temp_string).await.map_err(|e| {
-                    error!("Couldn't read the cookie secret from file: {}", e);
-                    std::process::exit(1);
-                }).unwrap();
-
-                temp_string
-            } else {
-                error!("COOKIE_SECRET or COOKIE_SECRET_FILE is not set, will not be able to log in users securely!");
-                std::process::exit(1);
-            }
-        }
-    };*/
-
-    let listen_at = match env::var("SERVE_AT")
-        .ok()
-        .unwrap_or_else(|| "[::]:8080".to_string())
-        .parse::<std::net::SocketAddr>() {
-            Ok(addr) => addr,
-            Err(e) => {
-                error!("Cannot parse SERVE_AT: {}", e);
-                std::process::exit(1);
-            }
-        };
-
-    // This thing handles redirects automatically but is type-incompatible with hyper::Client
-    // Bonus: less generics to be aware of, this thing hides its complexity
-    let http: reqwest::Client = {
-        #[allow(unused_mut)]
-        let mut builder = reqwest::Client::builder()
-            .user_agent(concat!(
-                env!("CARGO_PKG_NAME"),
-                "/",
-                env!("CARGO_PKG_VERSION")
-            ));
-        // TODO: add a root certificate if there's an environment variable pointing at it
-        //builder = builder.add_root_certificate(reqwest::Certificate::from_pem(todo!()));
-
-        builder.build().unwrap()
-    };
-
-    if backend_uri.starts_with("redis") {
-        println!("The Redis backend is deprecated.");
-        std::process::exit(1);
-    } else if backend_uri.starts_with("file") {
-        
-        let database = {
-            let folder = backend_uri.strip_prefix("file://").unwrap();
-            let path = std::path::PathBuf::from(folder);
-            match kittybox::database::FileStorage::new(path).await {
-                Ok(db) => db,
-                Err(err) => {
-                    error!("Error creating database: {:?}", err);
-                    std::process::exit(1);
-                }
-            }
-        };
-
-        let endpoints = kittybox::frontend::IndiewebEndpoints {
-            authorization_endpoint: authorization_endpoint.to_string(),
-            token_endpoint: token_endpoint.to_string(),
-            webmention: None,
-            microsub: None,
-        };
-        
-        let homepage = warp::get()
-            .and(warp::path::end())
-            .and(kittybox::frontend::homepage(database.clone(), endpoints.clone()));
-
-        let onboarding = warp::path("onboarding")
-            .and(warp::path::end())
-            .and(kittybox::frontend::onboarding(
-                database.clone(),
-                endpoints.clone(),
-                http.clone()
-            ));
-        
-        let micropub = warp::path("micropub")
-            .and(warp::path::end()
-                 .and(kittybox::micropub::micropub(
-                     database.clone(),
-                     token_endpoint.to_string(),
-                     http.clone()
-                 ))
-                 .or(warp::get()
-                     .and(warp::path("client"))
-                     .and(warp::path::end())
-                     .map(|| warp::reply::html(kittybox::MICROPUB_CLIENT))));
-
-        let media = warp::path("media")
-            .and(warp::path::end()
-                 .and(kittybox::media::media())
-                 .or(kittybox::util::require_host()
-                     .and(warp::path::param())
-                     .map(|_host: Authority, path: String| format!("media file {}", path))));
-        
-        // TODO remember how login logic works because I forgor
-        let login = warp::path("login")
-            .and(warp::path("callback")
-                 .map(|| "callback!")
-                 // TODO form on GET and handler on POST
-                 .or(warp::path::end().map(|| "login page!")));
-
-        // TODO prettier error response
-        let coffee = warp::path("coffee")
-            .map(|| warp::reply::with_status("I'm a teapot!", warp::http::StatusCode::IM_A_TEAPOT));
-        
-        let static_files = warp::path("static")
-            .and(kittybox::frontend::static_files());
-
-        let catchall = kittybox::frontend::catchall(
-            database.clone(),
-            endpoints.clone()
-        );
-
-        let health = warp::path("health").and(warp::path::end()).map(|| "OK");
-        let metrics = warp::path("metrics").and(warp::path::end()).map(kittybox::metrics::gather);
-
-        let app = homepage
-            .or(onboarding)
-            .or(metrics
-                .or(health))
-            .or(static_files)
-            .or(login)
-            .or(coffee)
-            .or(micropub)
-            .or(media)
-            .or(catchall)
-            .with(warp::log("kittybox"))
-            .with(kittybox::metrics::metrics(vec![
-                "health".to_string(),
-                "micropub".to_string(),
-                "static".to_string(),
-                "media".to_string(),
-                "metrics".to_string()
-            ]))
-            ;
-
-        let svc = warp::service(app);
-
-        let mut listenfd = listenfd::ListenFd::from_env();
-        let tcp_listener: std::net::TcpListener = if let Ok(Some(listener)) = listenfd.take_tcp_listener(0) {
-            listener
-        } else {
-            std::net::TcpListener::bind(listen_at).unwrap()
-        };
-        tcp_listener.set_nonblocking(true).unwrap();
-
-        info!("Listening on {}", tcp_listener.local_addr().unwrap());
-        let server = hyper::server::Server::from_tcp(tcp_listener)
-            .unwrap()
-            .tcp_keepalive(Some(Duration::from_secs(30 * 60)))
-            .serve(hyper::service::make_service_fn(move |_| {
-                let service = svc.clone();
-                async move {
-                    Ok::<_, Infallible>(service)
-                }
-            }))
-            .with_graceful_shutdown(async move {
-                // Defer to C-c handler whenever we're not on Unix
-                // TODO consider using a diverging future here
-                #[cfg(not(unix))]
-                return tokio::signal::ctrl_c().await.unwrap();
-                #[cfg(unix)]
-                {
-                    use tokio::signal::unix::{signal, SignalKind};
-
-                    signal(SignalKind::terminate())
-                        .unwrap()
-                        .recv()
-                        .await
-                        .unwrap()
-                }
-            });
-
-        if let Err(err) = server.await {
-            error!("Error serving requests: {}", err);
-            std::process::exit(1);
-        }
-    } else {
-        println!("Unknown backend, not starting.");
-        std::process::exit(1);
-    }
-}