mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Reject octet-stream content type when we expect json (#5862)
* reject octet-stream content type when we expect json * added a test, fixed a bug with checking for 415's
This commit is contained in:
@@ -415,6 +415,23 @@ impl BeaconNodeHttpClient {
|
||||
ok_or_error(response).await
|
||||
}
|
||||
|
||||
/// Generic POST function that includes octet-stream content type header.
|
||||
async fn post_generic_with_ssz_header<T: Serialize, U: IntoUrl>(
|
||||
&self,
|
||||
url: U,
|
||||
body: &T,
|
||||
) -> Result<Response, Error> {
|
||||
let builder = self.client.post(url);
|
||||
let mut headers = HeaderMap::new();
|
||||
|
||||
headers.insert(
|
||||
"Content-Type",
|
||||
HeaderValue::from_static("application/octet-stream"),
|
||||
);
|
||||
let response = builder.headers(headers).json(body).send().await?;
|
||||
ok_or_error(response).await
|
||||
}
|
||||
|
||||
/// Generic POST function supporting arbitrary responses and timeouts.
|
||||
async fn post_generic_with_consensus_version_and_ssz_body<T: Into<Body>, U: IntoUrl>(
|
||||
&self,
|
||||
@@ -543,6 +560,26 @@ impl BeaconNodeHttpClient {
|
||||
self.get_opt(path).await
|
||||
}
|
||||
|
||||
/// TESTING ONLY: This request should fail with a 415 response code.
|
||||
pub async fn post_beacon_states_validator_balances_with_ssz_header(
|
||||
&self,
|
||||
state_id: StateId,
|
||||
ids: Vec<ValidatorId>,
|
||||
) -> Result<Response, Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
path.path_segments_mut()
|
||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||
.push("beacon")
|
||||
.push("states")
|
||||
.push(&state_id.to_string())
|
||||
.push("validator_balances");
|
||||
|
||||
let request = ValidatorBalancesRequestBody { ids };
|
||||
|
||||
self.post_generic_with_ssz_header(path, &request).await
|
||||
}
|
||||
|
||||
/// `POST beacon/states/{state_id}/validator_balances`
|
||||
///
|
||||
/// Returns `Ok(None)` on a 404 error.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use bytes::Bytes;
|
||||
use eth2::{CONTENT_TYPE_HEADER, SSZ_CONTENT_TYPE_HEADER};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::error::Error as StdError;
|
||||
use warp::{Filter, Rejection};
|
||||
@@ -16,7 +17,17 @@ impl Json {
|
||||
}
|
||||
|
||||
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)))
|
||||
})
|
||||
warp::header::optional::<String>(CONTENT_TYPE_HEADER)
|
||||
.and(warp::body::bytes())
|
||||
.and_then(|header: Option<String>, bytes: Bytes| async move {
|
||||
if let Some(header) = header {
|
||||
if header == SSZ_CONTENT_TYPE_HEADER {
|
||||
return Err(reject::unsupported_media_type(
|
||||
"The request's content-type is not supported".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Json::decode(bytes)
|
||||
.map_err(|err| reject::custom_deserialize_error(format!("{:?}", err)))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -136,6 +136,15 @@ pub fn invalid_auth(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(InvalidAuthorization(msg))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnsupportedMediaType(pub String);
|
||||
|
||||
impl Reject for UnsupportedMediaType {}
|
||||
|
||||
pub fn unsupported_media_type(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(UnsupportedMediaType(msg))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexedBadRequestErrors {
|
||||
pub message: String,
|
||||
@@ -170,6 +179,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 err.find::<crate::reject::UnsupportedMediaType>().is_some() {
|
||||
code = StatusCode::UNSUPPORTED_MEDIA_TYPE;
|
||||
message = "UNSUPPORTED_MEDIA_TYPE".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;
|
||||
|
||||
Reference in New Issue
Block a user