From 79e604eb963e5b7be897f068770db6295b998f45 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 19 Nov 2024 06:41:19 +0100 Subject: [PATCH] `rdserver`: Use `mediatype` to process `Accept` header --- acrate_rdserver/src/route.rs | 38 ++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/acrate_rdserver/src/route.rs b/acrate_rdserver/src/route.rs index 753f288..61ba271 100644 --- a/acrate_rdserver/src/route.rs +++ b/acrate_rdserver/src/route.rs @@ -1,9 +1,10 @@ +use std::iter::IntoIterator; use std::sync::Arc; use axum::Extension; use axum::extract::Path; use axum::http::{HeaderMap, Response, StatusCode}; use axum_extra::extract::Query; -use mediatype::MediaTypeBuf; +use mediatype::{MediaTypeBuf, MediaTypeList}; use serde::Deserialize; use acrate_database::diesel::GroupedBy; use acrate_database::diesel_async::{AsyncConnection, AsyncPgConnection}; @@ -20,8 +21,6 @@ pub struct WebfingerQuery { pub rel: Vec, } -#[allow(unused_variables)] // Inspection seems to be broken on this function. Idk why... -#[axum::debug_handler] pub async fn webfinger_handler( Path(path): Path, Query(WebfingerQuery {resource, rel}): Query, @@ -38,13 +37,13 @@ pub async fn webfinger_handler( log::debug!("Rel is: {rel:#?}"); - let accept = headers.get("Accept") - .map(|v| v.to_str()) - .filter(Result::is_ok) - .map(|v| v.unwrap()) - .unwrap_or("application/json") - .to_string(); + let accept = headers.get("Accept"); log::debug!("Accept is: {accept:#?}"); + let accept = accept + .map(|h| h.to_str()) + .unwrap_or(Ok("*/*")) + .map(|h| MediaTypeList::new(h)) + .map_err(|_| StatusCode::BAD_REQUEST)?; let mut response = Response::new("".to_string()); @@ -118,21 +117,26 @@ pub async fn webfinger_handler( ); } - for mime in accept.split(",") { + for media_type in accept.into_iter() { + let media_type = match media_type { + Err(e) => { + log::debug!("Skipping error while parsing media type: {e:?}"); + continue; + }, + Ok(media_type) => media_type + }; + { let headers = response.headers_mut(); headers.insert( "Content-Type", - mime.parse().map_err(|_| StatusCode::BAD_REQUEST)? + media_type.to_string() + .parse() + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? ); } - let (mime, _params) = match mime.trim().split_once(";") { - Some((mime, params)) => (mime, Some(params)), - None => (mime, None), - }; - - match mime { + match media_type.essence().to_string().to_ascii_lowercase().as_str() { "*/*" | "application/json" | "application/jrd+json" => { let aliases = aliases .into_iter()