{-# LANGUAGE OverloadedStrings #-}

module Network.HPACK.Token (
  -- * Data type
    Token(..)
  , tokenCIKey
  , tokenFoldedKey
  , toToken
  -- * Ix
  , minTokenIx
  , maxStaticTokenIx
  , maxTokenIx
  , cookieTokenIx
  -- * Utilities
  , isMaxTokenIx
  , isCookieTokenIx
  , isStaticTokenIx
  , isStaticToken
  -- * Defined tokens
  , tokenAuthority
  , tokenMethod
  , tokenPath
  , tokenScheme
  , tokenStatus
  , tokenAcceptCharset
  , tokenAcceptEncoding
  , tokenAcceptLanguage
  , tokenAcceptRanges
  , tokenAccept
  , tokenAccessControlAllowOrigin
  , tokenAge
  , tokenAllow
  , tokenAuthorization
  , tokenCacheControl
  , tokenContentDisposition
  , tokenContentEncoding
  , tokenContentLanguage
  , tokenContentLength
  , tokenContentLocation
  , tokenContentRange
  , tokenContentType
  , tokenCookie
  , tokenDate
  , tokenEtag
  , tokenExpect
  , tokenExpires
  , tokenFrom
  , tokenHost
  , tokenIfMatch
  , tokenIfModifiedSince
  , tokenIfNoneMatch
  , tokenIfRange
  , tokenIfUnmodifiedSince
  , tokenLastModified
  , tokenLink
  , tokenLocation
  , tokenMaxForwards
  , tokenProxyAuthenticate
  , tokenProxyAuthorization
  , tokenRange
  , tokenReferer
  , tokenRefresh
  , tokenRetryAfter
  , tokenServer
  , tokenSetCookie
  , tokenStrictTransportSecurity
  , tokenTransferEncoding
  , tokenUserAgent
  , tokenVary
  , tokenVia
  , tokenWwwAuthenticate
  , tokenConnection
  , tokenTE
  , tokenMax
  , tokenAccessControlAllowCredentials
  , tokenAccessControlAllowHeaders
  , tokenAccessControlAllowMethods
  , tokenAccessControlExposeHeaders
  , tokenAccessControlRequestHeaders
  , tokenAccessControlRequestMethod
  , tokenAltSvc
  , tokenContentSecurityPolicy
  , tokenEarlyData
  , tokenExpectCt
  , tokenForwarded
  , tokenOrigin
  , tokenPurpose
  , tokenTimingAllowOrigin
  , tokenUpgradeInsecureRequests
  , tokenXContentTypeOptions
  , tokenXForwardedFor
  , tokenXFrameOptions
  , tokenXXssProtection
  ) where

import qualified Data.ByteString as B
import Data.ByteString.Internal (ByteString(..), memcmp)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (plusPtr)
import System.IO.Unsafe (unsafeDupablePerformIO)
import Data.CaseInsensitive (original, mk, CI(..))

-- $setup
-- >>> :set -XOverloadedStrings

-- | Internal representation for header keys.
data Token = Token {
    Token -> Int
tokenIx :: Int          -- ^ Index for value table
  , Token -> Bool
shouldBeIndexed :: Bool -- ^ should be indexed in HPACK
  , Token -> Bool
isPseudo :: Bool        -- ^ is this a pseudo header key?
  , Token -> CI ByteString
tokenKey :: CI ByteString -- ^ Case insensitive header key
  } deriving (Token -> Token -> Bool
(Token -> Token -> Bool) -> (Token -> Token -> Bool) -> Eq Token
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c== :: Token -> Token -> Bool
Eq, Int -> Token -> ShowS
[Token] -> ShowS
Token -> String
(Int -> Token -> ShowS)
-> (Token -> String) -> ([Token] -> ShowS) -> Show Token
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Token] -> ShowS
$cshowList :: [Token] -> ShowS
show :: Token -> String
$cshow :: Token -> String
showsPrec :: Int -> Token -> ShowS
$cshowsPrec :: Int -> Token -> ShowS
Show)

