diff --git a/Cargo.lock b/Cargo.lock index ca4192a..1e1b863 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4052,6 +4052,7 @@ dependencies = [ "futures-util", "getrandom 0.2.11", "hex", + "http", "httpc-test", "metrics", "metrics-exporter-prometheus", @@ -4074,6 +4075,7 @@ dependencies = [ "thiserror", "time", "tokio", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", diff --git a/Cargo.toml b/Cargo.toml index a5b2d62..774daeb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ rand = { version = "0.8", default-features = false } rand_core = { version = "0.6", default-features = false } tokio = { version = "1.26.0", features = ["rt-multi-thread"] } hex = { version = "0.4", features = ["serde"] } +http = "0.2.11" futures-util = { version = "0.3", features = ["sink"] } bytes = "1.0" time = "0.3" @@ -52,6 +53,7 @@ prost-types = "0.12.0" futures = "0.3.28" opentelemetry = "0.20.0" tracing-opentelemetry = "0.20.0" +tower-http = { version = "0.4.4", features = ["cors"] } opentelemetry-jaeger = "0.19.0" opentelemetry_api = { version = "0.20.0", features = ["metrics"] } axum-prometheus = { version = "0.4.0", optional = true } diff --git a/config/Settings.example.toml b/config/Settings.example.toml index 102809d..3ce2111 100644 --- a/config/Settings.example.toml +++ b/config/Settings.example.toml @@ -17,6 +17,7 @@ create_index = true [server] serve_at = "0.0.0.0" port = 30303 +cors_allow_origins = [] [indexer] tendermint_addr = "http://127.0.0.1" diff --git a/src/config.rs b/src/config.rs index f8166fc..2543e36 100644 --- a/src/config.rs +++ b/src/config.rs @@ -31,6 +31,7 @@ pub struct IndexerConfig { pub struct ServerConfig { pub serve_at: String, pub port: u16, + pub cors_allow_origins: Vec, } #[derive(Debug, Deserialize)] @@ -102,6 +103,7 @@ impl Default for ServerConfig { Self { serve_at: SERVER_ADDR.to_owned(), port: SERVER_PORT, + cors_allow_origins: vec![], } } } @@ -147,6 +149,8 @@ pub struct CliSettings { pub server_serve_at: String, #[clap(long, env, default_value_t = SERVER_PORT)] pub server_port: u16, + #[clap(long, env)] + pub server_cors_allow_origin: Vec, #[clap(long, env, default_value = "localhost")] pub database_host: String, #[clap(long, env, default_value = "postgres")] @@ -221,6 +225,7 @@ impl From for Settings { server: ServerConfig { serve_at: value.server_serve_at, port: value.server_port, + cors_allow_origins: value.server_cors_allow_origin, }, indexer: IndexerConfig { tendermint_addr: value.indexer_tendermint_addr, diff --git a/src/server/mod.rs b/src/server/mod.rs index e50e117..ffdb2b0 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,4 +1,6 @@ use axum::{routing::get, Router}; +use tower_http::cors::{Any, CorsLayer}; +use http::{HeaderValue, Method}; #[cfg(feature = "prometheus")] use axum_prometheus::{PrometheusMetricLayerBuilder, AXUM_HTTP_REQUESTS_DURATION_SECONDS}; @@ -41,6 +43,9 @@ pub struct ServerState { } fn server_routes(state: ServerState) -> Router<()> { + let cors = CorsLayer::new() + .allow_methods([Method::GET, Method::POST]) + .allow_origin(Any); Router::new() .route("/block/height/:block_height", get(get_block_by_height)) .route("/block/hash/:block_hash", get(get_block_by_hash)) @@ -53,6 +58,7 @@ fn server_routes(state: ServerState) -> Router<()> { "/validator/:validator_address/uptime", get(get_validator_uptime), ) + .layer(cors) .with_state(state) } @@ -91,7 +97,14 @@ pub fn create_server( .with_metrics_from_fn(|| prometheus_handle) .build_pair(); - let routes = server_routes(ServerState { db, checksums_map }); + let mut routes = server_routes(ServerState { db, checksums_map }); + if !config.cors_allow_origins.is_empty() { + let origins: Vec = config.cors_allow_origins.iter().map(|s| s.parse::().unwrap()).collect(); + let cors = CorsLayer::new() + .allow_methods([Method::GET]) + .allow_origin(origins); + routes = routes.layer(cors) + }; #[cfg(feature = "prometheus")] let routes = routes diff --git a/tests/utils.rs b/tests/utils.rs index a5c677b..e326e15 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -14,6 +14,7 @@ pub fn start_server(db: Database) -> Result { // this ensure there would not be conflicts with other server instances started by other // tests port: 0, + cors_allow_origins: vec![], }; let (socket, server) = create_server(db, &config)?;