1 //! HTTP header types
2 //!
3 //! The module provides [`HeaderName`], [`HeaderMap`], and a number of types
4 //! used for interacting with `HeaderMap`. These types allow representing both
5 //! HTTP/1 and HTTP/2 headers.
6 //!
7 //! # `HeaderName`
8 //!
9 //! The `HeaderName` type represents both standard header names as well as
10 //! custom header names. The type handles the case insensitive nature of header
11 //! names and is used as the key portion of `HeaderMap`. Header names are
12 //! normalized to lower case. In other words, when creating a `HeaderName` with
13 //! a string, even if upper case characters are included, when getting a string
14 //! representation of the `HeaderName`, it will be all lower case. This allows
15 //! for faster `HeaderMap` comparison operations.
16 //!
17 //! The internal representation is optimized to efficiently handle the cases
18 //! most commonly encountered when working with HTTP. Standard header names are
19 //! special cased and are represented internally as an enum. Short custom
20 //! headers will be stored directly in the `HeaderName` struct and will not
21 //! incur any allocation overhead, however longer strings will require an
22 //! allocation for storage.
23 //!
24 //! ## Limitations
25 //!
26 //! `HeaderName` has a max length of 32,768 for header names. Attempting to
27 //! parse longer names will result in a panic.
28 //!
29 //! # `HeaderMap`
30 //!
31 //! `HeaderMap` is a map structure of header names highly optimized for use
32 //! cases common with HTTP. It is a [multimap] structure, where each header name
33 //! may have multiple associated header values. Given this, some of the APIs
34 //! diverge from [`HashMap`].
35 //!
36 //! ## Overview
37 //!
38 //! Just like `HashMap` in Rust's stdlib, `HeaderMap` is based on [Robin Hood
39 //! hashing]. This algorithm tends to reduce the worst case search times in the
40 //! table and enables high load factors without seriously affecting performance.
41 //! Internally, keys and values are stored in vectors. As such, each insertion
42 //! will not incur allocation overhead. However, once the underlying vector
43 //! storage is full, a larger vector must be allocated and all values copied.
44 //!
45 //! ## Deterministic ordering
46 //!
47 //! Unlike Rust's `HashMap`, values in `HeaderMap` are deterministically
48 //! ordered. Roughly, values are ordered by insertion. This means that a
49 //! function that deterministically operates on a header map can rely on the
50 //! iteration order to remain consistent across processes and platforms.
51 //!
52 //! ## Adaptive hashing
53 //!
54 //! `HeaderMap` uses an adaptive hashing strategy in order to efficiently handle
55 //! most common cases. All standard headers have statically computed hash values
56 //! which removes the need to perform any hashing of these headers at runtime.
57 //! The default hash function emphasizes performance over robustness. However,
58 //! `HeaderMap` detects high collision rates and switches to a secure hash
59 //! function in those events. The threshold is set such that only denial of
60 //! service attacks should trigger it.
61 //!
62 //! ## Limitations
63 //!
64 //! `HeaderMap` can store a maximum of 32,768 headers (header name / value
65 //! pairs). Attempting to insert more will result in a panic.
66 //!
67 //! [`HeaderName`]: struct.HeaderName.html
68 //! [`HeaderMap`]: struct.HeaderMap.html
69 //! [multimap]: https://en.wikipedia.org/wiki/Multimap
70 //! [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
71 //! [Robin Hood hashing]: https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing
72 
73 mod map;
74 mod name;
75 mod value;
76 
77 pub use self::map::{
78     HeaderMap,
79     AsHeaderName,
80     IntoHeaderName,
81     Iter,
82     IterMut,
83     Keys,
84     Values,
85     ValuesMut,
86     Drain,
87     GetAll,
88     Entry,
89     VacantEntry,
90     OccupiedEntry,
91     ValueIter,
92     ValueIterMut,
93     ValueDrain,
94     IntoIter,
95 };
96 pub use self::name::{
97     HeaderName,
98     InvalidHeaderName,
99     InvalidHeaderNameBytes,
100 };
101 pub use self::value::{
102     HeaderValue,
103     InvalidHeaderValue,
104     InvalidHeaderValueBytes,
105     ToStrError,
106 };
107 
108 // Use header name constants
109 pub use self::name::{
110     ACCEPT,
111     ACCEPT_CHARSET,
112     ACCEPT_ENCODING,
113     ACCEPT_LANGUAGE,
114     ACCEPT_RANGES,
115     ACCESS_CONTROL_ALLOW_CREDENTIALS,
116     ACCESS_CONTROL_ALLOW_HEADERS,
117     ACCESS_CONTROL_ALLOW_METHODS,
118     ACCESS_CONTROL_ALLOW_ORIGIN,
119     ACCESS_CONTROL_EXPOSE_HEADERS,
120     ACCESS_CONTROL_MAX_AGE,
121     ACCESS_CONTROL_REQUEST_HEADERS,
122     ACCESS_CONTROL_REQUEST_METHOD,
123     AGE,
124     ALLOW,
125     ALT_SVC,
126     AUTHORIZATION,
127     CACHE_CONTROL,
128     CONNECTION,
129     CONTENT_DISPOSITION,
130     CONTENT_ENCODING,
131     CONTENT_LANGUAGE,
132     CONTENT_LENGTH,
133     CONTENT_LOCATION,
134     CONTENT_RANGE,
135     CONTENT_SECURITY_POLICY,
136     CONTENT_SECURITY_POLICY_REPORT_ONLY,
137     CONTENT_TYPE,
138     COOKIE,
139     DNT,
140     DATE,
141     ETAG,
142     EXPECT,
143     EXPIRES,
144     FORWARDED,
145     FROM,
146     HOST,
147     IF_MATCH,
148     IF_MODIFIED_SINCE,
149     IF_NONE_MATCH,
150     IF_RANGE,
151     IF_UNMODIFIED_SINCE,
152     LAST_MODIFIED,
153     LINK,
154     LOCATION,
155     MAX_FORWARDS,
156     ORIGIN,
157     PRAGMA,
158     PROXY_AUTHENTICATE,
159     PROXY_AUTHORIZATION,
160     PUBLIC_KEY_PINS,
161     PUBLIC_KEY_PINS_REPORT_ONLY,
162     RANGE,
163     REFERER,
164     REFERRER_POLICY,
165     REFRESH,
166     RETRY_AFTER,
167     SEC_WEBSOCKET_ACCEPT,
168     SEC_WEBSOCKET_EXTENSIONS,
169     SEC_WEBSOCKET_KEY,
170     SEC_WEBSOCKET_PROTOCOL,
171     SEC_WEBSOCKET_VERSION,
172     SERVER,
173     SET_COOKIE,
174     STRICT_TRANSPORT_SECURITY,
175     TE,
176     TRAILER,
177     TRANSFER_ENCODING,
178     UPGRADE,
179     UPGRADE_INSECURE_REQUESTS,
180     USER_AGENT,
181     VARY,
182     VIA,
183     WARNING,
184     WWW_AUTHENTICATE,
185     X_CONTENT_TYPE_OPTIONS,
186     X_DNS_PREFETCH_CONTROL,
187     X_FRAME_OPTIONS,
188     X_XSS_PROTECTION,
189 };
190 
191 /// Maximum length of a header name
192 ///
193 /// Generally, 64kb for a header name is WAY too much than would ever be needed
194 /// in practice. Restricting it to this size enables using `u16` values to
195 /// represent offsets when dealing with header names.
196 const MAX_HEADER_NAME_LEN: usize = 1 << 16;
197