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, $lower:literal)
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 #[cfg(test)]
55 pub(crate) const VARIANTS: &[KnownHeaderName] = &[$(Self::$variant,)+];
56
57 pub fn as_str(&self) -> &'static str {
59 match self {
60 $( Self::$variant => $capitalized, )+
61 }
62 }
63
64 pub(crate) fn as_lower_str(&self) -> &'static str {
66 match self {
67 $( Self::$variant => $lower, )+
68 }
69 }
70
71 pub(crate) fn lowercase_byte_match(bytes: &[u8]) -> Option<Self> {
73 let len = bytes.len();
74
75 $( if len == $lower.len() && bytes == $lower.as_bytes() { return Some(Self::$variant); } )+
76 None
77 }
78 }
79
80 impl FromStr for KnownHeaderName {
81 type Err = ();
82 fn from_str(s: &str) -> Result<Self, Self::Err> {
83 if !s.is_ascii() { return Err(()); }
84 let len = s.len();
85
86 $( if len == $capitalized.len() && s.eq_ignore_ascii_case($capitalized) { return Ok(Self::$variant); } )+
87 Err(())
88 }
89 }
90
91 #[cfg(test)]
92 mod known_header_name_tests {
93 use super::*;
94
95 #[test]
96 fn roundtrip_all_variants() {
97 $(
98 let parsed: KnownHeaderName = $capitalized.parse()
99 .unwrap_or_else(|_| panic!("failed to parse {:?}", $capitalized));
100 assert_eq!(
101 parsed,
102 KnownHeaderName::$variant,
103 "parse({:?}) returned wrong variant",
104 $capitalized,
105 );
106 assert_eq!(
107 parsed.as_str(),
108 $capitalized,
109 "as_str() mismatch for {:?}",
110 stringify!($variant),
111 );
112 )+
113 }
114
115 #[test]
116 fn roundtrip_all_lower_variants() {
117 $(
118 let parsed: KnownHeaderName = $lower.parse()
119 .unwrap_or_else(|_| panic!("failed to parse {:?}", $lower));
120 assert_eq!(
121 parsed,
122 KnownHeaderName::$variant,
123 "parse({:?}) returned wrong variant",
124 $lower,
125 );
126 assert_eq!(
127 parsed.as_lower_str(),
128 $lower,
129 "as_str() mismatch for {:?}",
130 stringify!($variant),
131 );
132 )+
133 }
134
135
136 #[test]
137 fn case_insensitive_roundtrip() {
138 $(
139 let lower: KnownHeaderName = $capitalized.to_lowercase().parse()
140 .unwrap_or_else(|_| panic!("failed to parse lowercase {:?}", $capitalized));
141 assert_eq!(lower, KnownHeaderName::$variant);
142
143 let upper: KnownHeaderName = $capitalized.to_uppercase().parse()
144 .unwrap_or_else(|_| panic!("failed to parse uppercase {:?}", $capitalized));
145 assert_eq!(upper, KnownHeaderName::$variant);
146 )+
147 }
148
149 #[test]
150 fn unknown_headers_return_err() {
151 assert!("X-Unknown-Custom-Header".parse::<KnownHeaderName>().is_err());
152 assert!("".parse::<KnownHeaderName>().is_err());
153 assert!("Hostt".parse::<KnownHeaderName>().is_err());
154 assert!("Hos".parse::<KnownHeaderName>().is_err());
155 }
156 }
157 }
158}
159
160known_headers! {
178 ("Host", Host, "host"),
179 ("Date", Date, "date"),
180
181 ("Accept", Accept, "accept"),
182 ("Accept-CH", AcceptCh, "accept-ch"),
183 ("Accept-CH-Lifetime", AcceptChLifetime, "accept-ch-lifetime"),
184 ("Accept-Charset", AcceptCharset, "accept-charset"),
185 ("Accept-Encoding", AcceptEncoding, "accept-encoding"),
186 ("Accept-Language", AcceptLanguage, "accept-language"),
187 ("Accept-Push-Policy", AcceptPushPolicy, "accept-push-policy"),
188 ("Accept-Ranges", AcceptRanges, "accept-ranges"),
189 ("Accept-Signature", AcceptSignature, "accept-signature"),
190 ("Access-Control-Allow-Credentials", AccessControlAllowCredentials, "access-control-allow-credentials"),
191 ("Access-Control-Allow-Headers", AccessControlAllowHeaders, "access-control-allow-headers"),
192 ("Access-Control-Allow-Methods", AccessControlAllowMethods, "access-control-allow-methods"),
193 ("Access-Control-Allow-Origin", AccessControlAllowOrigin, "access-control-allow-origin"),
194 ("Access-Control-Expose-Headers", AccessControlExposeHeaders, "access-control-expose-headers"),
195 ("Access-Control-Max-Age", AccessControlMaxAge, "access-control-max-age"),
196 ("Access-Control-Request-Headers", AccessControlRequestHeaders, "access-control-request-headers"),
197 ("Access-Control-Request-Method", AccessControlRequestMethod, "access-control-request-method"),
198 ("Age", Age, "age"),
199 ("Allow", Allow, "allow"),
200 ("Alt-Svc", AltSvc, "alt-svc"),
201 ("Alt-Used", AltUsed, "alt-used"),
202 ("Authentication-Info", AuthenticationInfo, "authentication-info"),
203 ("Authorization", Authorization, "authorization"),
204 ("Cache-Control", CacheControl, "cache-control"),
205 ("Clear-Site-Data", ClearSiteData, "clear-site-data"),
206 ("Connection", Connection, "connection"),
207 ("Content-DPR", ContentDpr, "content-dpr"),
208 ("Content-Digest", ContentDigest, "content-digest"),
209 ("Content-Disposition", ContentDisposition, "content-disposition"),
210 ("Content-Encoding", ContentEncoding, "content-encoding"),
211 ("Content-Language", ContentLanguage, "content-language"),
212 ("Content-Length", ContentLength, "content-length"),
213 ("Content-Location", ContentLocation, "content-location"),
214 ("Content-Range", ContentRange, "content-range"),
215 ("Content-Security-Policy", ContentSecurityPolicy, "content-security-policy"),
216 ("Content-Security-Policy-Report-Only", ContentSecurityPolicyReportOnly, "content-security-policy-report-only"),
217 ("Content-Type", ContentType, "content-type"),
218 ("Cookie", Cookie, "cookie"),
219 ("Cookie2", Cookie2, "cookie2"),
220 ("Cross-Origin-Embedder-Policy", CrossOriginEmbedderPolicy, "cross-origin-embedder-policy"),
221 ("Cross-Origin-Opener-Policy", CrossOriginOpenerPolicy, "cross-origin-opener-policy"),
222 ("Cross-Origin-Resource-Policy", CrossOriginResourcePolicy, "cross-origin-resource-policy"),
223 ("DNT", Dnt, "dnt"),
224 ("DPR", Dpr, "dpr"),
225 ("DPoP", Dpop, "dpop"),
226 ("Deprecation", Deprecation, "deprecation"),
227 ("Device-Memory", DeviceMemory, "device-memory"),
228 ("Digest", Digest, "digest"),
229 ("Downlink", Downlink, "downlink"),
230 ("ECT", Ect, "ect"),
231 ("ETag", Etag, "etag"),
232 ("Early-Data", EarlyData, "early-data"),
233 ("Expect", Expect, "expect"),
234 ("Expect-CT", ExpectCt, "expect-ct"),
235 ("Expires", Expires, "expires"),
236 ("Feature-Policy", FeaturePolicy, "feature-policy"),
237 ("Forwarded", Forwarded, "forwarded"),
238 ("From", From, "from"),
239 ("If-Match", IfMatch, "if-match"),
240 ("If-Modified-Since", IfModifiedSince, "if-modified-since"),
241 ("If-None-Match", IfNoneMatch, "if-none-match"),
242 ("If-Range", IfRange, "if-range"),
243 ("If-Unmodified-Since", IfUnmodifiedSince, "if-unmodified-since"),
244 ("Keep-Alive", KeepAlive, "keep-alive"),
245 ("Large-Allocation", LargeAllocation, "large-allocation"),
246 ("Last-Event-ID", LastEventId, "last-event-id"),
247 ("Last-Modified", LastModified, "last-modified"),
248 ("Link", Link, "link"),
249 ("Location", Location, "location"),
250 ("Max-Forwards", MaxForwards, "max-forwards"),
251 ("NEL", Nel, "nel"),
252 ("Origin", Origin, "origin"),
253 ("Origin-Isolation", OriginIsolation, "origin-isolation"),
254 ("Permissions-Policy", PermissionsPolicy, "permissions-policy"),
255 ("Ping-From", PingFrom, "ping-from"),
256 ("Ping-To", PingTo, "ping-to"),
257 ("Pragma", Pragma, "pragma"),
258 ("Priority", Priority, "priority"),
259 ("Proxy-Authenticate", ProxyAuthenticate, "proxy-authenticate"),
260 ("Proxy-Authentication-Info", ProxyAuthenticationInfo, "proxy-authentication-info"),
261 ("Proxy-Authorization", ProxyAuthorization, "proxy-authorization"),
262 ("Proxy-Connection", ProxyConnection, "proxy-connection"),
263 ("Proxy-Status", ProxyStatus, "proxy-status"),
264 ("Public-Key-Pins", PublicKeyPins, "public-key-pins"),
265 ("Public-Key-Pins-Report-Only", PublicKeyPinsReportOnly, "public-key-pins-report-only"),
266 ("Purpose", Purpose, "purpose"),
267 ("Push-Policy", PushPolicy, "push-policy"),
268 ("RTT", Rtt, "rtt"),
269 ("Range", Range, "range"),
270 ("RateLimit-Reset", RatelimitReset, "ratelimit-reset"),
271 ("Ratelimit-Limit", RatelimitLimit, "ratelimit-limit"),
272 ("Ratelimit-Remaining", RatelimitRemaining, "ratelimit-remaining"),
273 ("Referer", Referer, "referer"),
274 ("Referrer-Policy", ReferrerPolicy, "referrer-policy"),
275 ("Refresh-Cache", RefreshCache, "refresh-cache"),
276 ("Report-To", ReportTo, "report-to"),
277 ("Repr-Digest", ReprDigest, "repr-digest"),
278 ("Retry-After", RetryAfter, "retry-after"),
279 ("Save-Data", SaveData, "save-data"),
280 ("Sec-CH-UA", SecChUa, "sec-ch-ua"),
281 ("Sec-CH-UA-Mobile", SecChUAMobile, "sec-ch-ua-mobile"),
282 ("Sec-CH-UA-Platform", SecChUAPlatform, "sec-ch-ua-platform"),
283 ("Sec-Fetch-Dest", SecFetchDest, "sec-fetch-dest"),
284 ("Sec-Fetch-Mode", SecFetchMode, "sec-fetch-mode"),
285 ("Sec-Fetch-Site", SecFetchSite, "sec-fetch-site"),
286 ("Sec-Fetch-User", SecFetchUser, "sec-fetch-user"),
287 ("Sec-GPC", SecGpc, "sec-gpc"),
288 ("Sec-WebSocket-Accept", SecWebsocketAccept, "sec-websocket-accept"),
289 ("Sec-WebSocket-Extensions", SecWebsocketExtensions, "sec-websocket-extensions"),
290 ("Sec-WebSocket-Key", SecWebsocketKey, "sec-websocket-key"),
291 ("Sec-WebSocket-Protocol", SecWebsocketProtocol, "sec-websocket-protocol"),
292 ("Sec-WebSocket-Version", SecWebsocketVersion, "sec-websocket-version"),
293 ("Server", Server, "server"),
294 ("Server-Timing", ServerTiming, "server-timing"),
295 ("Service-Worker-Allowed", ServiceWorkerAllowed, "service-worker-allowed"),
296 ("Set-Cookie", SetCookie, "set-cookie"),
297 ("Set-Cookie2", SetCookie2, "set-cookie2"),
298 ("Signature", Signature, "signature"),
299 ("Signed-Headers", SignedHeaders, "signed-headers"),
300 ("SourceMap", Sourcemap, "sourcemap"),
301 ("Strict-Transport-Security", StrictTransportSecurity, "strict-transport-security"),
302 ("TE", Te, "te"),
303 ("Timing-Allow-Origin", TimingAllowOrigin, "timing-allow-origin"),
304 ("Traceparent", Traceparent, "traceparent"),
305 ("Tracestate", Tracestate, "tracestate"),
306 ("Trailer", Trailer, "trailer"),
307 ("Transfer-Encoding", TransferEncoding, "transfer-encoding"),
308 ("Upgrade", Upgrade, "upgrade"),
309 ("Upgrade-Insecure-Requests", UpgradeInsecureRequests, "upgrade-insecure-requests"),
310 ("User-Agent", UserAgent, "user-agent"),
311 ("Vary", Vary, "vary"),
312 ("Via", Via, "via"),
313 ("Viewport-Width", ViewportWidth, "viewport-width"),
314 ("WWW-Authenticate", WwwAuthenticate, "www-authenticate"),
315 ("Want-Content-Digest", WantContentDigest, "want-content-digest"),
316 ("Want-Digest", WantDigest, "want-digest"),
317 ("Want-Repr-Digest", WantReprDigest, "want-repr-digest"),
318 ("Warning", Warning, "warning"),
319 ("Width", Width, "width"),
320 ("X-B3-Traceid", Xb3Traceid, "x-b3-traceid"),
321 ("X-Cache", Xcache, "x-cache"),
322 ("X-Content-Type-Options", XcontentTypeOptions, "x-content-type-options"),
323 ("X-Correlation-ID", XcorrelationId, "x-correlation-id"),
324 ("X-DNS-Prefetch-Control", XdnsPrefetchControl, "x-dns-prefetch-control"),
325 ("X-Download-Options", XdownloadOptions, "x-download-options"),
326 ("X-Firefox-Spdy", XfirefoxSpdy, "x-firefox-spdy"),
327 ("X-Forwarded-By", XforwardedBy, "x-forwarded-by"),
328 ("X-Forwarded-For", XforwardedFor, "x-forwarded-for"),
329 ("X-Forwarded-Host", XforwardedHost, "x-forwarded-host"),
330 ("X-Forwarded-Proto", XforwardedProto, "x-forwarded-proto"),
331 ("X-Forwarded-SSL", XforwardedSsl, "x-forwarded-ssl"),
332 ("X-Frame-Options", XframeOptions, "x-frame-options"),
333 ("X-Permitted-Cross-Domain-Policies", XpermittedCrossDomainPolicies, "x-permitted-cross-domain-policies"),
334 ("X-Pingback", Xpingback, "x-pingback"),
335 ("X-Powered-By", XpoweredBy, "x-powered-by"),
336 ("X-Real-IP", XrealIp, "x-real-ip"),
337 ("X-Request-Id", XrequestId, "x-request-id"),
338 ("X-Requested-With", XrequestedWith, "x-requested-with"),
339 ("X-Robots-Tag", XrobotsTag, "x-robots-tag"),
340 ("X-Runtime", Xruntime, "x-runtime"),
341 ("X-Served-By", XservedBy, "x-served-by"),
342 ("X-UA-Compatible", XuaCompatible, "x-ua-compatible"),
343 ("X-XSS-Protection", XxssProtection, "x-xss-protection")
344}