{-# LANGUAGE OverloadedStrings, BangPatterns #-}

module Network.HPACK.Token (
  -- * Data type
    Token(..)
  , tokenIx
  , 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
  ) 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
ix :: !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 an index from a token.
{-# INLINE tokenIx #-}
tokenIx :: Token -> Int
tokenIx :: Token -> Int
tokenIx (Token n :: Int
n _ _ _) = Int
n

-- | Extracting a case insensitive header key from a token.
{-# INLINE tokenCIKey #-}
tokenCIKey :: Token -> ByteString
tokenCIKey :: Token -> ByteString
tokenCIKey (Token _ _ _ ci :: 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 _ _ _ ci :: 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 -- Original
tokenTE                       :: Token -- Original
tokenMax                      :: Token -- Other tokens

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

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

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

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

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

-- | Is this token ix for Cookie?
{-# INLINE isCookieTokenIx #-}
isCookieTokenIx :: Int -> Bool
isCookieTokenIx :: Int -> Bool
isCookieTokenIx n :: 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 n :: 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 n :: 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 n :: 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 {ix = 54, shouldBeIndexed = True, isPseudo = False, tokenKey = "foo"}
-- >>> toToken ":bar"
-- Token {ix = 54, shouldBeIndexed = True, isPseudo = True, tokenKey = ":bar"}
toToken :: ByteString -> Token
toToken :: ByteString -> Token
toToken bs :: ByteString
bs = case Int
len of
    2 -> if ByteString
bs ByteString -> ByteString -> Bool
=== "te" then Token
tokenTE else ByteString -> Token
mkTokenMax ByteString
bs
    3 -> case Word8
lst of
        97  | ByteString
bs ByteString -> ByteString -> Bool
=== "via" -> Token
tokenVia
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "age" -> Token
tokenAge
        _                  -> ByteString -> Token
mkTokenMax ByteString
bs
    4 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "date" -> Token
tokenDate
        103 | ByteString
bs ByteString -> ByteString -> Bool
=== "etag" -> Token
tokenEtag
        107 | ByteString
bs ByteString -> ByteString -> Bool
=== "link" -> Token
tokenLink
        109 | ByteString
bs ByteString -> ByteString -> Bool
=== "from" -> Token
tokenFrom
        116 | ByteString
bs ByteString -> ByteString -> Bool
=== "host" -> Token
tokenHost
        121 | ByteString
bs ByteString -> ByteString -> Bool
=== "vary" -> Token
tokenVary
        _                   -> ByteString -> Token
mkTokenMax ByteString
bs
    5 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "range" -> Token
tokenRange
        104 | ByteString
bs ByteString -> ByteString -> Bool
=== ":path" -> Token
tokenPath
        119 | ByteString
bs ByteString -> ByteString -> Bool
=== "allow" -> Token
tokenAllow
        _                    -> ByteString -> Token
mkTokenMax ByteString
bs
    6 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "cookie" -> Token
tokenCookie
        114 | ByteString
bs ByteString -> ByteString -> Bool
=== "server" -> Token
tokenServer
        116 | ByteString
bs ByteString -> ByteString -> Bool
=== "expect" -> Token
tokenExpect
            | ByteString
bs ByteString -> ByteString -> Bool
=== "accept" -> Token
tokenAccept
        _                     -> ByteString -> Token
mkTokenMax ByteString
bs
    7 -> case Word8
lst of
        100 | ByteString
bs ByteString -> ByteString -> Bool
=== ":method" -> Token
tokenMethod
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== ":scheme" -> Token
tokenScheme
        104 | ByteString
bs ByteString -> ByteString -> Bool
=== "refresh" -> Token
tokenRefresh
        114 | ByteString
bs ByteString -> ByteString -> Bool
=== "referer" -> Token
tokenReferer
        115 | ByteString
bs ByteString -> ByteString -> Bool
=== "expires" -> Token
tokenExpires
            | ByteString
bs ByteString -> ByteString -> Bool
=== ":status" -> Token
tokenStatus
        _                      -> ByteString -> Token
mkTokenMax ByteString
bs
    8 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "if-range" -> Token
tokenIfRange
        104 | ByteString
bs ByteString -> ByteString -> Bool
=== "if-match" -> Token
tokenIfMatch
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "location" -> Token
tokenLocation
        _                       -> ByteString -> Token
mkTokenMax ByteString
bs
    10 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "set-cookie" -> Token
tokenSetCookie
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "connection" -> Token
tokenConnection
        116 | ByteString
bs ByteString -> ByteString -> Bool
=== "user-agent" -> Token
tokenUserAgent
        121 | ByteString
bs ByteString -> ByteString -> Bool
=== ":authority" -> Token
tokenAuthority
        _                         -> ByteString -> Token
mkTokenMax ByteString
bs
    11 -> case Word8
lst of
        114 | ByteString
bs ByteString -> ByteString -> Bool
=== "retry-after" -> Token
tokenRetryAfter
        _                          -> ByteString -> Token
mkTokenMax ByteString
bs
    12 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-type" -> Token
tokenContentType
        115 | ByteString
bs ByteString -> ByteString -> Bool
=== "max-forwards" -> Token
tokenMaxForwards
        _                           -> ByteString -> Token
mkTokenMax ByteString
bs
    13 -> case Word8
lst of
        100 | ByteString
bs ByteString -> ByteString -> Bool
=== "last-modified" -> Token
tokenLastModified
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-range" -> Token
tokenContentRange
        104 | ByteString
bs ByteString -> ByteString -> Bool
=== "if-none-match" -> Token
tokenIfNoneMatch
        108 | ByteString
bs ByteString -> ByteString -> Bool
=== "cache-control" -> Token
tokenCacheControl
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "authorization" -> Token
tokenAuthorization
        115 | ByteString
bs ByteString -> ByteString -> Bool
=== "accept-ranges" -> Token
tokenAcceptRanges
        _                            -> ByteString -> Token
mkTokenMax ByteString
bs
    14 -> case Word8
lst of
        104 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-length" -> Token
tokenContentLength
        116 | ByteString
bs ByteString -> ByteString -> Bool
=== "accept-charset" -> Token
tokenAcceptCharset
        _                             -> ByteString -> Token
mkTokenMax ByteString
bs
    15 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "accept-language" -> Token
tokenAcceptLanguage
        103 | ByteString
bs ByteString -> ByteString -> Bool
=== "accept-encoding" -> Token
tokenAcceptEncoding
        _                              -> ByteString -> Token
mkTokenMax ByteString
bs
    16 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-language" -> Token
tokenContentLanguage
            | ByteString
bs ByteString -> ByteString -> Bool
=== "www-authenticate" -> Token
tokenWwwAuthenticate
        103 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-encoding" -> Token
tokenContentEncoding
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "content-location" -> Token
tokenContentLocation
        _                               -> ByteString -> Token
mkTokenMax ByteString
bs
    17 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "if-modified-since" -> Token
tokenIfModifiedSince
        103 | ByteString
bs ByteString -> ByteString -> Bool
=== "transfer-encoding" -> Token
tokenTransferEncoding
        _                                -> ByteString -> Token
mkTokenMax ByteString
bs
    18 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "proxy-authenticate" -> Token
tokenProxyAuthenticate
        _                                 -> ByteString -> Token
mkTokenMax ByteString
bs
    19 -> case Word8
lst of
        101 | ByteString
bs ByteString -> ByteString -> Bool
=== "if-unmodified-since" -> Token
tokenIfUnmodifiedSince
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "proxy-authorization" -> Token
tokenProxyAuthorization
            | ByteString
bs ByteString -> ByteString -> Bool
=== "content-disposition" -> Token
tokenContentDisposition
        _                                  -> ByteString -> Token
mkTokenMax ByteString
bs
    25 -> case Word8
lst of
        121 | ByteString
bs ByteString -> ByteString -> Bool
=== "strict-transport-security" -> Token
tokenStrictTransportSecurity
        _                                        -> ByteString -> Token
mkTokenMax ByteString
bs
    27 -> case Word8
lst of
        110 | ByteString
bs ByteString -> ByteString -> Bool
=== "access-control-allow-origin" -> Token
tokenAccessControlAllowOrigin
        _                                          -> ByteString -> Token
mkTokenMax ByteString
bs
    _  -> 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 fp1 :: ForeignPtr Word8
fp1 off1 :: Int
off1 siz :: Int
siz === :: ByteString -> ByteString -> Bool
=== PS fp2 :: ForeignPtr Word8
fp2 off2 :: Int
off2 _ = 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
$ \p1 :: 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
$ \p2 :: 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
== 0

mkTokenMax :: ByteString -> Token
mkTokenMax :: ByteString -> Token
mkTokenMax bs :: 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
== 0 = Bool
False
       | ByteString -> Word8
B.head ByteString
bs Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 58  = Bool
True
       | Bool
otherwise        = Bool
False