{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK hide #-}

module Network.HTTP.Semantics.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 Data.CaseInsensitive (CI (..), mk, original)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (plusPtr)
import Network.HTTP.Types (HeaderName)
import System.IO.Unsafe (unsafeDupablePerformIO)

-- $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 -> HeaderName
tokenKey :: HeaderName
    -- ^ 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
$c== :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
/= :: 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
$cshowsPrec :: Int -> Token -> ShowS
showsPrec :: Int -> Token -> ShowS
$cshow :: Token -> String
show :: Token -> String
$cshowList :: [Token] -> ShowS
showList :: [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
_ HeaderName
ci) = HeaderName -> ByteString
forall s. CI s -> s
original HeaderName
ci

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

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

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

tokenMax :: Token
tokenMax                           = Int -> Bool -> Bool -> HeaderName -> Token
Token Int
73  Bool
True Bool
False HeaderName
"for other tokens"
{- FOURMOLU_ENABLE -}

-- | 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 -> HeaderName -> Token
Token Int
maxTokenIx Bool
True Bool
False HeaderName
""
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 = HasCallStack => ByteString -> Word8
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 a. a -> IO a
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 -> HeaderName -> Token
Token Int
maxTokenIx Bool
True Bool
p (ByteString -> HeaderName
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
        | HasCallStack => ByteString -> Word8
ByteString -> Word8
B.head ByteString
bs Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
58 = Bool
True
        | Bool
otherwise = Bool
False