commit c806356b760c9478ac6b47e22e71917ba436bcd8 from: msi date: Fri Nov 14 14:59:10 2025 UTC Add ip extracter commit - 1cb08214cf3a82ad3acb8fec023e7fb2a404f6bd commit + c806356b760c9478ac6b47e22e71917ba436bcd8 blob - 556952c4198c548f93bd7667434b18fda7be9c84 blob + 9b0bebcc211a37fb3c319e992a6b8b8919de1f93 --- web/README.md +++ web/README.md @@ -4,7 +4,7 @@ * [x] Graceful Shutdown * [x] Minijinja * [x] Prometheus -* [ ] Middleware Ip +* [x] Middleware Ip * [x] Request Id Header * [x] Static files * [x] Config blob - 207eafbd53830c5193ccc5ea5502abca1654ccd8 blob + d266dac95ef710f4e07d61d0565c34bc52ca0566 --- web/template/Cargo.toml +++ web/template/Cargo.toml @@ -9,6 +9,7 @@ edition = "2024" [dependencies] anyhow = "=1.0.100" axum = { version = "=0.8.6", features = ["macros"] } +axum-client-ip = "=1.1.3" axum-messages = "=0.8.0" axum_csrf = { version = "=0.11.0", features = ["layer"] } config = { version = "=0.15.19", default-features = false, features = ["toml"] } blob - f9c63402ebb48560a26b3ab2a1b4286a335395f8 blob + d1f56d93282c97bddded2b3c6399390911d2364c --- web/template/src/main.rs +++ web/template/src/main.rs @@ -14,6 +14,7 @@ // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // +use std::net::SocketAddr; use std::sync::Arc; use minijinja::Environment; @@ -23,8 +24,8 @@ use tracing::info; mod helpers; mod metric; mod router; -mod state; mod settings; +mod state; #[tokio::main] async fn main() -> anyhow::Result<()> { @@ -52,8 +53,11 @@ async fn start_main_server() -> anyhow::Result<()> { // TODO(msi): from config let listener = TcpListener::bind("0.0.0.0:3000").await?; info!("listening on http://{}", listener.local_addr().unwrap()); - axum::serve(listener, app) - .with_graceful_shutdown(helpers::shutdown_signal()) - .await?; + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .with_graceful_shutdown(helpers::shutdown_signal()) + .await?; Ok(()) } blob - 170890ae66c2802d5e4c9638ba179ea083e46c7b blob + ca2f2a800fa47ac104c61617c1a9d127a84700b4 --- web/template/src/router.rs +++ web/template/src/router.rs @@ -23,6 +23,7 @@ use axum::{ response::{Html, IntoResponse, Redirect}, routing::get, }; +use axum_client_ip::{ClientIp, ClientIpSource}; use axum_csrf::{CsrfConfig, CsrfLayer, CsrfToken, Key}; use axum_messages::{Messages, MessagesManagerLayer}; use minijinja::context; @@ -62,6 +63,9 @@ pub(crate) fn route(app_state: Arc) -> Route .with_key(Some(cookie_key)) .with_cookie_domain(Some("127.0.0.1")); + // TODO(msi): from config, if debug mode + let ip_source = ClientIpSource::ConnectInfo; + Router::new() .route("/", get(handler_home)) .route("/content", get(handler_content)) @@ -70,6 +74,7 @@ pub(crate) fn route(app_state: Arc) -> Route .route("/message", get(set_messages_handler)) .route("/read-messages", get(read_messages_handler)) .route("/csrf", get(csrf_root).post(csrf_check_key)) + .route("/ip", get(ip_handler)) .layer(MessagesManagerLayer) // TODO(msi): from config folder asssets .nest_service("/assets", ServeDir::new("assets")) @@ -97,6 +102,7 @@ pub(crate) fn route(app_state: Arc) -> Route .with_expiry(Expiry::OnInactivity(Duration::seconds(10))), MessagesManagerLayer, CsrfLayer::new(config), + ip_source.into_extension(), // TODO(msi): from config TimeoutLayer::new(std::time::Duration::from_secs(10)), PropagateRequestIdLayer::new(x_request_id), @@ -106,6 +112,10 @@ pub(crate) fn route(app_state: Arc) -> Route .with_state(app_state) } +async fn ip_handler(ClientIp(ip): ClientIp) -> String { + ip.to_string() +} + async fn csrf_root( token: CsrfToken, State(state): State>, blob - 897cbf4288d8cc11fc05ceb140d88314764f74bd blob + 981476489b4c549916d998d1ff06ed29398442de --- web/template/src/settings.rs +++ web/template/src/settings.rs @@ -48,7 +48,8 @@ pub(crate) struct Settings { impl Settings { pub(crate) fn new() -> Result { info!("loading settings"); - let run_mode = env::var("RUN_MODE").unwrap_or_else(|_| "development".into()); + let run_mode = + env::var("RUN_MODE").unwrap_or_else(|_| "development".into()); let s = Config::builder() // Start off by merging in the "default" configuration file @@ -57,8 +58,7 @@ impl Settings { // Default to 'development' env // Note that this file is _optional_ .add_source( - File::with_name(&format!("config/{run_mode}")) - .required(false), + File::with_name(&format!("config/{run_mode}")).required(false), ) // Add in a local configuration file // This file shouldn't be checked in to git blob - f162c30c552c43988a707bd39c1cbd88cc1ed4a4 blob + 6abc2fda11620fbecb3d72b3b37cc2b3dac02d2d --- web/template/templates/layout.jinja +++ web/template/templates/layout.jinja @@ -12,6 +12,7 @@
  • Set Message
  • Read Messages
  • Csrf
  • +
  • Ip
  • Hello, World web =]