http_extract/
content_type.rs1use http::{HeaderMap, Request, header::CONTENT_TYPE};
10
11use crate::{Error, header::extract_single_header_text};
12
13pub fn extract_header_content_type(headers: &HeaderMap) -> Result<Option<mime::Mime>, Error> {
20 extract_single_header_text(headers, &CONTENT_TYPE)?
21 .map(|value| {
22 value
23 .parse()
24 .map_err(|_| Error::invalid_header(CONTENT_TYPE))
25 })
26 .transpose()
27}
28
29pub fn extract_request_content_type<B>(request: &Request<B>) -> Result<Option<mime::Mime>, Error> {
35 extract_header_content_type(request.headers())
36}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41
42 #[test]
43 fn extracts_a_singular_media_type() {
44 let mut headers = HeaderMap::new();
45 headers.insert(
46 CONTENT_TYPE,
47 "application/json; charset=utf-8".parse().unwrap(),
48 );
49
50 let value = extract_header_content_type(&headers).unwrap().unwrap();
51 assert_eq!(value.type_(), "application");
52 assert_eq!(value.subtype(), "json");
53 }
54
55 #[test]
56 fn rejects_duplicate_content_type() {
57 let mut headers = HeaderMap::new();
58 headers.append(CONTENT_TYPE, "application/json".parse().unwrap());
59 headers.append(CONTENT_TYPE, "text/plain".parse().unwrap());
60
61 assert!(matches!(
62 extract_header_content_type(&headers),
63 Err(Error::DuplicateHeader { .. })
64 ));
65 }
66
67 #[test]
68 fn request_entry_point_delegates_to_headers() {
69 let request = Request::builder()
70 .header(CONTENT_TYPE, "application/json")
71 .body(())
72 .unwrap();
73 assert_eq!(
74 extract_request_content_type(&request).unwrap(),
75 Some(mime::APPLICATION_JSON)
76 );
77 }
78}