use http::{HeaderMap, Request, header::CONTENT_TYPE};
use crate::{Error, header::extract_single_header_text};
pub fn extract_header_content_type(headers: &HeaderMap) -> Result<Option<mime::Mime>, Error> {
extract_single_header_text(headers, &CONTENT_TYPE)?
.map(|value| {
value
.parse()
.map_err(|_| Error::invalid_header(CONTENT_TYPE))
})
.transpose()
}
pub fn extract_request_content_type<B>(request: &Request<B>) -> Result<Option<mime::Mime>, Error> {
extract_header_content_type(request.headers())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extracts_a_singular_media_type() {
let mut headers = HeaderMap::new();
headers.insert(
CONTENT_TYPE,
"application/json; charset=utf-8".parse().unwrap(),
);
let value = extract_header_content_type(&headers).unwrap().unwrap();
assert_eq!(value.type_(), "application");
assert_eq!(value.subtype(), "json");
}
#[test]
fn rejects_duplicate_content_type() {
let mut headers = HeaderMap::new();
headers.append(CONTENT_TYPE, "application/json".parse().unwrap());
headers.append(CONTENT_TYPE, "text/plain".parse().unwrap());
assert!(matches!(
extract_header_content_type(&headers),
Err(Error::DuplicateHeader { .. })
));
}
#[test]
fn request_entry_point_delegates_to_headers() {
let request = Request::builder()
.header(CONTENT_TYPE, "application/json")
.body(())
.unwrap();
assert_eq!(
extract_request_content_type(&request).unwrap(),
Some(mime::APPLICATION_JSON)
);
}
}