Support pre-flight CORS check (#1772)

## Issue Addressed

- Resolves #1766 

## Proposed Changes

- Use the `warp::filters::cors` filter instead of our work-around.

## Additional Info

It's not trivial to enable/disable `cors` using `warp`, since using `routes.with(cors)` changes the type of `routes`.  This makes it difficult to apply/not apply cors at runtime. My solution has been to *always* use the `warp::filters::cors` wrapper but when cors should be disabled, just pass the HTTP server listen address as the only permissible origin.
This commit is contained in:
Paul Hauner
2020-10-22 04:47:27 +00:00
parent a3552a4b70
commit a3704b971e
13 changed files with 138 additions and 38 deletions

View File

@@ -52,7 +52,7 @@ eth2_keystore = { path = "../crypto/eth2_keystore" }
account_utils = { path = "../common/account_utils" }
lighthouse_version = { path = "../common/lighthouse_version" }
warp_utils = { path = "../common/warp_utils" }
warp = "0.2.5"
warp = { git = "https://github.com/paulhauner/warp", branch = "cors-wildcard" }
hyper = "0.13.8"
serde_utils = { path = "../consensus/serde_utils" }
libsecp256k1 = "0.3.5"

View File

@@ -131,8 +131,10 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
Arg::with_name("http-allow-origin")
.long("http-allow-origin")
.value_name("ORIGIN")
.help("Set the value of the Access-Control-Allow-Origin response HTTP header. Use * to allow any origin (not recommended in production)")
.default_value("")
.help("Set the value of the Access-Control-Allow-Origin response HTTP header. \
Use * to allow any origin (not recommended in production). \
If no value is supplied, the CORS allowed origin is set to the listen \
address of this server (e.g., http://localhost:5062).")
.takes_value(true),
)
}

View File

@@ -100,7 +100,19 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
) -> Result<(SocketAddr, impl Future<Output = ()>), Error> {
let config = &ctx.config;
let log = ctx.log.clone();
let allow_origin = config.allow_origin.clone();
// Configure CORS.
let cors_builder = {
let builder = warp::cors()
.allow_methods(vec!["GET", "POST", "PATCH"])
.allow_headers(vec!["Content-Type", "Authorization"]);
warp_utils::cors::set_builder_origins(
builder,
config.allow_origin.as_deref(),
(config.listen_addr, config.listen_port),
)?
};
// Sanity check.
if !config.enabled {
@@ -428,8 +440,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.recover(warp_utils::reject::handle_rejection)
// Add a `Server` header.
.map(|reply| warp::reply::with_header(reply, "Server", &version_with_platform()))
// Maybe add some CORS headers.
.map(move |reply| warp_utils::reply::maybe_cors(reply, allow_origin.as_ref()));
.with(cors_builder.build());
let (listening_socket, server) = warp::serve(routes).try_bind_with_graceful_shutdown(
SocketAddrV4::new(config.listen_addr, config.listen_port),