mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-29 10:54:24 +00:00
Assume Content-Type is json for endpoints that require json (#4575)
* added default content type filter * Merge branch 'unstable' of https://github.com/sigp/lighthouse into unstable * create custom warp json filter that ignores content type header * cargo fmt and linting * updated test * updated test * merge unstable * merge conflicts * workspace=true * use Bytes instead of Buf * resolve merge conflict * resolve merge conflicts * add extra error message context * merge conflicts * lint
This commit is contained in:
@@ -373,10 +373,30 @@ impl BeaconNodeHttpClient {
|
||||
if let Some(timeout) = timeout {
|
||||
builder = builder.timeout(timeout);
|
||||
}
|
||||
|
||||
let response = builder.json(body).send().await?;
|
||||
ok_or_error(response).await
|
||||
}
|
||||
|
||||
/// Generic POST function supporting arbitrary responses and timeouts.
|
||||
/// Does not include Content-Type application/json in the request header.
|
||||
async fn post_generic_json_without_content_type_header<T: Serialize, U: IntoUrl>(
|
||||
&self,
|
||||
url: U,
|
||||
body: &T,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<Response, Error> {
|
||||
let mut builder = self.client.post(url);
|
||||
if let Some(timeout) = timeout {
|
||||
builder = builder.timeout(timeout);
|
||||
}
|
||||
|
||||
let serialized_body = serde_json::to_vec(body).map_err(Error::InvalidJson)?;
|
||||
|
||||
let response = builder.body(serialized_body).send().await?;
|
||||
ok_or_error(response).await
|
||||
}
|
||||
|
||||
/// Generic POST function supporting arbitrary responses and timeouts.
|
||||
async fn post_generic_with_consensus_version<T: Serialize, U: IntoUrl>(
|
||||
&self,
|
||||
@@ -1250,7 +1270,8 @@ impl BeaconNodeHttpClient {
|
||||
.push("pool")
|
||||
.push("attester_slashings");
|
||||
|
||||
self.post(path, slashing).await?;
|
||||
self.post_generic_json_without_content_type_header(path, slashing, None)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ beacon_chain = { workspace = true }
|
||||
state_processing = { workspace = true }
|
||||
safe_arith = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
headers = "0.3.2"
|
||||
lighthouse_metrics = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
serde_array_query = "0.1.0"
|
||||
bytes = { workspace = true }
|
||||
|
||||
22
common/warp_utils/src/json.rs
Normal file
22
common/warp_utils/src/json.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use bytes::Bytes;
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::error::Error as StdError;
|
||||
use warp::{Filter, Rejection};
|
||||
|
||||
use crate::reject;
|
||||
|
||||
struct Json;
|
||||
|
||||
type BoxError = Box<dyn StdError + Send + Sync>;
|
||||
|
||||
impl Json {
|
||||
fn decode<T: DeserializeOwned>(bytes: Bytes) -> Result<T, BoxError> {
|
||||
serde_json::from_slice(&bytes).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json<T: DeserializeOwned + Send>() -> impl Filter<Extract = (T,), Error = Rejection> + Copy {
|
||||
warp::body::bytes().and_then(|bytes: Bytes| async move {
|
||||
Json::decode(bytes).map_err(|err| reject::custom_deserialize_error(format!("{:?}", err)))
|
||||
})
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
//! Lighthouse project. E.g., the `http_api` and `http_metrics` crates.
|
||||
|
||||
pub mod cors;
|
||||
pub mod json;
|
||||
pub mod metrics;
|
||||
pub mod query;
|
||||
pub mod reject;
|
||||
|
||||
@@ -82,6 +82,15 @@ pub fn custom_bad_request(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(CustomBadRequest(msg))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CustomDeserializeError(pub String);
|
||||
|
||||
impl Reject for CustomDeserializeError {}
|
||||
|
||||
pub fn custom_deserialize_error(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(CustomDeserializeError(msg))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CustomServerError(pub String);
|
||||
|
||||
@@ -161,6 +170,9 @@ pub async fn handle_rejection(err: warp::Rejection) -> Result<impl warp::Reply,
|
||||
if err.is_not_found() {
|
||||
code = StatusCode::NOT_FOUND;
|
||||
message = "NOT_FOUND".to_string();
|
||||
} else if let Some(e) = err.find::<crate::reject::CustomDeserializeError>() {
|
||||
message = format!("BAD_REQUEST: body deserialize error: {}", e.0);
|
||||
code = StatusCode::BAD_REQUEST;
|
||||
} else if let Some(e) = err.find::<warp::filters::body::BodyDeserializeError>() {
|
||||
message = format!("BAD_REQUEST: body deserialize error: {}", e);
|
||||
code = StatusCode::BAD_REQUEST;
|
||||
|
||||
Reference in New Issue
Block a user