1
Fork 0

nodeinfo: Split off Content-Type parameters before checking the MIME type

This commit is contained in:
Steffo 2024-11-09 14:57:55 +01:00
parent de5fdf26f3
commit d964f1befc
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0

View file

@ -2,6 +2,7 @@
//! //!
//! [RFC 6415]: https://datatracker.ietf.org/doc/html/rfc6415 //! [RFC 6415]: https://datatracker.ietf.org/doc/html/rfc6415
use reqwest::header::HeaderValue;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
/// A [host-meta document]. /// A [host-meta document].
@ -60,15 +61,21 @@ impl HostMetaDocument {
.await .await
.map_err(Request)?; .map_err(Request)?;
log::trace!("Checking headers of the response..."); log::trace!("Checking `Content-Type` of the response...");
response let content_type = response
.headers() .headers()
.get(reqwest::header::CONTENT_TYPE) .get(reqwest::header::CONTENT_TYPE)
.ok_or(ContentTypeMissing)? .ok_or(ContentTypeMissing)?;
.eq("application/json")
.then_some(()) log::trace!("Extracting MIME type from the `Content-Type` header...");
let mime_type = extract_mime_from_content_type(content_type)
.ok_or(ContentTypeInvalid)?; .ok_or(ContentTypeInvalid)?;
log::trace!("Ensuring MIME type of `{mime_type}` is acceptable for JRD parsing...");
if mime_type != "application/json" {
return Err(ContentTypeInvalid)
}
log::trace!("Attempting to parse response as JSON..."); log::trace!("Attempting to parse response as JSON...");
let data = response.json::<Self>() let data = response.json::<Self>()
.await .await
@ -107,15 +114,21 @@ impl HostMetaDocument {
.await .await
.map_err(Request)?; .map_err(Request)?;
log::trace!("Checking headers of the response..."); log::trace!("Checking `Content-Type` of the response...");
response let content_type = response
.headers() .headers()
.get(reqwest::header::CONTENT_TYPE) .get(reqwest::header::CONTENT_TYPE)
.ok_or(ContentTypeMissing)? .ok_or(ContentTypeMissing)?;
.eq("application/xrd+json")
.then_some(()) log::trace!("Extracting MIME type from the `Content-Type` header...");
let mime_type = extract_mime_from_content_type(content_type)
.ok_or(ContentTypeInvalid)?; .ok_or(ContentTypeInvalid)?;
log::trace!("Ensuring MIME type of `{mime_type}` is acceptable for JRD parsing...");
if mime_type != "application/xrd+xml" {
return Err(ContentTypeInvalid)
}
log::trace!("Attempting to parse response as text..."); log::trace!("Attempting to parse response as text...");
let data = response.text() let data = response.text()
.await .await
@ -302,4 +315,13 @@ pub enum HostMetaGetJRDError {
ContentTypeInvalid, ContentTypeInvalid,
/// The document failed to be parsed as JSON by [`reqwest`]. /// The document failed to be parsed as JSON by [`reqwest`].
Parse(reqwest::Error), Parse(reqwest::Error),
} }
/// Extract the MIME type from the value of the `Content-Type` header.
fn extract_mime_from_content_type(value: &HeaderValue) -> Option<String> {
let value = value.to_str().ok()?;
match value.split_once("; ") {
None => Some(value.to_string()),
Some((mime, _)) => Some(mime.to_string()),
}
}