1use crate::error::{Error, Result};
2use crate::util::AsciiLowercaseTestExt;
3use std::convert::{TryFrom, TryInto};
4use std::fmt::{Display, Formatter};
5
6mod minimal {
7 #[cfg(feature = "_minimal")]
8 use crate::error::{Error, Result};
9 #[cfg(feature = "_minimal")]
10 use crate::hash::hash;
11
12 pub const CONTENT_LENGTH: &[u8] = b"content-length";
13 pub const HOST: &[u8] = b"host";
14 pub const TRANSFER_ENCODING: &[u8] = b"transfer-encoding";
15 pub const IF_MATCH: &[u8] = b"if-match";
16 pub const IF_NONE_MATCH: &[u8] = b"if-none-match";
17 pub const X_HUB_SIGNATURE_256: &[u8] = b"x-hub-signature-256";
18
19 pub const CONTENT_LENGTH_HASH: u32 = 314322716;
20 pub const HOST_HASH: u32 = 3475444733;
21 pub const TRANSFER_ENCODING_HASH: u32 = 1470906230;
22 pub const IF_MATCH_HASH: u32 = 1168849366;
23 pub const IF_NONE_MATCH_HASH: u32 = 1529156225;
24 pub const X_HUB_SIGNATURE_256_HASH: u32 = 1932839174;
25
26 #[cfg(feature = "_minimal")]
27 #[derive(Default)]
28 pub struct KnownHeaders<'a> {
29 pub content_length: Option<&'a [u8]>,
30 pub host: Option<&'a [u8]>,
31 pub transfer_encoding: Option<&'a [u8]>,
32 pub if_match: Option<&'a [u8]>,
33 pub if_none_match: Option<&'a [u8]>,
34 pub x_hub_signature_256_hash: Option<&'a [u8]>,
35 }
36
37 #[cfg(feature = "_minimal")]
38 #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
39 pub enum HeaderName {
40 ContentLength,
41 Host,
42 TransferEncoding,
43 IfMatch,
44 IfNoneMatch,
45 XHubSignature256,
46
47 Other(&'static [u8]),
48 Unknown(Vec<u8>),
49 }
50
51 #[cfg(feature = "_minimal")]
52 pub(crate) fn _try_from_lowercase(value: &[u8], lowercase: &[u8]) -> Result<HeaderName> {
53 match hash(lowercase) {
54 CONTENT_LENGTH_HASH if lowercase == CONTENT_LENGTH => Ok(HeaderName::ContentLength),
55 HOST_HASH if lowercase == HOST => Ok(HeaderName::Host),
56 TRANSFER_ENCODING_HASH if lowercase == TRANSFER_ENCODING => {
57 Ok(HeaderName::TransferEncoding)
58 }
59 IF_MATCH_HASH if lowercase == IF_MATCH => Ok(HeaderName::IfMatch),
60 IF_NONE_MATCH_HASH if lowercase == IF_NONE_MATCH => Ok(HeaderName::IfNoneMatch),
61 X_HUB_SIGNATURE_256_HASH if lowercase == X_HUB_SIGNATURE_256 => {
62 Ok(HeaderName::XHubSignature256)
63 }
64 _ => Err(Error::UnknownHeaderName(value.escape_ascii().to_string())),
65 }
66 }
67
68 #[cfg(feature = "_minimal")]
69 impl TryFrom<&HeaderName> for &'static [u8] {
70 type Error = Error;
71
72 fn try_from(value: &HeaderName) -> Result<Self> {
73 match value {
74 HeaderName::ContentLength => Ok(CONTENT_LENGTH),
75 HeaderName::Host => Ok(HOST),
76 HeaderName::TransferEncoding => Ok(TRANSFER_ENCODING),
77 HeaderName::IfMatch => Ok(IF_MATCH),
78 HeaderName::IfNoneMatch => Ok(IF_NONE_MATCH),
79 HeaderName::XHubSignature256 => Ok(X_HUB_SIGNATURE_256),
80 HeaderName::Other(value) => Ok(value),
81 HeaderName::Unknown(value) => {
82 Err(Error::UnknownHeaderName(value.escape_ascii().to_string()))
83 }
84 }
85 }
86 }
87}
88
89#[cfg(not(feature = "_minimal"))]
90mod others {
91 use super::minimal::*;
92 use crate::error::{Error, Result};
93 use crate::hash::hash;
94 use crate::request::{
95 CONTENT_LENGTH_HASH, HOST_HASH, IF_MATCH_HASH, IF_NONE_MATCH_HASH, X_HUB_SIGNATURE_256_HASH,
96 };
97
98 pub const ACCEPT: &[u8] = b"accept";
99 pub const ACCEPT_ENCODING: &[u8] = b"accept-encoding";
100 pub const ACCEPT_LANGUAGE: &[u8] = b"accept-language";
101 pub const ACCESS_CONTROL_REQUEST_HEADERS: &[u8] = b"access-control-request-headers";
102 pub const ACCESS_CONTROL_REQUEST_METHOD: &[u8] = b"access-control-request-method";
103 pub const AUTHORIZATION: &[u8] = b"authorization";
104 pub const CONNECTION: &[u8] = b"connection";
105 pub const CONTENT_ENCODING: &[u8] = b"content-encoding";
106 pub const CONTENT_TYPE: &[u8] = b"content-type";
107 pub const COOKIE: &[u8] = b"cookie";
108 pub const EXPECT: &[u8] = b"expect";
109 pub const IF_MODIFIED_SINCE: &[u8] = b"if-modified-since";
110 pub const IF_RANGE: &[u8] = b"if-range";
111 pub const IF_UNMODIFIED_SINCE: &[u8] = b"if-unmodified-since";
112 pub const ORIGIN: &[u8] = b"origin";
113 pub const RANGE: &[u8] = b"range";
114 pub const REFERER: &[u8] = b"referer";
115 pub const SEC_CH_UA: &[u8] = b"sec-ch-ua";
116 pub const SEC_CH_UA_MOBILE: &[u8] = b"sec-ch-ua-mobile";
117 pub const SEC_CH_UA_PLATFORM: &[u8] = b"sec-ch-ua-platform";
118 pub const SEC_FETCH_DEST: &[u8] = b"sec-fetch-dest";
119 pub const SEC_FETCH_MODE: &[u8] = b"sec-fetch-mode";
120 pub const SEC_FETCH_SITE: &[u8] = b"sec-fetch-site";
121 pub const SEC_FETCH_USER: &[u8] = b"sec-fetch-user";
122 pub const USER_AGENT: &[u8] = b"user-agent";
123 pub const X_CSRF_TOKEN: &[u8] = b"x-csrf-token";
124 pub const X_FORWARDED_FOR: &[u8] = b"x-forwarded-for";
125 pub const X_FORWARDED_HOST: &[u8] = b"x-forwarded-host";
126 pub const X_REAL_IP: &[u8] = b"x-real-ip";
127
128 pub const ACCEPT_HASH: u32 = 3005279540;
129 pub const ACCEPT_ENCODING_HASH: u32 = 2687938133;
130 pub const ACCEPT_LANGUAGE_HASH: u32 = 480585391;
131 pub const ACCESS_CONTROL_REQUEST_HEADERS_HASH: u32 = 3862518975;
132 pub const ACCESS_CONTROL_REQUEST_METHOD_HASH: u32 = 1698782395;
133 pub const AUTHORIZATION_HASH: u32 = 2053999599;
134 pub const CONNECTION_HASH: u32 = 704082790;
135 pub const CONTENT_ENCODING_HASH: u32 = 3836410099;
136 pub const CONTENT_TYPE_HASH: u32 = 3266185539;
137 pub const COOKIE_HASH: u32 = 2329983590;
138 pub const EXPECT_HASH: u32 = 482521170;
139 pub const IF_MODIFIED_SINCE_HASH: u32 = 1848278858;
140 pub const IF_RANGE_HASH: u32 = 2893522586;
141 pub const IF_UNMODIFIED_SINCE_HASH: u32 = 462614015;
142 pub const ORIGIN_HASH: u32 = 3740358174;
143 pub const RANGE_HASH: u32 = 2475121225;
144 pub const REFERER_HASH: u32 = 1440495237;
145 pub const SEC_CH_UA_HASH: u32 = 3458784846;
146 pub const SEC_CH_UA_MOBILE_HASH: u32 = 3851717610;
147 pub const SEC_CH_UA_PLATFORM_HASH: u32 = 464571004;
148 pub const SEC_FETCH_DEST_HASH: u32 = 1781535743;
149 pub const SEC_FETCH_MODE_HASH: u32 = 1973190087;
150 pub const SEC_FETCH_SITE_HASH: u32 = 2333422472;
151 pub const SEC_FETCH_USER_HASH: u32 = 1875242021;
152 pub const USER_AGENT_HASH: u32 = 2191772431;
153 pub const X_CSRF_TOKEN_HASH: u32 = 3276872746;
154 pub const X_FORWARDED_FOR_HASH: u32 = 2397052407;
155 pub const X_FORWARDED_HOST_HASH: u32 = 1610193784;
156 pub const X_REAL_IP_HASH: u32 = 3988930344;
157
158 #[derive(Default)]
159 pub struct KnownHeaders<'a> {
160 pub accept: Option<&'a [u8]>,
161 pub accept_encoding: Option<&'a [u8]>,
162 pub accept_language: Option<&'a [u8]>,
163 pub access_control_request_headers: Option<&'a [u8]>,
164 pub access_control_request_method: Option<&'a [u8]>,
165 pub authorization: Option<&'a [u8]>,
166 pub connection: Option<&'a [u8]>,
167 pub content_encoding: Option<&'a [u8]>,
168 pub content_length: Option<&'a [u8]>,
169 pub content_type: Option<&'a [u8]>,
170 pub cookie: Option<&'a [u8]>,
171 pub expect: Option<&'a [u8]>,
172 pub host: Option<&'a [u8]>,
173 pub if_match: Option<&'a [u8]>,
174 pub if_modified_since: Option<&'a [u8]>,
175 pub if_none_match: Option<&'a [u8]>,
176 pub if_range: Option<&'a [u8]>,
177 pub if_unmodified_since: Option<&'a [u8]>,
178 pub origin: Option<&'a [u8]>,
179 pub range: Option<&'a [u8]>,
180 pub referer: Option<&'a [u8]>,
181 pub sec_ch_ua: Option<&'a [u8]>,
182 pub sec_ch_ua_mobile: Option<&'a [u8]>,
183 pub sec_ch_ua_platform: Option<&'a [u8]>,
184 pub sec_fetch_dest: Option<&'a [u8]>,
185 pub sec_fetch_mode: Option<&'a [u8]>,
186 pub sec_fetch_site: Option<&'a [u8]>,
187 pub sec_fetch_user: Option<&'a [u8]>,
188 pub transfer_encoding: Option<&'a [u8]>,
189 pub user_agent: Option<&'a [u8]>,
190 pub x_csrf_token: Option<&'a [u8]>,
191 pub x_forwarded_for: Option<&'a [u8]>,
192 pub x_forwarded_host: Option<&'a [u8]>,
193 pub x_real_ip: Option<&'a [u8]>,
194 pub x_hub_signature_256_hash: Option<&'a [u8]>,
195 }
196
197 #[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
198 pub enum HeaderName {
199 Accept,
200 AcceptEncoding,
201 AcceptLanguage,
202 AccessControlRequestHeaders,
203 AccessControlRequestMethod,
204 Authorization,
205 Connection,
206 ContentEncoding,
207 ContentLength,
208 ContentType,
209 Cookie,
210 Expect,
211 Host,
212 IfMatch,
213 IfModifiedSince,
214 IfNoneMatch,
215 IfRange,
216 IfUnmodifiedSince,
217 Origin,
218 Range,
219 Referer,
220 SecChUa,
221 SecChUaMobile,
222 SecChUaPlatform,
223 SecFetchDest,
224 SecFetchMode,
225 SecFetchSite,
226 SecFetchUser,
227 TransferEncoding,
228 UserAgent,
229 XCSRFToken,
230 XForwardedFor,
231 XForwardedHost,
232 XRealIp,
233 XHubSignature256,
234
235 Other(&'static [u8]),
236 Unknown(Vec<u8>),
237 }
238
239 pub(crate) fn _try_from_lowercase(value: &[u8], lowercase: &[u8]) -> Result<HeaderName> {
240 match hash(lowercase) {
241 ACCEPT_HASH if lowercase == ACCEPT => Ok(HeaderName::Accept),
242 ACCEPT_ENCODING_HASH if lowercase == ACCEPT_ENCODING => Ok(HeaderName::AcceptEncoding),
243 ACCEPT_LANGUAGE_HASH if lowercase == ACCEPT_LANGUAGE => Ok(HeaderName::AcceptLanguage),
244 ACCESS_CONTROL_REQUEST_HEADERS_HASH if lowercase == ACCESS_CONTROL_REQUEST_HEADERS => {
245 Ok(HeaderName::AccessControlRequestHeaders)
246 }
247 ACCESS_CONTROL_REQUEST_METHOD_HASH if lowercase == ACCESS_CONTROL_REQUEST_METHOD => {
248 Ok(HeaderName::AccessControlRequestMethod)
249 }
250 AUTHORIZATION_HASH if lowercase == AUTHORIZATION => Ok(HeaderName::Authorization),
251 CONNECTION_HASH if lowercase == CONNECTION => Ok(HeaderName::Connection),
252 CONTENT_ENCODING_HASH if lowercase == CONTENT_ENCODING => {
253 Ok(HeaderName::ContentEncoding)
254 }
255 CONTENT_LENGTH_HASH if lowercase == CONTENT_LENGTH => Ok(HeaderName::ContentLength),
256 CONTENT_TYPE_HASH if lowercase == CONTENT_TYPE => Ok(HeaderName::ContentType),
257 COOKIE_HASH if lowercase == COOKIE => Ok(HeaderName::Cookie),
258 EXPECT_HASH if lowercase == EXPECT => Ok(HeaderName::Expect),
259 HOST_HASH if lowercase == HOST => Ok(HeaderName::Host),
260 IF_MATCH_HASH if lowercase == IF_MATCH => Ok(HeaderName::IfMatch),
261 IF_MODIFIED_SINCE_HASH if lowercase == IF_MODIFIED_SINCE => {
262 Ok(HeaderName::IfModifiedSince)
263 }
264 IF_NONE_MATCH_HASH if lowercase == IF_NONE_MATCH => Ok(HeaderName::IfNoneMatch),
265 IF_RANGE_HASH if lowercase == IF_RANGE => Ok(HeaderName::IfRange),
266 IF_UNMODIFIED_SINCE_HASH if lowercase == IF_UNMODIFIED_SINCE => {
267 Ok(HeaderName::IfUnmodifiedSince)
268 }
269 ORIGIN_HASH if lowercase == ORIGIN => Ok(HeaderName::Origin),
270 RANGE_HASH if lowercase == RANGE => Ok(HeaderName::Range),
271 REFERER_HASH if lowercase == REFERER => Ok(HeaderName::Referer),
272 SEC_CH_UA_HASH if lowercase == SEC_CH_UA => Ok(HeaderName::SecChUa),
273 SEC_CH_UA_MOBILE_HASH if lowercase == SEC_CH_UA_MOBILE => Ok(HeaderName::SecChUaMobile),
274 SEC_CH_UA_PLATFORM_HASH if lowercase == SEC_CH_UA_PLATFORM => {
275 Ok(HeaderName::SecChUaPlatform)
276 }
277 SEC_FETCH_DEST_HASH if lowercase == SEC_FETCH_DEST => Ok(HeaderName::SecFetchDest),
278 SEC_FETCH_MODE_HASH if lowercase == SEC_FETCH_MODE => Ok(HeaderName::SecFetchMode),
279 SEC_FETCH_SITE_HASH if lowercase == SEC_FETCH_SITE => Ok(HeaderName::SecFetchSite),
280 SEC_FETCH_USER_HASH if lowercase == SEC_FETCH_USER => Ok(HeaderName::SecFetchUser),
281 TRANSFER_ENCODING_HASH if lowercase == TRANSFER_ENCODING => {
282 Ok(HeaderName::TransferEncoding)
283 }
284 USER_AGENT_HASH if lowercase == USER_AGENT => Ok(HeaderName::UserAgent),
285 X_CSRF_TOKEN_HASH if lowercase == X_CSRF_TOKEN => Ok(HeaderName::XCSRFToken),
286 X_FORWARDED_FOR_HASH if lowercase == X_FORWARDED_FOR => Ok(HeaderName::XForwardedFor),
287 X_FORWARDED_HOST_HASH if lowercase == X_FORWARDED_HOST => {
288 Ok(HeaderName::XForwardedHost)
289 }
290 X_HUB_SIGNATURE_256_HASH if lowercase == X_HUB_SIGNATURE_256 => {
291 Ok(HeaderName::XHubSignature256)
292 }
293 X_REAL_IP_HASH if lowercase == X_REAL_IP => Ok(HeaderName::XRealIp),
294 _ => Err(Error::UnknownHeaderName(value.escape_ascii().to_string())),
295 }
296 }
297
298 impl TryFrom<&HeaderName> for &'static [u8] {
299 type Error = Error;
300
301 fn try_from(value: &HeaderName) -> Result<Self> {
302 match value {
303 HeaderName::Accept => Ok(ACCEPT),
304 HeaderName::AcceptEncoding => Ok(ACCEPT_ENCODING),
305 HeaderName::AcceptLanguage => Ok(ACCEPT_LANGUAGE),
306 HeaderName::AccessControlRequestHeaders => Ok(ACCESS_CONTROL_REQUEST_HEADERS),
307 HeaderName::AccessControlRequestMethod => Ok(ACCESS_CONTROL_REQUEST_METHOD),
308 HeaderName::Authorization => Ok(AUTHORIZATION),
309 HeaderName::Connection => Ok(CONNECTION),
310 HeaderName::ContentEncoding => Ok(CONTENT_ENCODING),
311 HeaderName::ContentLength => Ok(CONTENT_LENGTH),
312 HeaderName::ContentType => Ok(CONTENT_TYPE),
313 HeaderName::Cookie => Ok(COOKIE),
314 HeaderName::Expect => Ok(EXPECT),
315 HeaderName::Host => Ok(HOST),
316 HeaderName::IfMatch => Ok(IF_MATCH),
317 HeaderName::IfModifiedSince => Ok(IF_MODIFIED_SINCE),
318 HeaderName::IfNoneMatch => Ok(IF_NONE_MATCH),
319 HeaderName::IfRange => Ok(IF_RANGE),
320 HeaderName::IfUnmodifiedSince => Ok(IF_UNMODIFIED_SINCE),
321 HeaderName::Origin => Ok(ORIGIN),
322 HeaderName::Range => Ok(RANGE),
323 HeaderName::Referer => Ok(REFERER),
324 HeaderName::SecChUa => Ok(SEC_CH_UA),
325 HeaderName::SecChUaMobile => Ok(SEC_CH_UA_MOBILE),
326 HeaderName::SecChUaPlatform => Ok(SEC_CH_UA_PLATFORM),
327 HeaderName::SecFetchDest => Ok(SEC_FETCH_DEST),
328 HeaderName::SecFetchMode => Ok(SEC_FETCH_MODE),
329 HeaderName::SecFetchSite => Ok(SEC_FETCH_SITE),
330 HeaderName::SecFetchUser => Ok(SEC_FETCH_USER),
331 HeaderName::TransferEncoding => Ok(TRANSFER_ENCODING),
332 HeaderName::UserAgent => Ok(USER_AGENT),
333 HeaderName::XCSRFToken => Ok(X_CSRF_TOKEN),
334 HeaderName::XForwardedFor => Ok(X_FORWARDED_FOR),
335 HeaderName::XForwardedHost => Ok(X_FORWARDED_HOST),
336 HeaderName::XRealIp => Ok(X_REAL_IP),
337 HeaderName::XHubSignature256 => Ok(X_HUB_SIGNATURE_256),
338 HeaderName::Other(value) => Ok(value),
339 HeaderName::Unknown(value) => {
340 Err(Error::UnknownHeaderName(value.escape_ascii().to_string()))
341 }
342 }
343 }
344 }
345}
346
347pub use minimal::*;
348#[cfg(not(feature = "_minimal"))]
349pub use others::*;
350
351impl HeaderName {
352 pub fn as_slice(&self) -> &[u8] {
353 match self {
354 HeaderName::Unknown(vec) => vec.as_slice(),
355 _ => self.try_into().unwrap(),
356 }
357 }
358 pub fn try_from_static(value: &'static [u8]) -> Result<Self> {
359 value.try_into().or_else(|_| {
360 if value.is_ascii_lowercase() {
361 Ok(HeaderName::Other(value))
362 } else {
363 Err(Error::CustomHeaderNameNotLowercase(
364 String::from_utf8_lossy(value).to_string(),
365 ))
366 }
367 })
368 }
369 pub fn owned(value: &[u8]) -> Result<Self> {
370 match value.try_into() {
371 Err(_) => {
372 let lowercase = value.to_ascii_lowercase();
373 if lowercase.is_ascii_lowercase() {
374 Ok(HeaderName::Unknown(value.to_ascii_lowercase()))
375 } else {
376 Err(Error::InvalidHeaderName(value.escape_ascii().to_string()))
377 }
378 }
379 it => it,
380 }
381 }
382}
383
384impl Display for HeaderName {
385 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
386 write!(f, "{}", self.as_slice().escape_ascii())
387 }
388}
389
390impl<'a, const N: usize> TryFrom<&'a [u8; N]> for HeaderName {
391 type Error = Error;
392
393 fn try_from(value: &'a [u8; N]) -> Result<Self> {
394 value.as_slice().try_into()
395 }
396}
397
398impl<'a> TryFrom<&'a [u8]> for HeaderName {
399 type Error = Error;
400
401 fn try_from(value: &'a [u8]) -> Result<Self> {
402 if value.is_ascii_lowercase() {
403 _try_from_lowercase(value, value)
404 } else {
405 _try_from_lowercase(value, value.to_ascii_lowercase().as_slice())
406 }
407 }
408}
409
410impl AsRef<[u8]> for HeaderName {
411 fn as_ref(&self) -> &[u8] {
412 self.as_slice()
413 }
414}
415
416impl TryFrom<&str> for HeaderName {
417 type Error = Error;
418
419 fn try_from(value: &str) -> Result<Self> {
420 let value = value.as_bytes();
421 if value.is_ascii_lowercase() {
422 value.try_into()
423 } else {
424 value.to_ascii_lowercase().as_slice().try_into()
425 }
426 }
427}
428
429#[cfg(test)]
430#[cfg(not(feature = "_minimal"))]
431mod test {
432 use super::*;
433
434 #[test]
435 fn from_bytes() {
436 assert_eq!(ACCEPT.try_into(), Ok(HeaderName::Accept));
437 assert_eq!(ACCEPT_ENCODING.try_into(), Ok(HeaderName::AcceptEncoding));
438 assert_eq!(ACCEPT_LANGUAGE.try_into(), Ok(HeaderName::AcceptLanguage));
439 assert_eq!(
440 ACCESS_CONTROL_REQUEST_HEADERS.try_into(),
441 Ok(HeaderName::AccessControlRequestHeaders)
442 );
443 assert_eq!(
444 ACCESS_CONTROL_REQUEST_METHOD.try_into(),
445 Ok(HeaderName::AccessControlRequestMethod)
446 );
447 assert_eq!(AUTHORIZATION.try_into(), Ok(HeaderName::Authorization));
448 assert_eq!(CONNECTION.try_into(), Ok(HeaderName::Connection));
449 assert_eq!(CONTENT_ENCODING.try_into(), Ok(HeaderName::ContentEncoding));
450 assert_eq!(CONTENT_LENGTH.try_into(), Ok(HeaderName::ContentLength));
451 assert_eq!(CONTENT_TYPE.try_into(), Ok(HeaderName::ContentType));
452 assert_eq!(COOKIE.try_into(), Ok(HeaderName::Cookie));
453 assert_eq!(EXPECT.try_into(), Ok(HeaderName::Expect));
454 assert_eq!(HOST.try_into(), Ok(HeaderName::Host));
455 assert_eq!(IF_MATCH.try_into(), Ok(HeaderName::IfMatch));
456 assert_eq!(
457 IF_MODIFIED_SINCE.try_into(),
458 Ok(HeaderName::IfModifiedSince)
459 );
460 assert_eq!(IF_NONE_MATCH.try_into(), Ok(HeaderName::IfNoneMatch));
461 assert_eq!(IF_RANGE.try_into(), Ok(HeaderName::IfRange));
462 assert_eq!(
463 IF_UNMODIFIED_SINCE.try_into(),
464 Ok(HeaderName::IfUnmodifiedSince)
465 );
466 assert_eq!(ORIGIN.try_into(), Ok(HeaderName::Origin));
467 assert_eq!(RANGE.try_into(), Ok(HeaderName::Range));
468 assert_eq!(REFERER.try_into(), Ok(HeaderName::Referer));
469 assert_eq!(SEC_CH_UA.try_into(), Ok(HeaderName::SecChUa));
470 assert_eq!(SEC_CH_UA_MOBILE.try_into(), Ok(HeaderName::SecChUaMobile));
471 assert_eq!(
472 SEC_CH_UA_PLATFORM.try_into(),
473 Ok(HeaderName::SecChUaPlatform)
474 );
475 assert_eq!(SEC_FETCH_DEST.try_into(), Ok(HeaderName::SecFetchDest));
476 assert_eq!(SEC_FETCH_MODE.try_into(), Ok(HeaderName::SecFetchMode));
477 assert_eq!(SEC_FETCH_SITE.try_into(), Ok(HeaderName::SecFetchSite));
478 assert_eq!(SEC_FETCH_USER.try_into(), Ok(HeaderName::SecFetchUser));
479 assert_eq!(
480 TRANSFER_ENCODING.try_into(),
481 Ok(HeaderName::TransferEncoding)
482 );
483 assert_eq!(USER_AGENT.try_into(), Ok(HeaderName::UserAgent));
484 assert_eq!(X_CSRF_TOKEN.try_into(), Ok(HeaderName::XCSRFToken));
485 assert_eq!(X_FORWARDED_FOR.try_into(), Ok(HeaderName::XForwardedFor));
486 assert_eq!(X_FORWARDED_HOST.try_into(), Ok(HeaderName::XForwardedHost));
487 assert_eq!(X_REAL_IP.try_into(), Ok(HeaderName::XRealIp));
488 assert_eq!(
489 X_HUB_SIGNATURE_256.try_into(),
490 Ok(HeaderName::XHubSignature256)
491 );
492 let unknown: Result<HeaderName> = b"UNKNOWN".try_into();
493 assert!(unknown.is_err());
494 let unknown: Result<HeaderName> = HeaderName::try_from_static(b"Unknown");
495 assert!(unknown.is_err());
496 assert_eq!(HeaderName::try_from_static(b"Host"), Ok(HeaderName::Host));
497 assert_eq!(
498 HeaderName::try_from_static(b"origin"),
499 Ok(HeaderName::Origin)
500 );
501 assert_eq!(
502 HeaderName::try_from_static(b"unknown"),
503 Ok(HeaderName::Other(b"unknown"))
504 );
505 assert_eq!(
506 HeaderName::owned(b"HOST").unwrap().try_into(),
507 Ok(HeaderName::Host)
508 );
509 assert_eq!(
510 HeaderName::owned(b"accept").unwrap().try_into(),
511 Ok(HeaderName::Accept)
512 );
513 assert_eq!(
514 HeaderName::owned(b"Unknown").unwrap().try_into(),
515 Ok(HeaderName::Unknown(b"unknown".to_vec()))
516 );
517 assert_eq!(
518 HeaderName::owned(b"unknown").unwrap().try_into(),
519 Ok(HeaderName::Unknown(b"unknown".to_vec()))
520 );
521 }
522
523 #[test]
524 fn from_str() {
525 assert_eq!("Accept".try_into(), Ok(HeaderName::Accept));
526 assert_eq!("accept".try_into(), Ok(HeaderName::Accept));
527 assert_eq!("ACCEPT".try_into(), Ok(HeaderName::Accept));
528 assert_eq!("Accept-Encoding".try_into(), Ok(HeaderName::AcceptEncoding));
529 assert_eq!("accept-encoding".try_into(), Ok(HeaderName::AcceptEncoding));
530 assert_eq!("ACCEPT-ENCODING".try_into(), Ok(HeaderName::AcceptEncoding));
531 assert_eq!("Accept-Language".try_into(), Ok(HeaderName::AcceptLanguage));
532 assert_eq!("accept-language".try_into(), Ok(HeaderName::AcceptLanguage));
533 assert_eq!("ACCEPT-LANGUAGE".try_into(), Ok(HeaderName::AcceptLanguage));
534 assert_eq!(
535 "Access-Control-Request-Headers".try_into(),
536 Ok(HeaderName::AccessControlRequestHeaders)
537 );
538 assert_eq!(
539 "access-control-request-headers".try_into(),
540 Ok(HeaderName::AccessControlRequestHeaders)
541 );
542 assert_eq!(
543 "ACCESS-CONTROL-REQUEST-HEADERS".try_into(),
544 Ok(HeaderName::AccessControlRequestHeaders)
545 );
546 assert_eq!(
547 "Access-Control-Request-Method".try_into(),
548 Ok(HeaderName::AccessControlRequestMethod)
549 );
550 assert_eq!(
551 "access-control-request-method".try_into(),
552 Ok(HeaderName::AccessControlRequestMethod)
553 );
554 assert_eq!(
555 "ACCESS-CONTROL-REQUEST-METHOD".try_into(),
556 Ok(HeaderName::AccessControlRequestMethod)
557 );
558 assert_eq!("Authorization".try_into(), Ok(HeaderName::Authorization));
559 assert_eq!("authorization".try_into(), Ok(HeaderName::Authorization));
560 assert_eq!("AUTHORIZATION".try_into(), Ok(HeaderName::Authorization));
561 assert_eq!("Connection".try_into(), Ok(HeaderName::Connection));
562 assert_eq!("connection".try_into(), Ok(HeaderName::Connection));
563 assert_eq!("CONNECTION".try_into(), Ok(HeaderName::Connection));
564 assert_eq!(
565 "Content-Encoding".try_into(),
566 Ok(HeaderName::ContentEncoding)
567 );
568 assert_eq!(
569 "content-encoding".try_into(),
570 Ok(HeaderName::ContentEncoding)
571 );
572 assert_eq!(
573 "CONTENT-ENCODING".try_into(),
574 Ok(HeaderName::ContentEncoding)
575 );
576 assert_eq!("Content-Length".try_into(), Ok(HeaderName::ContentLength));
577 assert_eq!("content-length".try_into(), Ok(HeaderName::ContentLength));
578 assert_eq!("CONTENT-LENGTH".try_into(), Ok(HeaderName::ContentLength));
579 assert_eq!("Content-Type".try_into(), Ok(HeaderName::ContentType));
580 assert_eq!("content-type".try_into(), Ok(HeaderName::ContentType));
581 assert_eq!("CONTENT-TYPE".try_into(), Ok(HeaderName::ContentType));
582 assert_eq!("Cookie".try_into(), Ok(HeaderName::Cookie));
583 assert_eq!("cookie".try_into(), Ok(HeaderName::Cookie));
584 assert_eq!("COOKIE".try_into(), Ok(HeaderName::Cookie));
585 assert_eq!("Expect".try_into(), Ok(HeaderName::Expect));
586 assert_eq!("expect".try_into(), Ok(HeaderName::Expect));
587 assert_eq!("EXPECT".try_into(), Ok(HeaderName::Expect));
588 assert_eq!("Host".try_into(), Ok(HeaderName::Host));
589 assert_eq!("host".try_into(), Ok(HeaderName::Host));
590 assert_eq!("HOST".try_into(), Ok(HeaderName::Host));
591 assert_eq!("If-Match".try_into(), Ok(HeaderName::IfMatch));
592 assert_eq!("if-match".try_into(), Ok(HeaderName::IfMatch));
593 assert_eq!("IF-MATCH".try_into(), Ok(HeaderName::IfMatch));
594 assert_eq!(
595 "If-Modified-Since".try_into(),
596 Ok(HeaderName::IfModifiedSince)
597 );
598 assert_eq!(
599 "if-modified-since".try_into(),
600 Ok(HeaderName::IfModifiedSince)
601 );
602 assert_eq!(
603 "IF-MODIFIED-SINCE".try_into(),
604 Ok(HeaderName::IfModifiedSince)
605 );
606 assert_eq!("If-None-Match".try_into(), Ok(HeaderName::IfNoneMatch));
607 assert_eq!("if-none-match".try_into(), Ok(HeaderName::IfNoneMatch));
608 assert_eq!("IF-NONE-MATCH".try_into(), Ok(HeaderName::IfNoneMatch));
609 assert_eq!("If-Range".try_into(), Ok(HeaderName::IfRange));
610 assert_eq!("if-range".try_into(), Ok(HeaderName::IfRange));
611 assert_eq!("IF-RANGE".try_into(), Ok(HeaderName::IfRange));
612 assert_eq!(
613 "If-Unmodified-Since".try_into(),
614 Ok(HeaderName::IfUnmodifiedSince)
615 );
616 assert_eq!(
617 "if-unmodified-since".try_into(),
618 Ok(HeaderName::IfUnmodifiedSince)
619 );
620 assert_eq!(
621 "IF-UNMODIFIED-SINCE".try_into(),
622 Ok(HeaderName::IfUnmodifiedSince)
623 );
624 assert_eq!("Origin".try_into(), Ok(HeaderName::Origin));
625 assert_eq!("origin".try_into(), Ok(HeaderName::Origin));
626 assert_eq!("ORIGIN".try_into(), Ok(HeaderName::Origin));
627 assert_eq!("Range".try_into(), Ok(HeaderName::Range));
628 assert_eq!("range".try_into(), Ok(HeaderName::Range));
629 assert_eq!("RANGE".try_into(), Ok(HeaderName::Range));
630 assert_eq!("Referer".try_into(), Ok(HeaderName::Referer));
631 assert_eq!("referer".try_into(), Ok(HeaderName::Referer));
632 assert_eq!("REFERER".try_into(), Ok(HeaderName::Referer));
633 assert_eq!("Sec-Ch-Ua".try_into(), Ok(HeaderName::SecChUa));
634 assert_eq!("sec-ch-ua".try_into(), Ok(HeaderName::SecChUa));
635 assert_eq!("SEC-CH-UA".try_into(), Ok(HeaderName::SecChUa));
636 assert_eq!("Sec-Ch-Ua-Mobile".try_into(), Ok(HeaderName::SecChUaMobile));
637 assert_eq!("sec-ch-ua-mobile".try_into(), Ok(HeaderName::SecChUaMobile));
638 assert_eq!("SEC-CH-UA-MOBILE".try_into(), Ok(HeaderName::SecChUaMobile));
639 assert_eq!(
640 "Sec-Ch-Ua-Platform".try_into(),
641 Ok(HeaderName::SecChUaPlatform)
642 );
643 assert_eq!(
644 "sec-ch-ua-platform".try_into(),
645 Ok(HeaderName::SecChUaPlatform)
646 );
647 assert_eq!(
648 "SEC-CH-UA-PLATFORM".try_into(),
649 Ok(HeaderName::SecChUaPlatform)
650 );
651 assert_eq!("sec-fetch-dest".try_into(), Ok(HeaderName::SecFetchDest));
652 assert_eq!("Sec-Fetch-Dest".try_into(), Ok(HeaderName::SecFetchDest));
653 assert_eq!("SEC-FETCH-DEST".try_into(), Ok(HeaderName::SecFetchDest));
654 assert_eq!("sec-fetch-mode".try_into(), Ok(HeaderName::SecFetchMode));
655 assert_eq!("Sec-Fetch-Mode".try_into(), Ok(HeaderName::SecFetchMode));
656 assert_eq!("SEC-FETCH-MODE".try_into(), Ok(HeaderName::SecFetchMode));
657 assert_eq!("sec-fetch-site".try_into(), Ok(HeaderName::SecFetchSite));
658 assert_eq!("Sec-Fetch-Site".try_into(), Ok(HeaderName::SecFetchSite));
659 assert_eq!("SEC-FETCH-SITE".try_into(), Ok(HeaderName::SecFetchSite));
660 assert_eq!("sec-fetch-user".try_into(), Ok(HeaderName::SecFetchUser));
661 assert_eq!("Sec-Fetch-User".try_into(), Ok(HeaderName::SecFetchUser));
662 assert_eq!("SEC-FETCH-USER".try_into(), Ok(HeaderName::SecFetchUser));
663 assert_eq!(
664 "Transfer-Encoding".try_into(),
665 Ok(HeaderName::TransferEncoding)
666 );
667 assert_eq!(
668 "transfer-encoding".try_into(),
669 Ok(HeaderName::TransferEncoding)
670 );
671 assert_eq!(
672 "TRANSFER-ENCODING".try_into(),
673 Ok(HeaderName::TransferEncoding)
674 );
675 assert_eq!("User-Agent".try_into(), Ok(HeaderName::UserAgent));
676 assert_eq!("user-agent".try_into(), Ok(HeaderName::UserAgent));
677 assert_eq!("USER-AGENT".try_into(), Ok(HeaderName::UserAgent));
678 assert_eq!("X-CSRF-Token".try_into(), Ok(HeaderName::XCSRFToken));
679 assert_eq!("x-csrf-token".try_into(), Ok(HeaderName::XCSRFToken));
680 assert_eq!("X-CSRF-TOKEN".try_into(), Ok(HeaderName::XCSRFToken));
681 assert_eq!("X-Forwarded-For".try_into(), Ok(HeaderName::XForwardedFor));
682 assert_eq!("x-forwarded-for".try_into(), Ok(HeaderName::XForwardedFor));
683 assert_eq!("X-FORWARDED-FOR".try_into(), Ok(HeaderName::XForwardedFor));
684 assert_eq!(
685 "X-Forwarded-Host".try_into(),
686 Ok(HeaderName::XForwardedHost)
687 );
688 assert_eq!(
689 "x-forwarded-host".try_into(),
690 Ok(HeaderName::XForwardedHost)
691 );
692 assert_eq!(
693 "X-FORWARDED-HOST".try_into(),
694 Ok(HeaderName::XForwardedHost)
695 );
696 assert_eq!("X-Real-Ip".try_into(), Ok(HeaderName::XRealIp));
697 assert_eq!("x-real-ip".try_into(), Ok(HeaderName::XRealIp));
698 assert_eq!("X-REAL-IP".try_into(), Ok(HeaderName::XRealIp));
699 assert_eq!(
700 "X-Hub-Signature-256".try_into(),
701 Ok(HeaderName::XHubSignature256)
702 );
703 assert_eq!(
704 "x-hub-signature-256".try_into(),
705 Ok(HeaderName::XHubSignature256)
706 );
707 assert_eq!(
708 "X-HUB-SIGNATURE-256".try_into(),
709 Ok(HeaderName::XHubSignature256)
710 );
711 let unknown: Result<HeaderName> = "UNKNOWN".try_into();
712 assert!(unknown.is_err());
713 }
714
715 #[test]
716 fn as_ref() {
717 assert_eq!(HeaderName::Accept.as_ref(), ACCEPT);
718 assert_eq!(HeaderName::AcceptEncoding.as_ref(), ACCEPT_ENCODING);
719 assert_eq!(HeaderName::AcceptLanguage.as_ref(), ACCEPT_LANGUAGE);
720 assert_eq!(
721 HeaderName::AccessControlRequestHeaders.as_ref(),
722 ACCESS_CONTROL_REQUEST_HEADERS
723 );
724 assert_eq!(
725 HeaderName::AccessControlRequestMethod.as_ref(),
726 ACCESS_CONTROL_REQUEST_METHOD
727 );
728 assert_eq!(HeaderName::Authorization.as_ref(), AUTHORIZATION);
729 assert_eq!(HeaderName::Connection.as_ref(), CONNECTION);
730 assert_eq!(HeaderName::ContentEncoding.as_ref(), CONTENT_ENCODING);
731 assert_eq!(HeaderName::ContentLength.as_ref(), CONTENT_LENGTH);
732 assert_eq!(HeaderName::ContentType.as_ref(), CONTENT_TYPE);
733 assert_eq!(HeaderName::Cookie.as_ref(), COOKIE);
734 assert_eq!(HeaderName::Expect.as_ref(), EXPECT);
735 assert_eq!(HeaderName::Host.as_ref(), HOST);
736 assert_eq!(HeaderName::IfMatch.as_ref(), IF_MATCH);
737 assert_eq!(HeaderName::IfModifiedSince.as_ref(), IF_MODIFIED_SINCE);
738 assert_eq!(HeaderName::IfNoneMatch.as_ref(), IF_NONE_MATCH);
739 assert_eq!(HeaderName::IfRange.as_ref(), IF_RANGE);
740 assert_eq!(HeaderName::IfUnmodifiedSince.as_ref(), IF_UNMODIFIED_SINCE);
741 assert_eq!(HeaderName::Origin.as_ref(), ORIGIN);
742 assert_eq!(HeaderName::Range.as_ref(), RANGE);
743 assert_eq!(HeaderName::TransferEncoding.as_ref(), TRANSFER_ENCODING);
744 assert_eq!(HeaderName::UserAgent.as_ref(), USER_AGENT);
745 assert_eq!(HeaderName::XCSRFToken.as_ref(), X_CSRF_TOKEN);
746 assert_eq!(HeaderName::XForwardedFor.as_ref(), X_FORWARDED_FOR);
747 assert_eq!(HeaderName::XForwardedHost.as_ref(), X_FORWARDED_HOST);
748 assert_eq!(HeaderName::XRealIp.as_ref(), X_REAL_IP);
749 assert_eq!(HeaderName::XHubSignature256.as_ref(), X_HUB_SIGNATURE_256);
750 assert_eq!(
751 HeaderName::try_from_static(b"unknown").unwrap().as_ref(),
752 b"unknown"
753 );
754 assert_eq!(
755 &HeaderName::try_from_static(b"unknown").unwrap().as_ref(),
756 b"unknown"
757 );
758 }
759}