rama_http_headers/common/
x_frame_options.rs1use rama_http_types::{HeaderName, HeaderValue};
2
3use crate::{Error, HeaderDecode, HeaderEncode, TypedHeader};
4
5#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
26pub enum XFrameOptions {
27 Deny,
29 SameOrigin,
31}
32
33impl XFrameOptions {
34 fn as_str(self) -> &'static str {
35 match self {
36 Self::Deny => "DENY",
37 Self::SameOrigin => "SAMEORIGIN",
38 }
39 }
40}
41
42impl TypedHeader for XFrameOptions {
43 fn name() -> &'static HeaderName {
44 &::rama_http_types::header::X_FRAME_OPTIONS
45 }
46}
47
48impl HeaderDecode for XFrameOptions {
49 fn decode<'i, I: Iterator<Item = &'i HeaderValue>>(values: &mut I) -> Result<Self, Error> {
50 values
51 .next()
52 .and_then(|value| {
53 let s = value.to_str().ok()?.trim();
54 if s.eq_ignore_ascii_case("DENY") {
55 Some(Self::Deny)
56 } else if s.eq_ignore_ascii_case("SAMEORIGIN") {
57 Some(Self::SameOrigin)
58 } else {
59 None
61 }
62 })
63 .ok_or_else(Error::invalid)
64 }
65}
66
67impl HeaderEncode for XFrameOptions {
68 fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
69 values.extend(::std::iter::once(HeaderValue::from_static(self.as_str())));
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::super::test_decode;
76 use super::*;
77
78 #[test]
79 fn decode_deny() {
80 assert_eq!(
81 test_decode::<XFrameOptions>(&["DENY"]),
82 Some(XFrameOptions::Deny),
83 );
84 }
85
86 #[test]
87 fn decode_sameorigin() {
88 assert_eq!(
89 test_decode::<XFrameOptions>(&["SAMEORIGIN"]),
90 Some(XFrameOptions::SameOrigin),
91 );
92 }
93
94 #[test]
95 fn decode_case_insensitive() {
96 assert_eq!(
97 test_decode::<XFrameOptions>(&["deny"]),
98 Some(XFrameOptions::Deny),
99 );
100 assert_eq!(
101 test_decode::<XFrameOptions>(&["SameOrigin"]),
102 Some(XFrameOptions::SameOrigin),
103 );
104 }
105
106 #[test]
107 fn decode_rejects_allow_from() {
108 assert_eq!(
109 test_decode::<XFrameOptions>(&["ALLOW-FROM https://example.com"]),
110 None,
111 );
112 assert_eq!(test_decode::<XFrameOptions>(&["ALLOW-FROM"]), None);
113 assert_eq!(test_decode::<XFrameOptions>(&["allow-from *"]), None);
114 }
115
116 #[test]
117 fn decode_rejects_other_values() {
118 assert_eq!(test_decode::<XFrameOptions>(&[""]), None);
119 assert_eq!(test_decode::<XFrameOptions>(&["allowall"]), None);
120 assert_eq!(test_decode::<XFrameOptions>(&["DENY, SAMEORIGIN"]), None);
121 }
122}