use std::net::SocketAddr; use axum::{Router, response::Response, http::{Request, StatusCode}, middleware::{Next, self}, extract::ConnectInfo, RequestExt, body::HttpBody, Extension}; use tower_cookies::CookieManagerLayer; use tracing::metadata::LevelFilter; use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, Layer, filter::filter_fn}; use types::response::ResponseCode; use crate::{api::{pages, auth, users, posts}, types::extract::RouterURI}; mod api; mod database; mod types; mod console; async fn serve(req: Request, next: Next) -> Response { let file = ResponseCode::Success.file(&req.uri().to_string()).await; if file.status() != StatusCode::OK { return next.run(req).await; } file } async fn log(mut req: Request, next: Next) -> Response where B: Send + Sync + 'static + HttpBody, { let Ok(ConnectInfo(info)) = req.extract_parts::>().await else { return next.run(req).await }; console::log(info.ip().clone(), req.method().clone(), req.uri().clone(), None, None).await; return next.run(req).await } async fn not_found() -> Response { ResponseCode::NotFound.file("/404.html").await } #[tokio::main] async fn main() { database::init().unwrap(); let fmt_layer = tracing_subscriber::fmt::layer(); tracing_subscriber::registry() .with( fmt_layer.with_filter(LevelFilter::TRACE).with_filter(filter_fn(|metadata| { metadata.target().starts_with("xssbook") })) ) .init(); let app = Router::new() .fallback(not_found) .nest("/", pages::router()) .layer(middleware::from_fn(log)) .layer(middleware::from_fn(serve)) .nest("/api/auth", auth::router() .layer(Extension(RouterURI("/api/auth"))) ).nest("/api/users", users::router() .layer(Extension(RouterURI("/api/users"))) ).nest("/api/posts", posts::router() .layer(Extension(RouterURI("/api/posts"))) ).layer(CookieManagerLayer::new()); let addr = "[::]:8080".parse::().unwrap(); tracing::info!("listening on {}", addr); axum::Server::bind(&addr) .serve(app.into_make_service_with_connect_info::()) .await .unwrap(); }