1use super::{HeaderName, HeaderNameInner};
2use std::{
3 fmt::{self, Debug, Display, Formatter},
4 hash::Hash,
5 str::FromStr,
6};
7
8impl Display for KnownHeaderName {
9 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
10 f.write_str(self.as_ref())
11 }
12}
13
14impl From<KnownHeaderName> for HeaderName<'_> {
15 fn from(khn: KnownHeaderName) -> Self {
16 Self(HeaderNameInner::KnownHeader(khn))
17 }
18}
19
20impl PartialEq<HeaderName<'_>> for KnownHeaderName {
21 fn eq(&self, other: &HeaderName) -> bool {
22 matches!(&other.0, HeaderNameInner::KnownHeader(k) if self == k)
23 }
24}
25
26impl AsRef<str> for KnownHeaderName {
27 fn as_ref(&self) -> &str {
28 self.as_str()
29 }
30}
31
32macro_rules! known_headers {
33 (
34 $(
35 ($capitalized:literal, $variant:tt)
36 ),+
37 ) => {
38
39 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
44 #[non_exhaustive]
45 #[repr(u8)]
46 pub enum KnownHeaderName {
47 $(
48 #[doc = concat!("The [", $capitalized, "](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/", $capitalized, ") header.")]
49 $variant,
50 )+
51 }
52
53 impl KnownHeaderName {
54 pub fn as_str(&self) -> &'static str {
56 match self {
57 $( Self::$variant => $capitalized, )+
58 }
59 }
60 }
61
62 impl FromStr for KnownHeaderName {
63 type Err = ();
64 fn from_str(s: &str) -> Result<Self, Self::Err> {
65 if !s.is_ascii() { return Err(()); }
66 let len = s.len();
67
68 $( if len == $capitalized.len() && s.eq_ignore_ascii_case($capitalized) { return Ok(Self::$variant); } )+
69 Err(())
70 }
71 }
72
73 #[cfg(test)]
74 mod known_header_name_tests {
75 use super::*;
76
77 #[test]
78 fn roundtrip_all_variants() {
79 $(
80 let parsed: KnownHeaderName = $capitalized.parse()
81 .unwrap_or_else(|_| panic!("failed to parse {:?}", $capitalized));
82 assert_eq!(
83 parsed,
84 KnownHeaderName::$variant,
85 "parse({:?}) returned wrong variant",
86 $capitalized,
87 );
88 assert_eq!(
89 parsed.as_str(),
90 $capitalized,
91 "as_str() mismatch for {:?}",
92 stringify!($variant),
93 );
94 )+
95 }
96
97 #[test]
98 fn case_insensitive_roundtrip() {
99 $(
100 let lower: KnownHeaderName = $capitalized.to_lowercase().parse()
101 .unwrap_or_else(|_| panic!("failed to parse lowercase {:?}", $capitalized));
102 assert_eq!(lower, KnownHeaderName::$variant);
103
104 let upper: KnownHeaderName = $capitalized.to_uppercase().parse()
105 .unwrap_or_else(|_| panic!("failed to parse uppercase {:?}", $capitalized));
106 assert_eq!(upper, KnownHeaderName::$variant);
107 )+
108 }
109
110 #[test]
111 fn unknown_headers_return_err() {
112 assert!("X-Unknown-Custom-Header".parse::<KnownHeaderName>().is_err());
113 assert!("".parse::<KnownHeaderName>().is_err());
114 assert!("Hostt".parse::<KnownHeaderName>().is_err());
115 assert!("Hos".parse::<KnownHeaderName>().is_err());
116 }
117 }
118 }
119}
120
121known_headers! {
139 ("Host", Host),
140 ("Date", Date),
141
142 ("Accept", Accept),
143 ("Accept-CH", AcceptCh),
144 ("Accept-CH-Lifetime", AcceptChLifetime),
145 ("Accept-Charset", AcceptCharset),
146 ("Accept-Encoding", AcceptEncoding),
147 ("Accept-Language", AcceptLanguage),
148 ("Accept-Push-Policy", AcceptPushPolicy),
149 ("Accept-Ranges", AcceptRanges),
150 ("Accept-Signature", AcceptSignature),
151 ("Access-Control-Allow-Credentials", AccessControlAllowCredentials),
152 ("Access-Control-Allow-Headers", AccessControlAllowHeaders),
153 ("Access-Control-Allow-Methods", AccessControlAllowMethods),
154 ("Access-Control-Allow-Origin", AccessControlAllowOrigin),
155 ("Access-Control-Expose-Headers", AccessControlExposeHeaders),
156 ("Access-Control-Max-Age", AccessControlMaxAge),
157 ("Access-Control-Request-Headers", AccessControlRequestHeaders),
158 ("Access-Control-Request-Method", AccessControlRequestMethod),
159 ("Age", Age),
160 ("Allow", Allow),
161 ("Alt-Svc", AltSvc),
162 ("Alt-Used", AltUsed),
163 ("Authorization", Authorization),
164 ("Cache-Control", CacheControl),
165 ("Clear-Site-Data", ClearSiteData),
166 ("Connection", Connection),
167 ("Content-DPR", ContentDpr),
168 ("Content-Digest", ContentDigest),
169 ("Content-Disposition", ContentDisposition),
170 ("Content-Encoding", ContentEncoding),
171 ("Content-Language", ContentLanguage),
172 ("Content-Length", ContentLength),
173 ("Content-Location", ContentLocation),
174 ("Content-Range", ContentRange),
175 ("Content-Security-Policy", ContentSecurityPolicy),
176 ("Content-Security-Policy-Report-Only", ContentSecurityPolicyReportOnly),
177 ("Content-Type", ContentType),
178 ("Cookie", Cookie),
179 ("Cookie2", Cookie2),
180 ("Cross-Origin-Embedder-Policy", CrossOriginEmbedderPolicy),
181 ("Cross-Origin-Opener-Policy", CrossOriginOpenerPolicy),
182 ("Cross-Origin-Resource-Policy", CrossOriginResourcePolicy),
183 ("DNT", Dnt),
184 ("DPR", Dpr),
185 ("DPoP", Dpop),
186 ("Deprecation", Deprecation),
187 ("Device-Memory", DeviceMemory),
188 ("Digest", Digest),
189 ("Downlink", Downlink),
190 ("ECT", Ect),
191 ("ETag", Etag),
192 ("Early-Data", EarlyData),
193 ("Expect", Expect),
194 ("Expect-CT", ExpectCt),
195 ("Expires", Expires),
196 ("Feature-Policy", FeaturePolicy),
197 ("Forwarded", Forwarded),
198 ("From", From),
199 ("If-Match", IfMatch),
200 ("If-Modified-Since", IfModifiedSince),
201 ("If-None-Match", IfNoneMatch),
202 ("If-Range", IfRange),
203 ("If-Unmodified-Since", IfUnmodifiedSince),
204 ("Keep-Alive", KeepAlive),
205 ("Large-Allocation", LargeAllocation),
206 ("Last-Event-ID", LastEventId),
207 ("Last-Modified", LastModified),
208 ("Link", Link),
209 ("Location", Location),
210 ("Max-Forwards", MaxForwards),
211 ("NEL", Nel),
212 ("Origin", Origin),
213 ("Origin-Isolation", OriginIsolation),
214 ("Permissions-Policy", PermissionsPolicy),
215 ("Ping-From", PingFrom),
216 ("Ping-To", PingTo),
217 ("Pragma", Pragma),
218 ("Priority", Priority),
219 ("Proxy-Authenticate", ProxyAuthenticate),
220 ("Proxy-Authorization", ProxyAuthorization),
221 ("Proxy-Connection", ProxyConnection),
222 ("Proxy-Status", ProxyStatus),
223 ("Public-Key-Pins", PublicKeyPins),
224 ("Public-Key-Pins-Report-Only", PublicKeyPinsReportOnly),
225 ("Purpose", Purpose),
226 ("Push-Policy", PushPolicy),
227 ("RTT", Rtt),
228 ("Range", Range),
229 ("RateLimit-Reset", RatelimitReset),
230 ("Ratelimit-Limit", RatelimitLimit),
231 ("Ratelimit-Remaining", RatelimitRemaining),
232 ("Referer", Referer),
233 ("Referrer-Policy", ReferrerPolicy),
234 ("Refresh-Cache", RefreshCache),
235 ("Report-To", ReportTo),
236 ("Repr-Digest", ReprDigest),
237 ("Retry-After", RetryAfter),
238 ("Save-Data", SaveData),
239 ("Sec-CH-UA", SecChUa),
240 ("Sec-CH-UA-Mobile", SecChUAMobile),
241 ("Sec-CH-UA-Platform", SecChUAPlatform),
242 ("Sec-Fetch-Dest", SecFetchDest),
243 ("Sec-Fetch-Mode", SecFetchMode),
244 ("Sec-Fetch-Site", SecFetchSite),
245 ("Sec-Fetch-User", SecFetchUser),
246 ("Sec-GPC", SecGpc),
247 ("Sec-WebSocket-Accept", SecWebsocketAccept),
248 ("Sec-WebSocket-Extensions", SecWebsocketExtensions),
249 ("Sec-WebSocket-Key", SecWebsocketKey),
250 ("Sec-WebSocket-Protocol", SecWebsocketProtocol),
251 ("Sec-WebSocket-Version", SecWebsocketVersion),
252 ("Server", Server),
253 ("Server-Timing", ServerTiming),
254 ("Service-Worker-Allowed", ServiceWorkerAllowed),
255 ("Set-Cookie", SetCookie),
256 ("Set-Cookie2", SetCookie2),
257 ("Signature", Signature),
258 ("Signed-Headers", SignedHeaders),
259 ("SourceMap", Sourcemap),
260 ("Strict-Transport-Security", StrictTransportSecurity),
261 ("TE", Te),
262 ("Timing-Allow-Origin", TimingAllowOrigin),
263 ("Traceparent", Traceparent),
264 ("Tracestate", Tracestate),
265 ("Trailer", Trailer),
266 ("Transfer-Encoding", TransferEncoding),
267 ("Upgrade", Upgrade),
268 ("Upgrade-Insecure-Requests", UpgradeInsecureRequests),
269 ("User-Agent", UserAgent),
270 ("Vary", Vary),
271 ("Via", Via),
272 ("Viewport-Width", ViewportWidth),
273 ("WWW-Authenticate", WwwAuthenticate),
274 ("Want-Content-Digest", WantContentDigest),
275 ("Want-Digest", WantDigest),
276 ("Want-Repr-Digest", WantReprDigest),
277 ("Warning", Warning),
278 ("Width", Width),
279 ("X-B3-Traceid", Xb3Traceid),
280 ("X-Cache", Xcache),
281 ("X-Content-Type-Options", XcontentTypeOptions),
282 ("X-Correlation-ID", XcorrelationId),
283 ("X-DNS-Prefetch-Control", XdnsPrefetchControl),
284 ("X-Download-Options", XdownloadOptions),
285 ("X-Firefox-Spdy", XfirefoxSpdy),
286 ("X-Forwarded-By", XforwardedBy),
287 ("X-Forwarded-For", XforwardedFor),
288 ("X-Forwarded-Host", XforwardedHost),
289 ("X-Forwarded-Proto", XforwardedProto),
290 ("X-Forwarded-SSL", XforwardedSsl),
291 ("X-Frame-Options", XframeOptions),
292 ("X-Permitted-Cross-Domain-Policies", XpermittedCrossDomainPolicies),
293 ("X-Pingback", Xpingback),
294 ("X-Powered-By", XpoweredBy),
295 ("X-Real-IP", XrealIp),
296 ("X-Request-Id", XrequestId),
297 ("X-Requested-With", XrequestedWith),
298 ("X-Robots-Tag", XrobotsTag),
299 ("X-Runtime", Xruntime),
300 ("X-Served-By", XservedBy),
301 ("X-UA-Compatible", XuaCompatible),
302 ("X-XSS-Protection", XxssProtection)
303}