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 AsHeaderName, Drain, Entry, GetAll, HeaderMap, IntoHeaderName, IntoIter, Iter, IterMut, Keys, 79 OccupiedEntry, VacantEntry, ValueDrain, ValueIter, ValueIterMut, Values, ValuesMut, 80 }; 81 pub use self::name::{HeaderName, InvalidHeaderName}; 82 pub use self::value::{HeaderValue, InvalidHeaderValue, ToStrError}; 83 84 // Use header name constants 85 pub use self::name::{ 86 ACCEPT, 87 ACCEPT_CHARSET, 88 ACCEPT_ENCODING, 89 ACCEPT_LANGUAGE, 90 ACCEPT_RANGES, 91 ACCESS_CONTROL_ALLOW_CREDENTIALS, 92 ACCESS_CONTROL_ALLOW_HEADERS, 93 ACCESS_CONTROL_ALLOW_METHODS, 94 ACCESS_CONTROL_ALLOW_ORIGIN, 95 ACCESS_CONTROL_EXPOSE_HEADERS, 96 ACCESS_CONTROL_MAX_AGE, 97 ACCESS_CONTROL_REQUEST_HEADERS, 98 ACCESS_CONTROL_REQUEST_METHOD, 99 AGE, 100 ALLOW, 101 ALT_SVC, 102 AUTHORIZATION, 103 CACHE_CONTROL, 104 CONNECTION, 105 CONTENT_DISPOSITION, 106 CONTENT_ENCODING, 107 CONTENT_LANGUAGE, 108 CONTENT_LENGTH, 109 CONTENT_LOCATION, 110 CONTENT_RANGE, 111 CONTENT_SECURITY_POLICY, 112 CONTENT_SECURITY_POLICY_REPORT_ONLY, 113 CONTENT_TYPE, 114 COOKIE, 115 DNT, 116 DATE, 117 ETAG, 118 EXPECT, 119 EXPIRES, 120 FORWARDED, 121 FROM, 122 HOST, 123 IF_MATCH, 124 IF_MODIFIED_SINCE, 125 IF_NONE_MATCH, 126 IF_RANGE, 127 IF_UNMODIFIED_SINCE, 128 LAST_MODIFIED, 129 LINK, 130 LOCATION, 131 MAX_FORWARDS, 132 ORIGIN, 133 PRAGMA, 134 PROXY_AUTHENTICATE, 135 PROXY_AUTHORIZATION, 136 PUBLIC_KEY_PINS, 137 PUBLIC_KEY_PINS_REPORT_ONLY, 138 RANGE, 139 REFERER, 140 REFERRER_POLICY, 141 REFRESH, 142 RETRY_AFTER, 143 SEC_WEBSOCKET_ACCEPT, 144 SEC_WEBSOCKET_EXTENSIONS, 145 SEC_WEBSOCKET_KEY, 146 SEC_WEBSOCKET_PROTOCOL, 147 SEC_WEBSOCKET_VERSION, 148 SERVER, 149 SET_COOKIE, 150 STRICT_TRANSPORT_SECURITY, 151 TE, 152 TRAILER, 153 TRANSFER_ENCODING, 154 UPGRADE, 155 UPGRADE_INSECURE_REQUESTS, 156 USER_AGENT, 157 VARY, 158 VIA, 159 WARNING, 160 WWW_AUTHENTICATE, 161 X_CONTENT_TYPE_OPTIONS, 162 X_DNS_PREFETCH_CONTROL, 163 X_FRAME_OPTIONS, 164 X_XSS_PROTECTION, 165 }; 166 167 /// Maximum length of a header name 168 /// 169 /// Generally, 64kb for a header name is WAY too much than would ever be needed 170 /// in practice. Restricting it to this size enables using `u16` values to 171 /// represent offsets when dealing with header names. 172 const MAX_HEADER_NAME_LEN: usize = 1 << 16; 173