Skip to content

Commit

Permalink
feat(Rundler): Add cors to the server
Browse files Browse the repository at this point in the history
  • Loading branch information
Blu-J committed Dec 10, 2024
1 parent d283ce1 commit 3e0f184
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 2 deletions.
20 changes: 18 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ tonic-health = "0.12.3"
tonic-reflection = "0.12.3"
tonic-types = "0.12.3"
tower = { version = "0.4.13", features = ["timeout"] }
tower-http = { version = "0.6.2", features = ["cors"] }
tracing = "0.1.40"
strum = { version = "0.26.3", features = ["derive"] }
url = "2.5.2"
1 change: 1 addition & 0 deletions bin/rundler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ clap = { version = "4.5.16", features = ["derive", "env"] }
config = "0.14.0"
dotenv = "0.15.0"
go-parse-duration = "0.1"
http = "1.1.0"
itertools = "0.13.0"
metrics = "0.23.0"
metrics-derive.workspace = true
Expand Down
17 changes: 17 additions & 0 deletions bin/rundler/src/cli/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ pub struct RpcArgs {
default_value = "100"
)]
max_connections: u32,

/// Cors domains seperated by a comma, * is the wildcard
///
/// # Examples
///.env
/// ```env
/// RPC_CORSDOMAIN=*
/// RPC_CORSDOMAIN=https://site1.fake,https:://sub.site1.fake
/// ```
#[arg(
long = "rpc.corsdomain",
name = "rpc.corsdomain",
env = "RPC_CORSDOMAIN",
value_delimiter = ','
)]
pub corsdomain: Option<Vec<http::HeaderValue>>,
}

impl RpcArgs {
Expand Down Expand Up @@ -109,6 +125,7 @@ impl RpcArgs {
max_connections: self.max_connections,
entry_point_v0_6_enabled: !common.disable_entry_point_v0_6,
entry_point_v0_7_enabled: !common.disable_entry_point_v0_7,
corsdomain: self.corsdomain.clone(),
})
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ tokio.workspace = true
tokio-util.workspace = true
tonic.workspace = true
tower.workspace = true
tower-http = { workspace = true, features = ["cors"] }
tracing.workspace = true
url.workspace = true

Expand Down
23 changes: 23 additions & 0 deletions crates/rpc/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::{net::SocketAddr, sync::Arc, time::Duration};

use anyhow::Context;
use futures_util::FutureExt;
use http::{header::CONTENT_TYPE, HeaderValue};
use jsonrpsee::{
server::{middleware::http::ProxyGetRequestLayer, RpcServiceBuilder, ServerBuilder},
RpcModule,
Expand Down Expand Up @@ -75,6 +76,8 @@ pub struct Args {
pub entry_point_v0_6_enabled: bool,
/// Whether to enable entry point v0.7.
pub entry_point_v0_7_enabled: bool,
/// What domains to use in the corsdomain
pub corsdomain: Option<Vec<HeaderValue>>,
}

/// JSON-RPC server task.
Expand Down Expand Up @@ -189,6 +192,26 @@ where

// Set up health check endpoint via GET /health registers the jsonrpc handler
let http_middleware = tower::ServiceBuilder::new()
.option_layer(self.args.corsdomain.map(|layers| {
use tower_http::cors::{AllowOrigin, Any};
// In the case where we pass '*', I want to be able to test the any domain.
// but without this change the list Origins will reject if there is a wildcard present.
// So in the case that there is just '*' passed in the args we will treat it like any
const WILDCARD: HeaderValue = HeaderValue::from_static("*");
let layers: AllowOrigin = if layers.contains(&WILDCARD) && layers.len() == 1 {
Any.into()
} else {
layers.into()
};
tower::ServiceBuilder::new().layer(
tower_http::cors::CorsLayer::new()
// allow `GET` and `POST` when accessing the resource
.allow_methods([http::Method::GET, http::Method::POST])
// allow requests from any origin
.allow_origin(layers)
.allow_headers([CONTENT_TYPE]),
)
}))
// Proxy `GET /health` requests to internal `system_health` method.
.layer(ProxyGetRequestLayer::new("/health", "system_health")?)
.timeout(self.args.rpc_timeout)
Expand Down
2 changes: 2 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ List of command line options for configuring the RPC API.
- env: *RPC_TIMEOUT_SECONDS*
- `--rpc.max_connections`: Maximum number of concurrent connections (default: `100`)
- env: *RPC_MAX_CONNECTIONS*
- `--rpc.corsdomain`: Enable the cors functionality on the server (default: None and therefore corsdomain is disabled).
- env: *RPC_CORSDOMAIN*
- `--rpc.pool_url`: Pool URL for RPC (default: `http://localhost:50051`)
- env: *RPC_POOL_URL*
- *Only required when running in distributed mode*
Expand Down

0 comments on commit 3e0f184

Please sign in to comment.