mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-22 11:41:28 +00:00
Fix http header accept parsing problem (#3185)
## Issue Addressed Which issue # does this PR address? #3114 ## Proposed Changes 1. introduce `mime` package 2. Parse `Accept` field in the header with `mime` ## Additional Info Please provide any additional information. For example, future considerations or information useful for reviewers.
This commit is contained in:
parent
def9bc660e
commit
0428018cc1
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1586,6 +1586,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"libsecp256k1",
|
||||
"lighthouse_network",
|
||||
"mime",
|
||||
"procinfo",
|
||||
"proto_array",
|
||||
"psutil",
|
||||
|
@ -26,6 +26,7 @@ futures-util = "0.3.8"
|
||||
futures = "0.3.8"
|
||||
store = { path = "../../beacon_node/store", optional = true }
|
||||
slashing_protection = { path = "../../validator_client/slashing_protection", optional = true }
|
||||
mime = "0.3.16"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
psutil = { version = "3.2.2", optional = true }
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
use crate::Error as ServerError;
|
||||
use lighthouse_network::{ConnectionDirection, Enr, Multiaddr, PeerConnectionStatus};
|
||||
use mime::{Mime, APPLICATION, JSON, OCTET_STREAM, STAR};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Reverse;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::str::{from_utf8, FromStr};
|
||||
@ -1008,15 +1010,37 @@ impl FromStr for Accept {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"application/octet-stream" => Ok(Accept::Ssz),
|
||||
"application/json" => Ok(Accept::Json),
|
||||
"*/*" => Ok(Accept::Any),
|
||||
_ => Err("accept header cannot be parsed.".to_string()),
|
||||
}
|
||||
let mut mimes = parse_accept(s)?;
|
||||
|
||||
// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
|
||||
// find the highest q-factor supported accept type
|
||||
mimes.sort_by_key(|m| {
|
||||
Reverse(m.get_param("q").map_or(1000_u16, |n| {
|
||||
(n.as_ref().parse::<f32>().unwrap_or(0_f32) * 1000_f32) as u16
|
||||
}))
|
||||
});
|
||||
mimes
|
||||
.into_iter()
|
||||
.find_map(|m| match (m.type_(), m.subtype()) {
|
||||
(APPLICATION, OCTET_STREAM) => Some(Accept::Ssz),
|
||||
(APPLICATION, JSON) => Some(Accept::Json),
|
||||
(STAR, STAR) => Some(Accept::Any),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or_else(|| "accept header is not supported".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_accept(accept: &str) -> Result<Vec<Mime>, String> {
|
||||
accept
|
||||
.split(',')
|
||||
.map(|part| {
|
||||
part.parse()
|
||||
.map_err(|e| format!("error parsing Accept header: {}", e))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LivenessRequestData {
|
||||
pub epoch: Epoch,
|
||||
@ -1045,4 +1069,23 @@ mod tests {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_accept_header_content() {
|
||||
assert_eq!(
|
||||
Accept::from_str("application/json; charset=utf-8").unwrap(),
|
||||
Accept::Json
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Accept::from_str("text/plain,application/octet-stream;q=0.3,application/json;q=0.9")
|
||||
.unwrap(),
|
||||
Accept::Json
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Accept::from_str("text/plain"),
|
||||
Err("accept header is not supported".to_string())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user