-- | Extracting a case insensitive header key from a token.
{-# INLINE tokenCIKey #-}
tokenCIKey :: Token -> ByteString
tokenCIKey :: Token -> ByteString
tokenCIKey (Token Int
_ Bool
_ Bool
_ CI ByteString
ci) = CI ByteString -> ByteString
forall s. CI s -> s
original CI ByteString
ci

-- | Extracting a folded header key from a token.
{-# INLINE tokenFoldedKey #-}
tokenFoldedKey :: Token -> ByteString
tokenFoldedKey :: Token -> ByteString
tokenFoldedKey (Token Int
_ Bool
_ Bool
_ CI ByteString
ci) = CI ByteString -> ByteString
forall s. CI s -> s
foldedCase CI ByteString
ci

tokenAuthority                :: Token
tokenMethod                   :: Token
tokenPath                     :: Token
tokenScheme                   :: Token
tokenStatus                   :: Token
tokenAcceptCharset            :: Token
tokenAcceptEncoding           :: Token
tokenAcceptLanguage           :: Token
tokenAcceptRanges             :: Token
tokenAccept                   :: Token
tokenAccessControlAllowOrigin :: Token
tokenAge                      :: Token
tokenAllow                    :: Token
tokenAuthorization            :: Token
tokenCacheControl             :: Token
tokenContentDisposition       :: Token
tokenContentEncoding          :: Token
tokenContentLanguage          :: Token
tokenContentLength            :: Token
tokenContentLocation          :: Token
tokenContentRange             :: Token
tokenContentType              :: Token
tokenCookie                   :: Token
tokenDate                     :: Token
tokenEtag                     :: Token
tokenExpect                   :: Token
tokenExpires                  :: Token
tokenFrom                     :: Token
tokenHost                     :: Token
tokenIfMatch                  :: Token
tokenIfModifiedSince          :: Token
tokenIfNoneMatch              :: Token
tokenIfRange                  :: Token
tokenIfUnmodifiedSince        :: Token
tokenLastModified             :: Token
tokenLink                     :: Token
tokenLocation                 :: Token
tokenMaxForwards              :: Token
tokenProxyAuthenticate        :: Token
tokenProxyAuthorization       :: Token
tokenRange                    :: Token
tokenReferer                  :: Token
tokenRefresh                  :: Token
tokenRetryAfter               :: Token
tokenServer                   :: Token
tokenSetCookie                :: Token
tokenStrictTransportSecurity  :: Token
tokenTransferEncoding         :: Token
tokenUserAgent                :: Token
tokenVary                     :: Token
tokenVia                      :: Token
tokenWwwAuthenticate          :: Token
tokenConnection               :: Token -- Warp
tokenTE                       :: Token -- Warp
tokenAccessControlAllowCredentials :: Token -- QPACK
tokenAccessControlAllowHeaders     :: Token -- QPACK
tokenAccessControlAllowMethods     :: Token -- QPACK
tokenAccessControlExposeHeaders    :: Token -- QPACK
tokenAccessControlRequestHeaders   :: Token -- QPACK
tokenAccessControlRequestMethod    :: Token -- QPACK
tokenAltSvc                        :: Token -- QPACK
tokenContentSecurityPolicy         :: Token -- QPACK
tokenEarlyData                     :: Token -- QPACK
tokenExpectCt                      :: Token -- QPACK
tokenForwarded                     :: Token -- QPACK
tokenOrigin                        :: Token -- QPACK
tokenPurpose                       :: Token -- QPACK
tokenTimingAllowOrigin             :: Token -- QPACK
tokenUpgradeInsecureRequests       :: Token -- QPACK
tokenXContentTypeOptions           :: Token -- QPACK
tokenXForwardedFor                 :: Token -- QPACK
tokenXFrameOptions                 :: Token -- QPACK
tokenXXssProtection                :: Token -- QPACK

tokenMax                      :: Token -- Other tokens

tokenAuthority :: Token
tokenAuthority                = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
0  Bool
True  Bool
True CI ByteString
":authority"
tokenMethod :: Token
tokenMethod                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
1  Bool
True  Bool
True CI ByteString
":method"
tokenPath :: Token
tokenPath                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
2 Bool
False  Bool
True CI ByteString
":path"
tokenScheme :: Token
tokenScheme                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
3  Bool
True  Bool
True CI ByteString
":scheme"
tokenStatus :: Token
tokenStatus                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
4  Bool
True  Bool
True CI ByteString
":status"
tokenAcceptCharset :: Token
tokenAcceptCharset            = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
5  Bool
True Bool
False CI ByteString
"Accept-Charset"
tokenAcceptEncoding :: Token
tokenAcceptEncoding           = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
6  Bool
True Bool
False CI ByteString
"Accept-Encoding"
tokenAcceptLanguage :: Token
tokenAcceptLanguage           = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
7  Bool
True Bool
False CI ByteString
"Accept-Language"
tokenAcceptRanges :: Token
tokenAcceptRanges             = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
8  Bool
True Bool
False CI ByteString
"Accept-Ranges"
tokenAccept :: Token
tokenAccept                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token  Int
9  Bool
True Bool
False CI ByteString
"Accept"
tokenAccessControlAllowOrigin :: Token
tokenAccessControlAllowOrigin = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
10  Bool
True Bool
False CI ByteString
"Access-Control-Allow-Origin"
tokenAge :: Token
tokenAge                      = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
11  Bool
True Bool
False CI ByteString
"Age"
tokenAllow :: Token
tokenAllow                    = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
12  Bool
True Bool
False CI ByteString
"Allow"
tokenAuthorization :: Token
tokenAuthorization            = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
13  Bool
True Bool
False CI ByteString
"Authorization"
tokenCacheControl :: Token
tokenCacheControl             = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
14  Bool
True Bool
False CI ByteString
"Cache-Control"
tokenContentDisposition :: Token
tokenContentDisposition       = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
15  Bool
True Bool
False CI ByteString
"Content-Disposition"
tokenContentEncoding :: Token
tokenContentEncoding          = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
16  Bool
True Bool
False CI ByteString
"Content-Encoding"
tokenContentLanguage :: Token
tokenContentLanguage          = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
17  Bool
True Bool
False CI ByteString
"Content-Language"
tokenContentLength :: Token
tokenContentLength            = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
18 Bool
False Bool
False CI ByteString
"Content-Length"
tokenContentLocation :: Token
tokenContentLocation          = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
19 Bool
False Bool
False CI ByteString
"Content-Location"
tokenContentRange :: Token
tokenContentRange             = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
20  Bool
True Bool
False CI ByteString
"Content-Range"
tokenContentType :: Token
tokenContentType              = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
21  Bool
True Bool
False CI ByteString
"Content-Type"
tokenCookie :: Token
tokenCookie                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
22  Bool
True Bool
False CI ByteString
"Cookie"
tokenDate :: Token
tokenDate                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
23  Bool
True Bool
False CI ByteString
"Date"
tokenEtag :: Token
tokenEtag                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
24 Bool
False Bool
False CI ByteString
"Etag"
tokenExpect :: Token
tokenExpect                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
25  Bool
True Bool
False CI ByteString
"Expect"
tokenExpires :: Token
tokenExpires                  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
26  Bool
True Bool
False CI ByteString
"Expires"
tokenFrom :: Token
tokenFrom                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
27  Bool
True Bool
False CI ByteString
"From"
tokenHost :: Token
tokenHost                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
28  Bool
True Bool
False CI ByteString
"Host"
tokenIfMatch :: Token
tokenIfMatch                  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
29  Bool
True Bool
False CI ByteString
"If-Match"
tokenIfModifiedSince :: Token
tokenIfModifiedSince          = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
30  Bool
True Bool
False CI ByteString
"If-Modified-Since"
tokenIfNoneMatch :: Token
tokenIfNoneMatch              = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
31  Bool
True Bool
False CI ByteString
"If-None-Match"
tokenIfRange :: Token
tokenIfRange                  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
32  Bool
True Bool
False CI ByteString
"If-Range"
tokenIfUnmodifiedSince :: Token
tokenIfUnmodifiedSince        = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
33  Bool
True Bool
False CI ByteString
"If-Unmodified-Since"
tokenLastModified :: Token
tokenLastModified             = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
34  Bool
True Bool
False CI ByteString
"Last-Modified"
tokenLink :: Token
tokenLink                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
35  Bool
True Bool
False CI ByteString
"Link"
tokenLocation :: Token
tokenLocation                 = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
36  Bool
True Bool
False CI ByteString
"Location"
tokenMaxForwards :: Token
tokenMaxForwards              = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
37  Bool
True Bool
False CI ByteString
"Max-Forwards"
tokenProxyAuthenticate :: Token
tokenProxyAuthenticate        = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
38  Bool
True Bool
False CI ByteString
"Proxy-Authenticate"
tokenProxyAuthorization :: Token
tokenProxyAuthorization       = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
39  Bool
True Bool
False CI ByteString
"Proxy-Authorization"
tokenRange :: Token
tokenRange                    = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
40  Bool
True Bool
False CI ByteString
"Range"
tokenReferer :: Token
tokenReferer                  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
41  Bool
True Bool
False CI ByteString
"Referer"
tokenRefresh :: Token
tokenRefresh                  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
42  Bool
True Bool
False CI ByteString
"Refresh"
tokenRetryAfter :: Token
tokenRetryAfter               = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
43  Bool
True Bool
False CI ByteString
"Retry-After"
tokenServer :: Token
tokenServer                   = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
44  Bool
True Bool
False CI ByteString
"Server"
tokenSetCookie :: Token
tokenSetCookie                = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
45 Bool
False Bool
False CI ByteString
"Set-Cookie"
tokenStrictTransportSecurity :: Token
tokenStrictTransportSecurity  = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
46  Bool
True Bool
False CI ByteString
"Strict-Transport-Security"
tokenTransferEncoding :: Token
tokenTransferEncoding         = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
47  Bool
True Bool
False CI ByteString
"Transfer-Encoding"
tokenUserAgent :: Token
tokenUserAgent                = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
48  Bool
True Bool
False CI ByteString
"User-Agent"
tokenVary :: Token
tokenVary                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
49  Bool
True Bool
False CI ByteString
"Vary"
tokenVia :: Token
tokenVia                      = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
50  Bool
True Bool
False CI ByteString
"Via"
tokenWwwAuthenticate :: Token
tokenWwwAuthenticate          = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
51  Bool
True Bool
False CI ByteString
"Www-Authenticate"

-- | A place holder to hold header keys not defined in the static table.
-- | For Warp
tokenConnection :: Token
tokenConnection                    = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
52 Bool
False Bool
False CI ByteString
"Connection"
tokenTE :: Token
tokenTE                            = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
53 Bool
False Bool
False CI ByteString
"TE"
-- | For QPACK
tokenAccessControlAllowCredentials :: Token
tokenAccessControlAllowCredentials = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
54  Bool
True Bool
False CI ByteString
"Access-Control-Allow-Credentials"
tokenAccessControlAllowHeaders :: Token
tokenAccessControlAllowHeaders     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
55  Bool
True Bool
False CI ByteString
"Access-Control-Allow-Headers"
tokenAccessControlAllowMethods :: Token
tokenAccessControlAllowMethods     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
56  Bool
True Bool
False CI ByteString
"Access-Control-Allow-Methods"
tokenAccessControlExposeHeaders :: Token
tokenAccessControlExposeHeaders    = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
57  Bool
True Bool
False CI ByteString
"Access-Control-Expose-Headers"
tokenAccessControlRequestHeaders :: Token
tokenAccessControlRequestHeaders   = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
58  Bool
True Bool
False CI ByteString
"Access-Control-Request-Headers"
tokenAccessControlRequestMethod :: Token
tokenAccessControlRequestMethod    = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
59  Bool
True Bool
False CI ByteString
"Access-Control-Request-Method"
tokenAltSvc :: Token
tokenAltSvc                        = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
60  Bool
True Bool
False CI ByteString
"Alt-Svc"
tokenContentSecurityPolicy :: Token
tokenContentSecurityPolicy         = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
61  Bool
True Bool
False CI ByteString
"Content-Security-Policy"
tokenEarlyData :: Token
tokenEarlyData                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
62  Bool
True Bool
False CI ByteString
"Early-Data"
tokenExpectCt :: Token
tokenExpectCt                      = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
63  Bool
True Bool
False CI ByteString
"Expect-Ct"
tokenForwarded :: Token
tokenForwarded                     = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
64  Bool
True Bool
False CI ByteString
"Forwarded"
tokenOrigin :: Token
tokenOrigin                        = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
65  Bool
True Bool
False CI ByteString
"Origin"
tokenPurpose :: Token
tokenPurpose                       = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
66  Bool
True Bool
False CI ByteString
"Purpose"
tokenTimingAllowOrigin :: Token
tokenTimingAllowOrigin             = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
67  Bool
True Bool
False CI ByteString
"Timing-Allow-Origin"
tokenUpgradeInsecureRequests :: Token
tokenUpgradeInsecureRequests       = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
68  Bool
True Bool
False CI ByteString
"Upgrade-Insecure-Requests"
tokenXContentTypeOptions :: Token
tokenXContentTypeOptions           = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
69  Bool
True Bool
False CI ByteString
"X-Content-Type-Options"
tokenXForwardedFor :: Token
tokenXForwardedFor                 = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
70  Bool
True Bool
False CI ByteString
"X-Forwarded-For"
tokenXFrameOptions :: Token
tokenXFrameOptions                 = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
71  Bool
True Bool
False CI ByteString
"X-Frame-Options"
tokenXXssProtection :: Token
tokenXXssProtection                = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
72  Bool
True Bool
False CI ByteString
"X-Xss-Protection"

tokenMax :: Token
tokenMax                           = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
73  Bool
True Bool
False CI ByteString
"for other tokens"

-- | Minimum token index.
minTokenIx :: Int
minTokenIx :: Int
minTokenIx = Int
0

-- | Maximun token index defined in the static table.
maxStaticTokenIx :: Int
maxStaticTokenIx :: Int
maxStaticTokenIx = Int
51

-- | Maximum token index.
maxTokenIx :: Int
maxTokenIx :: Int
maxTokenIx = Int
73

-- | Token index for 'tokenCookie'.
cookieTokenIx :: Int
cookieTokenIx :: Int
cookieTokenIx = Int
22

-- | Is this token ix for Cookie?
{-# INLINE isCookieTokenIx #-}
isCookieTokenIx :: Int -> Bool
isCookieTokenIx :: Int -> Bool
isCookieTokenIx Int
n = Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
cookieTokenIx

-- | Is this token ix to be held in the place holder?
{-# INLINE isMaxTokenIx #-}
isMaxTokenIx :: Int -> Bool
isMaxTokenIx :: Int -> Bool
isMaxTokenIx Int
n = Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
maxTokenIx

-- | Is this token ix for a header not defined in the static table?
{-# INLINE isStaticTokenIx #-}
isStaticTokenIx :: Int -> Bool
isStaticTokenIx :: Int -> Bool
isStaticTokenIx Int
n = Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxStaticTokenIx

-- | Is this token for a header not defined in the static table?
{-# INLINE isStaticToken #-}
isStaticToken :: Token -> Bool
isStaticToken :: Token -> Bool
isStaticToken Token
n = Token -> Int
tokenIx Token
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxStaticTokenIx

-- | Making a token from a header key.
--
-- >>> toToken ":authority" == tokenAuthority
-- True
-- >>> toToken "foo"
-- Token {tokenIx = 73, shouldBeIndexed = True, isPseudo = False, tokenKey = "foo"}
-- >>> toToken ":bar"
-- Token {tokenIx = 73, shouldBeIndexed = True, isPseudo = True, tokenKey = ":bar"}
toToken :: ByteString -> Token
toToken :: ByteString -> Token
toToken ByteString
"" = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
maxTokenIx Bool
True Bool
False CI ByteString
""
toToken ByteString
bs = case Int
len of
    Int
2 -> if ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"te" then Token
tokenTE else ByteString -> Token
mkTokenMax ByteString
bs
    Int
3 -> case Word8
lst of
        Word8
97  | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"via" -> Token
tokenVia
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"age" -> Token
tokenAge
        Word8
_                  -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
4 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"date" -> Token
tokenDate
        Word8
103 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"etag" -> Token
tokenEtag
        Word8
107 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"link" -> Token
tokenLink
        Word8
109 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"from" -> Token
tokenFrom
        Word8
116 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"host" -> Token
tokenHost
        Word8
121 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"vary" -> Token
tokenVary
        Word8
_                   -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
5 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"range" -> Token
tokenRange
        Word8
104 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
":path" -> Token
tokenPath
        Word8
119 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"allow" -> Token
tokenAllow
        Word8
_                    -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
6 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"cookie" -> Token
tokenCookie
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"origin" -> Token
tokenOrigin
        Word8
114 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"server" -> Token
tokenServer
        Word8
116 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"expect" -> Token
tokenExpect
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"accept" -> Token
tokenAccept
        Word8
_                     -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
7 -> case Word8
lst of
        Word8
99  | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"alt-svc" -> Token
tokenAltSvc
        Word8
100 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
":method" -> Token
tokenMethod
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
":scheme" -> Token
tokenScheme
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"purpose" -> Token
tokenPurpose
        Word8
104 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"refresh" -> Token
tokenRefresh
        Word8
114 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"referer" -> Token
tokenReferer
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"expires" -> Token
tokenExpires
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
":status" -> Token
tokenStatus
        Word8
_                      -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
8 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"if-range" -> Token
tokenIfRange
        Word8
104 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"if-match" -> Token
tokenIfMatch
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"location" -> Token
tokenLocation
        Word8
_                       -> ByteString -> Token
mkTokenMax ByteString
bs

    Int
9 -> case Word8
lst of
        Word8
100 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"forwarded" -> Token
tokenForwarded
        Word8
116 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"expect-ct" -> Token
tokenExpectCt
        Word8
_                        -> ByteString -> Token
mkTokenMax ByteString
bs

    Int
10 -> case Word8
lst of
        Word8
97  | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"early-data" -> Token
tokenEarlyData
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"set-cookie" -> Token
tokenSetCookie
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"connection" -> Token
tokenConnection
        Word8
116 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"user-agent" -> Token
tokenUserAgent
        Word8
121 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
":authority" -> Token
tokenAuthority
        Word8
_                         -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
11 -> case Word8
lst of
        Word8
114 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"retry-after" -> Token
tokenRetryAfter
        Word8
_                          -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
12 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-type" -> Token
tokenContentType
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"max-forwards" -> Token
tokenMaxForwards
        Word8
_                           -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
13 -> case Word8
lst of
        Word8
100 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"last-modified" -> Token
tokenLastModified
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-range" -> Token
tokenContentRange
        Word8
104 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"if-none-match" -> Token
tokenIfNoneMatch
        Word8
108 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"cache-control" -> Token
tokenCacheControl
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"authorization" -> Token
tokenAuthorization
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"accept-ranges" -> Token
tokenAcceptRanges
        Word8
_                            -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
14 -> case Word8
lst of
        Word8
104 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-length" -> Token
tokenContentLength
        Word8
116 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"accept-charset" -> Token
tokenAcceptCharset
        Word8
_                             -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
15 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"accept-language" -> Token
tokenAcceptLanguage
        Word8
103 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"accept-encoding" -> Token
tokenAcceptEncoding
        Word8
114 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"x-forwarded-for" -> Token
tokenXForwardedFor
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"x-frame-options" -> Token
tokenXFrameOptions
        Word8
_                              -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
16 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-language" -> Token
tokenContentLanguage
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"www-authenticate" -> Token
tokenWwwAuthenticate
        Word8
103 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-encoding" -> Token
tokenContentEncoding
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-location" -> Token
tokenContentLocation
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"x-xss-protection" -> Token
tokenXXssProtection
        Word8
_                               -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
17 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"if-modified-since" -> Token
tokenIfModifiedSince
        Word8
103 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"transfer-encoding" -> Token
tokenTransferEncoding
        Word8
_                                -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
18 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"proxy-authenticate" -> Token
tokenProxyAuthenticate
        Word8
_                                 -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
19 -> case Word8
lst of
        Word8
101 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"if-unmodified-since" -> Token
tokenIfUnmodifiedSince
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"proxy-authorization" -> Token
tokenProxyAuthorization
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-disposition" -> Token
tokenContentDisposition
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"timing-allow-origin" -> Token
tokenTimingAllowOrigin
        Word8
_                                  -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
22 -> case Word8
lst of
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"x-content-type-options" -> Token
tokenXContentTypeOptions
        Word8
_                                     -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
23 -> case Word8
lst of
        Word8
121 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"content-security-policy" -> Token
tokenContentSecurityPolicy
        Word8
_                                      -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
25 -> case Word8
lst of
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"upgrade-insecure-requests" -> Token
tokenUpgradeInsecureRequests
        Word8
121 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"strict-transport-security" -> Token
tokenStrictTransportSecurity
        Word8
_                                        -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
27 -> case Word8
lst of
        Word8
110 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-allow-origin" -> Token
tokenAccessControlAllowOrigin
        Word8
_                                          -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
28 -> case Word8
lst of
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-allow-headers" -> Token
tokenAccessControlAllowHeaders
            | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-allow-methods" -> Token
tokenAccessControlAllowMethods
        Word8
_                                           -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
29 -> case Word8
lst of
        Word8
100 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-request-method" -> Token
tokenAccessControlRequestMethod
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-expose-headers" -> Token
tokenAccessControlExposeHeaders
        Word8
_                                            -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
30 -> case Word8
lst of
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-request-headers" -> Token
tokenAccessControlRequestHeaders
        Word8
_                                             -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
32 -> case Word8
lst of
        Word8
115 | ByteString
bs ByteString -> ByteString -> Bool
=== ByteString
"access-control-allow-credentials" -> Token
tokenAccessControlAllowCredentials
        Word8
_                                               -> ByteString -> Token
mkTokenMax ByteString
bs
    Int
_  -> ByteString -> Token
mkTokenMax ByteString
bs
  where
    len :: Int
len = ByteString -> Int
B.length ByteString
bs
    lst :: Word8
lst = ByteString -> Word8
B.last ByteString
bs
    PS ForeignPtr Word8
fp1 Int
off1 Int
siz === :: ByteString -> ByteString -> Bool
=== PS ForeignPtr Word8
fp2 Int
off2 Int
_ = IO Bool -> Bool
forall a. IO a -> a
unsafeDupablePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$
      ForeignPtr Word8 -> (Ptr Word8 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp1 ((Ptr Word8 -> IO Bool) -> IO Bool)
-> (Ptr Word8 -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p1 ->
      ForeignPtr Word8 -> (Ptr Word8 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp2 ((Ptr Word8 -> IO Bool) -> IO Bool)
-> (Ptr Word8 -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p2 -> do
        CInt
i <- Ptr Word8 -> Ptr Word8 -> Int -> IO CInt
memcmp (Ptr Word8
p1 Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off1) (Ptr Word8
p2 Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
off2) Int
siz
        Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ CInt
i CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0

mkTokenMax :: ByteString -> Token
mkTokenMax :: ByteString -> Token
mkTokenMax ByteString
bs = Int -> Bool -> Bool -> CI ByteString -> Token
Token Int
maxTokenIx Bool
True Bool
p (ByteString -> CI ByteString
forall s. FoldCase s => s -> CI s
mk ByteString
bs)
  where
    p :: Bool
p | ByteString -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Bool
False
      | ByteString -> Word8
B.head ByteString
bs Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
58  = Bool
True
      | Bool
otherwise        = Bool
False