1macro_rules! header {
2 ($value:literal) => {{
3 static GENERATED_HEADER_VALUE: ::http::HeaderValue =
4 ::http::HeaderValue::from_static($value);
5 GENERATED_HEADER_VALUE.clone()
6 }};
7}
8
9macro_rules! header_name {
11 ($value:literal) => {{
12 static GENERATED_HEADER_NAME: ::http::HeaderName = ::http::HeaderName::from_static($value);
13 GENERATED_HEADER_NAME.clone()
14 }};
15}
16
17mod csp;
18mod sts;
19
20pub use csp::{ContentSecurityPolicy, CspHashAlgorithm, CspSchemeSource, CspSource};
21use http::{
22 header::{
23 REFERRER_POLICY, X_CONTENT_TYPE_OPTIONS, X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS,
24 X_XSS_PROTECTION,
25 },
26 HeaderName, HeaderValue,
27};
28pub use sts::StrictTransportSecurity;
29
30pub trait Header {
31 fn name(&self) -> HeaderName;
32 fn value(&self) -> HeaderValue;
33}
34
35#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
36pub enum CrossOriginEmbedderPolicy {
37 #[default]
38 RequireCorp,
39 Credentialless,
40 UnsafeNone,
41}
42
43impl Header for CrossOriginEmbedderPolicy {
44 fn name(&self) -> HeaderName {
45 header_name!("cross-origin-embedder-policy")
46 }
47
48 fn value(&self) -> HeaderValue {
49 match self {
50 Self::RequireCorp => header!("require-corp"),
51 Self::Credentialless => header!("credentialless"),
52 Self::UnsafeNone => header!("unsafe-none"),
53 }
54 }
55}
56
57#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
58pub enum CrossOriginOpenerPolicy {
59 #[default]
60 SameOrigin,
61 SameOriginAllowPopups,
62 UnsafeNone,
63}
64
65impl Header for CrossOriginOpenerPolicy {
66 fn name(&self) -> HeaderName {
67 header_name!("cross-origin-opener-policy")
68 }
69
70 fn value(&self) -> HeaderValue {
71 match self {
72 Self::SameOrigin => header!("same-origin"),
73 Self::SameOriginAllowPopups => header!("same-origin-allow-popups"),
74 Self::UnsafeNone => header!("unsafe-none"),
75 }
76 }
77}
78
79#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
80pub enum CrossOriginResourcePolicy {
81 #[default]
82 SameOrigin,
83 SameSite,
84 CrossOrigin,
85}
86
87impl Header for CrossOriginResourcePolicy {
88 fn name(&self) -> HeaderName {
89 header_name!("cross-origin-resource-policy")
90 }
91
92 fn value(&self) -> HeaderValue {
93 match self {
94 Self::SameOrigin => header!("same-origin"),
95 Self::SameSite => header!("same-site"),
96 Self::CrossOrigin => header!("cross-origin"),
97 }
98 }
99}
100
101#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
102pub struct OriginAgentCluster;
103
104impl Header for OriginAgentCluster {
105 fn name(&self) -> HeaderName {
106 header_name!("origin-agent-cluster")
107 }
108
109 fn value(&self) -> HeaderValue {
110 header!("?1")
111 }
112}
113
114#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
115pub enum ReferrerPolicy {
116 #[default]
117 NoReferrer,
119 NoReferrerWhenDowngrade,
121 Origin,
123 OriginWhenCrossOrigin,
125 SameOrigin,
127 StrictOrigin,
129 StrictOriginWhenCrossOrigin,
131 UnsafeUrl,
133}
134
135impl Header for ReferrerPolicy {
136 fn name(&self) -> HeaderName {
137 REFERRER_POLICY
138 }
139
140 fn value(&self) -> HeaderValue {
141 match self {
142 Self::NoReferrer => header!("no-referrer"),
143 Self::NoReferrerWhenDowngrade => header!("no-referrer-when-downgrade"),
144 Self::Origin => header!("origin"),
145 Self::OriginWhenCrossOrigin => header!("origin-when-cross-origin"),
146 Self::SameOrigin => header!("same-origin"),
147 Self::StrictOrigin => header!("strict-origin"),
148 Self::StrictOriginWhenCrossOrigin => header!("strict-origin-when-cross-origin"),
149
150 Self::UnsafeUrl => header!("unsafe-url"),
151 }
152 }
153}
154
155#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
156pub struct XContentTypeOptions;
157
158impl Header for XContentTypeOptions {
159 fn name(&self) -> HeaderName {
160 X_CONTENT_TYPE_OPTIONS
161 }
162
163 fn value(&self) -> HeaderValue {
164 header!("nosniff")
165 }
166}
167
168#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
169pub enum XDnsPrefetchControl {
170 On,
171 #[default]
172 Off,
173}
174
175impl Header for XDnsPrefetchControl {
176 fn name(&self) -> HeaderName {
177 X_DNS_PREFETCH_CONTROL
178 }
179
180 fn value(&self) -> HeaderValue {
181 match self {
182 Self::Off => header!("off"),
183 Self::On => header!("on"),
184 }
185 }
186}
187
188#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
189pub struct XDownloadOptions;
190
191impl Header for XDownloadOptions {
192 fn name(&self) -> HeaderName {
193 header_name!("x-download-options")
194 }
195
196 fn value(&self) -> HeaderValue {
197 header!("noopen")
198 }
199}
200
201#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
202pub enum XFrameOptions {
203 Deny,
204 #[default]
205 Sameorigin,
206}
207
208impl Header for XFrameOptions {
209 fn name(&self) -> HeaderName {
210 X_FRAME_OPTIONS
211 }
212
213 fn value(&self) -> HeaderValue {
214 match self {
215 Self::Deny => header!("DENY"),
216 Self::Sameorigin => header!("SAMEORIGIN"),
217 }
218 }
219}
220
221#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
222pub enum XPermittedCrossDomainPolicies {
223 #[default]
224 None,
225 MasterOnly,
226 ByContentType,
227 All,
228}
229
230impl Header for XPermittedCrossDomainPolicies {
231 fn name(&self) -> HeaderName {
232 header_name!("x-permitted-cross-domain-policies")
233 }
234
235 fn value(&self) -> HeaderValue {
236 match self {
237 Self::None => header!("none"),
238 Self::MasterOnly => header!("master-only"),
239 Self::ByContentType => header!("by-content-type"),
240 Self::All => header!("all"),
241 }
242 }
243}
244
245#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
246pub enum XXssProtection {
247 #[default]
248 False,
249 TrueBlock,
250 True,
251}
252
253impl Header for XXssProtection {
254 fn name(&self) -> HeaderName {
255 X_XSS_PROTECTION
256 }
257
258 fn value(&self) -> HeaderValue {
259 match self {
260 Self::TrueBlock => header!("1; mode=block"),
261 Self::True => header!("1"),
262 Self::False => header!("0"),
263 }
264 }
265}