use axum::{ extract::DefaultBodyLimit, routing::{delete, get, post}, Router, Server, }; use sqlx::SqlitePool; use std::{net::SocketAddr, path::PathBuf, sync::Arc}; use tokio::net::TcpListener; use tokio_stream::wrappers::TcpListenerStream; mod auth; mod routes; mod state; mod utils; #[tokio::main] async fn main() -> anyhow::Result<()> { dotenvy::dotenv().ok(); println!("connecting to database"); let pool = SqlitePool::connect("u.db").await?; println!("running migrations"); sqlx::migrate!().run(&pool).await?; utils::check_admin_key(&pool).await?; let port = std::env::var("U_PORT").unwrap_or_else(|_| "8075".to_string()); let files_dir = std::env::var("U_FILES_DIR").unwrap_or_else(|_| "files".to_string()); let files_dir = PathBuf::from(files_dir); if !files_dir.exists() { std::fs::create_dir(&files_dir)?; } let state = Arc::new(state::State { db: pool, files_dir, }); let router = Router::default() .route("/i/:id", get(routes::i)) .route("/i/:id", delete(routes::delete)) .route("/api/upload", post(routes::upload)) .route("/api/new_key", post(routes::new_key)) .layer(DefaultBodyLimit::max(1_000_000_000)) .with_state(Arc::clone(&state)); let addr: SocketAddr = format!("0.0.0.0:{}", port).parse()?; println!("listening on {}", addr); let listener = TcpListener::bind(addr).await?; let stream = TcpListenerStream::new(listener); let acceptor = hyper::server::accept::from_stream(stream); Server::builder(acceptor) .serve(router.into_make_service()) .await?; Ok(()) }