src/main.rs (98 lines of code) (raw):

//! A server that tells clients what time it is and where they are in the world. //! #![deny(clippy::all)] pub mod endpoints; pub mod errors; pub mod geoip; pub mod keys; pub mod logging; pub mod metrics; pub mod settings; pub mod utils; use crate::{ endpoints::{canned, classify, country, debug, dockerflow, EndpointState}, errors::ClassifyError, geoip::GeoIp, settings::Settings, }; use actix_web::{ web::{self, Data}, App, }; use std::sync::Arc; const APP_NAME: &str = "classify-client"; #[actix_web::main] async fn main() -> Result<(), ClassifyError> { let Settings { api_keys_file, debug, geoip_db_path, host, human_logs, metrics_target, log_level, port, sentry_dsn, sentry_env, sentry_sample_rate, trusted_proxy_list, version_file, .. } = Settings::load()?; let app_log = logging::get_logger("app", human_logs, log_level); let metrics = Arc::new( metrics::get_client(metrics_target, app_log.clone()) .unwrap_or_else(|err| panic!("Critical failure setting up metrics logging: {}", err)), ); let _guard = sentry::init(( sentry_dsn, sentry::ClientOptions { release: sentry::release_name!(), environment: Some(sentry_env.into()), sample_rate: sentry_sample_rate, ..Default::default() }, )); let state = EndpointState { api_keys_hashset: keys::load(api_keys_file, app_log.clone()), geoip: Arc::new( GeoIp::builder() .path(geoip_db_path) .metrics(Arc::clone(&metrics)) .build()?, ), metrics, trusted_proxies: trusted_proxy_list, log: app_log.clone(), version_file, }; let addr = format!("{}:{}", host, port); slog::info!(app_log, "starting server on https://{}", addr); actix_web::HttpServer::new(move || { let mut app = App::new() .app_data(Data::new(state.clone())) .wrap(metrics::ResponseTimer) .wrap(logging::RequestLogger) .wrap(sentry_actix::Sentry::new()) // API Endpoints .service(web::resource("/").route(web::get().to(classify::classify_client))) .service( web::resource("/api/v1/classify_client/") .route(web::get().to(classify::classify_client)), ) .service(web::resource("/v1/country").route(web::route().to(country::get_country))) // Dockerflow Endpoints .service( web::resource("/__lbheartbeat__").route(web::get().to(dockerflow::lbheartbeat)), ) .service(web::resource("/__heartbeat__").route(web::get().to(dockerflow::heartbeat))) .service(web::resource("/__version__").route(web::get().to(dockerflow::version))) // Static responses // no /v1/geolocate, intentionally returning 404 .service(web::resource("/v1/geosubmit").route(web::to(canned::forbidden))) .service(web::resource("/v1/submit").route(web::to(canned::forbidden))) .service(web::resource("/v2/geosubmit").route(web::to(canned::forbidden))); if debug { app = app.service(web::resource("/debug").route(web::get().to(debug::debug_handler))); } app }) .bind(&addr)? .run() .await?; Ok(()) }