actix_web/guard/
acceptable.rs1use super::{Guard, GuardContext};
2use crate::http::header::Accept;
3
4#[derive(Debug, Clone)]
20pub struct Acceptable {
21 mime: mime::Mime,
22
23 match_star_star: bool,
27}
28
29impl Acceptable {
30 pub fn new(mime: mime::Mime) -> Self {
32 Self {
33 mime,
34 match_star_star: false,
35 }
36 }
37
38 pub fn match_star_star(mut self) -> Self {
40 self.match_star_star = true;
41 self
42 }
43}
44
45impl Guard for Acceptable {
46 fn check(&self, ctx: &GuardContext<'_>) -> bool {
47 let accept = match ctx.header::<Accept>() {
48 Some(hdr) => hdr,
49 None => return false,
50 };
51
52 let target_type = self.mime.type_();
53 let target_subtype = self.mime.subtype();
54
55 for mime in accept.0.into_iter().map(|q| q.item) {
56 return match (mime.type_(), mime.subtype()) {
57 (typ, subtype) if typ == target_type && subtype == target_subtype => true,
58 (typ, mime::STAR) if typ == target_type => true,
59 (mime::STAR, mime::STAR) if self.match_star_star => true,
60 _ => continue,
61 };
62 }
63
64 false
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use crate::{http::header, test::TestRequest};
72
73 #[test]
74 fn test_acceptable() {
75 let req = TestRequest::default().to_srv_request();
76 assert!(!Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
77
78 let req = TestRequest::default()
79 .insert_header((header::ACCEPT, "application/json"))
80 .to_srv_request();
81 assert!(Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
82
83 let req = TestRequest::default()
84 .insert_header((header::ACCEPT, "text/html, application/json"))
85 .to_srv_request();
86 assert!(Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
87 }
88
89 #[test]
90 fn test_acceptable_star() {
91 let req = TestRequest::default()
92 .insert_header((header::ACCEPT, "text/html, */*;q=0.8"))
93 .to_srv_request();
94
95 assert!(Acceptable::new(mime::APPLICATION_JSON)
96 .match_star_star()
97 .check(&req.guard_ctx()));
98 }
99}