      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172

    //! HTTP header types
    //!
    //! The module provides [`HeaderName`], [`HeaderMap`], and a number of types
    //! used for interacting with `HeaderMap`. These types allow representing both
    //! HTTP/1 and HTTP/2 headers.
    //!
    //! # `HeaderName`
    //!
    //! The `HeaderName` type represents both standard header names as well as
    //! custom header names. The type handles the case insensitive nature of header
    //! names and is used as the key portion of `HeaderMap`. Header names are
    //! normalized to lower case. In other words, when creating a `HeaderName` with
    //! a string, even if upper case characters are included, when getting a string
    //! representation of the `HeaderName`, it will be all lower case. This allows
    //! for faster `HeaderMap` comparison operations.
    //!
    //! The internal representation is optimized to efficiently handle the cases
    //! most commonly encountered when working with HTTP. Standard header names are
    //! special cased and are represented internally as an enum. Short custom
    //! headers will be stored directly in the `HeaderName` struct and will not
    //! incur any allocation overhead, however longer strings will require an
    //! allocation for storage.
    //!
    //! ## Limitations
    //!
    //! `HeaderName` has a max length of 32,768 for header names. Attempting to
    //! parse longer names will result in a panic.
    //!
    //! # `HeaderMap`
    //!
    //! `HeaderMap` is a map structure of header names highly optimized for use
    //! cases common with HTTP. It is a [multimap] structure, where each header name
    //! may have multiple associated header values. Given this, some of the APIs
    //! diverge from [`HashMap`].
    //!
    //! ## Overview
    //!
    //! Just like `HashMap` in Rust's stdlib, `HeaderMap` is based on [Robin Hood
    //! hashing]. This algorithm tends to reduce the worst case search times in the
    //! table and enables high load factors without seriously affecting performance.
    //! Internally, keys and values are stored in vectors. As such, each insertion
    //! will not incur allocation overhead. However, once the underlying vector
    //! storage is full, a larger vector must be allocated and all values copied.
    //!
    //! ## Deterministic ordering
    //!
    //! Unlike Rust's `HashMap`, values in `HeaderMap` are deterministically
    //! ordered. Roughly, values are ordered by insertion. This means that a
    //! function that deterministically operates on a header map can rely on the
    //! iteration order to remain consistent across processes and platforms.
    //!
    //! ## Adaptive hashing
    //!
    //! `HeaderMap` uses an adaptive hashing strategy in order to efficiently handle
    //! most common cases. All standard headers have statically computed hash values
    //! which removes the need to perform any hashing of these headers at runtime.
    //! The default hash function emphasizes performance over robustness. However,
    //! `HeaderMap` detects high collision rates and switches to a secure hash
    //! function in those events. The threshold is set such that only denial of
    //! service attacks should trigger it.
    //!
    //! ## Limitations
    //!
    //! `HeaderMap` can store a maximum of 32,768 headers (header name / value
    //! pairs). Attempting to insert more will result in a panic.
    //!
    //! [`HeaderName`]: struct.HeaderName.html
    //! [`HeaderMap`]: struct.HeaderMap.html
    //! [multimap]: https://en.wikipedia.org/wiki/Multimap
    //! [`HashMap`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html
    //! [Robin Hood hashing]: https://en.wikipedia.org/wiki/Hash_table#Robin_Hood_hashing

    mod map;
    mod name;
    mod value;

    pub use self::map::{
        AsHeaderName, Drain, Entry, GetAll, HeaderMap, IntoHeaderName, IntoIter, Iter, IterMut, Keys,
        OccupiedEntry, VacantEntry, ValueDrain, ValueIter, ValueIterMut, Values, ValuesMut,
    };
    pub use self::name::{HeaderName, InvalidHeaderName};
    pub use self::value::{HeaderValue, InvalidHeaderValue, ToStrError};

    // Use header name constants
    pub use self::name::{
        ACCEPT,
        ACCEPT_CHARSET,
        ACCEPT_ENCODING,
        ACCEPT_LANGUAGE,
        ACCEPT_RANGES,
        ACCESS_CONTROL_ALLOW_CREDENTIALS,
        ACCESS_CONTROL_ALLOW_HEADERS,
        ACCESS_CONTROL_ALLOW_METHODS,
        ACCESS_CONTROL_ALLOW_ORIGIN,
        ACCESS_CONTROL_EXPOSE_HEADERS,
        ACCESS_CONTROL_MAX_AGE,
        ACCESS_CONTROL_REQUEST_HEADERS,
        ACCESS_CONTROL_REQUEST_METHOD,
        AGE,
        ALLOW,
        ALT_SVC,
        AUTHORIZATION,
        CACHE_CONTROL,
        CONNECTION,
        CONTENT_DISPOSITION,
        CONTENT_ENCODING,
        CONTENT_LANGUAGE,
        CONTENT_LENGTH,
        CONTENT_LOCATION,
        CONTENT_RANGE,
        CONTENT_SECURITY_POLICY,
        CONTENT_SECURITY_POLICY_REPORT_ONLY,
        CONTENT_TYPE,
        COOKIE,
        DNT,
        DATE,
        ETAG,
        EXPECT,
        EXPIRES,
        FORWARDED,
        FROM,
        HOST,
        IF_MATCH,
        IF_MODIFIED_SINCE,
        IF_NONE_MATCH,
        IF_RANGE,
        IF_UNMODIFIED_SINCE,
        LAST_MODIFIED,
        LINK,
        LOCATION,
        MAX_FORWARDS,
        ORIGIN,
        PRAGMA,
        PROXY_AUTHENTICATE,
        PROXY_AUTHORIZATION,
        PUBLIC_KEY_PINS,
        PUBLIC_KEY_PINS_REPORT_ONLY,
        RANGE,
        REFERER,
        REFERRER_POLICY,
        REFRESH,
        RETRY_AFTER,
        SEC_WEBSOCKET_ACCEPT,
        SEC_WEBSOCKET_EXTENSIONS,
        SEC_WEBSOCKET_KEY,
        SEC_WEBSOCKET_PROTOCOL,
        SEC_WEBSOCKET_VERSION,
        SERVER,
        SET_COOKIE,
        STRICT_TRANSPORT_SECURITY,
        TE,
        TRAILER,
        TRANSFER_ENCODING,
        UPGRADE,
        UPGRADE_INSECURE_REQUESTS,
        USER_AGENT,
        VARY,
        VIA,
        WARNING,
        WWW_AUTHENTICATE,
        X_CONTENT_TYPE_OPTIONS,
        X_DNS_PREFETCH_CONTROL,
        X_FRAME_OPTIONS,
        X_XSS_PROTECTION,
    };

    /// Maximum length of a header name
    ///
    /// Generally, 64kb for a header name is WAY too much than would ever be needed
    /// in practice. Restricting it to this size enables using `u16` values to
    /// represent offsets when dealing with header names.
    const MAX_HEADER_NAME_LEN: usize = (1 << 16) - 1;