{-# LANGUAGE BinaryLiterals #-}
module Network.QPACK.HeaderBlock.Decode where
import Control.Concurrent.STM
import qualified Control.Exception as E
import qualified Data.ByteString.Char8 as BS8
import Data.CaseInsensitive
import Network.ByteOrder
import Network.HPACK.Internal (
HuffmanDecoder,
decodeH,
decodeI,
decodeS,
decodeSimple,
decodeSophisticated,
entryToken,
entryTokenHeader,
)
import Network.HTTP.Types
import Imports
import Network.QPACK.Error
import Network.QPACK.HeaderBlock.Prefix
import Network.QPACK.Table
import Network.QPACK.Types
decodeTokenHeader
:: DynamicTable
-> ReadBuffer
-> IO (TokenHeaderTable, Bool)
DynamicTable
dyntbl ReadBuffer
rbuf = do
(RequiredInsertCount
reqInsertCount, BasePoint
bp, Bool
needAck) <- ReadBuffer
-> DynamicTable -> IO (RequiredInsertCount, BasePoint, Bool)
decodePrefix ReadBuffer
rbuf DynamicTable
dyntbl
Bool
ready <- DynamicTable -> RequiredInsertCount -> IO Bool
checkRequiredInsertCountNB DynamicTable
dyntbl RequiredInsertCount
reqInsertCount
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ready (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Bool
ok <- DynamicTable -> IO Bool
tryIncreaseStreams DynamicTable
dyntbl
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
ok (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ DecodeError -> IO ()
forall e a. Exception e => e -> IO a
E.throwIO DecodeError
BlockedStreamsOverflow
DynamicTable -> RequiredInsertCount -> IO ()
checkRequiredInsertCount DynamicTable
dyntbl RequiredInsertCount
reqInsertCount
DynamicTable -> IO ()
decreaseStreams DynamicTable
dyntbl
DynamicTable -> RequiredInsertCount -> IO ()
checkRequiredInsertCount DynamicTable
dyntbl RequiredInsertCount
reqInsertCount
let bufsiz :: Offset
bufsiz = Offset
2048
ForeignPtr Word8
gcbuf <- Offset -> IO (ForeignPtr Word8)
forall a. Offset -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes Offset
2048
let hufdec :: ReadBuffer -> Offset -> IO ByteString
hufdec = ForeignPtr Word8 -> Offset -> ReadBuffer -> Offset -> IO ByteString
decodeH ForeignPtr Word8
gcbuf Offset
bufsiz
TokenHeaderTable
tbl <- (Word8 -> ReadBuffer -> IO TokenHeader)
-> ReadBuffer -> IO TokenHeaderTable
decodeSophisticated (DynamicTable
-> BasePoint
-> (ReadBuffer -> Offset -> IO ByteString)
-> Word8
-> ReadBuffer
-> IO TokenHeader
toTokenHeader DynamicTable
dyntbl BasePoint
bp ReadBuffer -> Offset -> IO ByteString
hufdec) ReadBuffer
rbuf
(TokenHeaderTable, Bool) -> IO (TokenHeaderTable, Bool)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (TokenHeaderTable
tbl, Bool
needAck)
decodeTokenHeaderS
:: DynamicTable
-> ReadBuffer
-> IO (Maybe ([Header], Bool))
DynamicTable
dyntbl ReadBuffer
rbuf = do
(RequiredInsertCount
reqInsertCount, BasePoint
bp, Bool
needAck) <- ReadBuffer
-> DynamicTable -> IO (RequiredInsertCount, BasePoint, Bool)
decodePrefix ReadBuffer
rbuf DynamicTable
dyntbl
Bool
ok <- DynamicTable -> RequiredInsertCount -> IO Bool
checkRequiredInsertCountNB DynamicTable
dyntbl RequiredInsertCount
reqInsertCount
if Bool
ok
then do
let bufsiz :: Offset
bufsiz = Offset
2048
ForeignPtr Word8
gcbuf <- Offset -> IO (ForeignPtr Word8)
forall a. Offset -> IO (ForeignPtr a)
mallocPlainForeignPtrBytes Offset
2048
let hufdec :: ReadBuffer -> Offset -> IO ByteString
hufdec = ForeignPtr Word8 -> Offset -> ReadBuffer -> Offset -> IO ByteString
decodeH ForeignPtr Word8
gcbuf Offset
bufsiz
[Header]
hs <- (Word8 -> ReadBuffer -> IO TokenHeader)
-> ReadBuffer -> IO [Header]
decodeSimple (DynamicTable
-> BasePoint
-> (ReadBuffer -> Offset -> IO ByteString)
-> Word8
-> ReadBuffer
-> IO TokenHeader
toTokenHeader DynamicTable
dyntbl BasePoint
bp ReadBuffer -> Offset -> IO ByteString
hufdec) ReadBuffer
rbuf
Maybe ([Header], Bool) -> IO (Maybe ([Header], Bool))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ([Header], Bool) -> IO (Maybe ([Header], Bool)))
-> Maybe ([Header], Bool) -> IO (Maybe ([Header], Bool))
forall a b. (a -> b) -> a -> b
$ ([Header], Bool) -> Maybe ([Header], Bool)
forall a. a -> Maybe a
Just ([Header]
hs, Bool
needAck)
else Maybe ([Header], Bool) -> IO (Maybe ([Header], Bool))
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ([Header], Bool)
forall a. Maybe a
Nothing
toTokenHeader
:: DynamicTable
-> BasePoint
-> HuffmanDecoder
-> Word8
-> ReadBuffer
-> IO TokenHeader
DynamicTable
dyntbl BasePoint
bp ReadBuffer -> Offset -> IO ByteString
hufdec Word8
w8 ReadBuffer
rbuf
| Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
7 =
ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLine ReadBuffer
rbuf DynamicTable
dyntbl BasePoint
bp Word8
w8
| Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
6 =
ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithNameReference ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
bp Word8
w8
| Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
5 =
ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithLiteralName ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
bp Word8
w8
| Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
4 =
ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLineWithPostBaseIndex ReadBuffer
rbuf DynamicTable
dyntbl BasePoint
bp Word8
w8
| Bool
otherwise =
ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithPostBaseNameReference ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
bp Word8
w8
decodeIndexedFieldLine
:: ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLine :: ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLine ReadBuffer
rbuf DynamicTable
dyntbl BasePoint
bp Word8
w8 = do
Offset
i <- Offset -> Word8 -> ReadBuffer -> IO Offset
decodeI Offset
6 (Word8
w8 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b00111111) ReadBuffer
rbuf
let static :: Bool
static = Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
6
hidx :: HIndex
hidx
| Bool
static = AbsoluteIndex -> HIndex
SIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ Offset -> AbsoluteIndex
AbsoluteIndex Offset
i
| Bool
otherwise = AbsoluteIndex -> HIndex
DIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ PreBaseIndex -> BasePoint -> AbsoluteIndex
fromPreBaseIndex (Offset -> PreBaseIndex
PreBaseIndex Offset
i) BasePoint
bp
TokenHeader
ret <- STM TokenHeader -> IO TokenHeader
forall a. STM a -> IO a
atomically (Entry -> TokenHeader
entryTokenHeader (Entry -> TokenHeader) -> STM Entry -> STM TokenHeader
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynamicTable -> HIndex -> STM Entry
toIndexedEntry DynamicTable
dyntbl HIndex
hidx)
DynamicTable -> IO () -> IO ()
qpackDebug DynamicTable
dyntbl (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
DynamicTable -> HIndex -> IO ()
checkHIndex DynamicTable
dyntbl HIndex
hidx
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"IndexedFieldLine (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ HIndex -> String
forall a. Show a => a -> String
show HIndex
hidx String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenHeader -> String
showTokenHeader TokenHeader
ret
TokenHeader -> IO TokenHeader
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TokenHeader
ret
decodeIndexedFieldLineWithPostBaseIndex
:: ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLineWithPostBaseIndex :: ReadBuffer -> DynamicTable -> BasePoint -> Word8 -> IO TokenHeader
decodeIndexedFieldLineWithPostBaseIndex ReadBuffer
rbuf DynamicTable
dyntbl BasePoint
bp Word8
w8 = do
Offset
i <- Offset -> Word8 -> ReadBuffer -> IO Offset
decodeI Offset
4 (Word8
w8 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b00001111) ReadBuffer
rbuf
let hidx :: HIndex
hidx = AbsoluteIndex -> HIndex
DIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ PostBaseIndex -> BasePoint -> AbsoluteIndex
fromPostBaseIndex (Offset -> PostBaseIndex
PostBaseIndex Offset
i) BasePoint
bp
TokenHeader
ret <- STM TokenHeader -> IO TokenHeader
forall a. STM a -> IO a
atomically (Entry -> TokenHeader
entryTokenHeader (Entry -> TokenHeader) -> STM Entry -> STM TokenHeader
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynamicTable -> HIndex -> STM Entry
toIndexedEntry DynamicTable
dyntbl HIndex
hidx)
DynamicTable -> IO () -> IO ()
qpackDebug DynamicTable
dyntbl (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
DynamicTable -> HIndex -> IO ()
checkHIndex DynamicTable
dyntbl HIndex
hidx
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"IndexedFieldLineWithPostBaseIndex ("
String -> String -> String
forall a. [a] -> [a] -> [a]
++ HIndex -> String
forall a. Show a => a -> String
show HIndex
hidx
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ BasePoint -> String
forall a. Show a => a -> String
show BasePoint
bp
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" after "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Offset -> String
forall a. Show a => a -> String
show Offset
i
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenHeader -> String
showTokenHeader TokenHeader
ret
TokenHeader -> IO TokenHeader
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TokenHeader
ret
decodeLiteralFieldLineWithNameReference
:: ReadBuffer
-> DynamicTable
-> HuffmanDecoder
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithNameReference :: ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithNameReference ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
bp Word8
w8 = do
Offset
i <- Offset -> Word8 -> ReadBuffer -> IO Offset
decodeI Offset
4 (Word8
w8 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b00001111) ReadBuffer
rbuf
let static :: Bool
static = Word8
w8 Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
4
hidx :: HIndex
hidx
| Bool
static = AbsoluteIndex -> HIndex
SIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ Offset -> AbsoluteIndex
AbsoluteIndex Offset
i
| Bool
otherwise = AbsoluteIndex -> HIndex
DIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ PreBaseIndex -> BasePoint -> AbsoluteIndex
fromPreBaseIndex (Offset -> PreBaseIndex
PreBaseIndex Offset
i) BasePoint
bp
Token
key <- STM Token -> IO Token
forall a. STM a -> IO a
atomically (Entry -> Token
entryToken (Entry -> Token) -> STM Entry -> STM Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynamicTable -> HIndex -> STM Entry
toIndexedEntry DynamicTable
dyntbl HIndex
hidx)
ByteString
val <- (Word8 -> Word8)
-> (Word8 -> Bool)
-> Offset
-> (ReadBuffer -> Offset -> IO ByteString)
-> ReadBuffer
-> IO ByteString
decodeS (Word8 -> Offset -> Word8
forall a. Bits a => a -> Offset -> a
`clearBit` Offset
7) (Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
7) Offset
7 ReadBuffer -> Offset -> IO ByteString
hufdec ReadBuffer
rbuf
let ret :: TokenHeader
ret = (Token
key, ByteString
val)
DynamicTable -> IO () -> IO ()
qpackDebug DynamicTable
dyntbl (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
DynamicTable -> HIndex -> IO ()
checkHIndex DynamicTable
dyntbl HIndex
hidx
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"LiteralFieldLineWithNameReference ("
String -> String -> String
forall a. [a] -> [a] -> [a]
++ HIndex -> String
forall a. Show a => a -> String
show HIndex
hidx
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenHeader -> String
showTokenHeader TokenHeader
ret
TokenHeader -> IO TokenHeader
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TokenHeader
ret
decodeLiteralFieldLineWithPostBaseNameReference
:: ReadBuffer
-> DynamicTable
-> HuffmanDecoder
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithPostBaseNameReference :: ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithPostBaseNameReference ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
bp Word8
w8 = do
Offset
i <- Offset -> Word8 -> ReadBuffer -> IO Offset
decodeI Offset
3 (Word8
w8 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b00000111) ReadBuffer
rbuf
let hidx :: HIndex
hidx = AbsoluteIndex -> HIndex
DIndex (AbsoluteIndex -> HIndex) -> AbsoluteIndex -> HIndex
forall a b. (a -> b) -> a -> b
$ PostBaseIndex -> BasePoint -> AbsoluteIndex
fromPostBaseIndex (Offset -> PostBaseIndex
PostBaseIndex Offset
i) BasePoint
bp
Token
key <- STM Token -> IO Token
forall a. STM a -> IO a
atomically (Entry -> Token
entryToken (Entry -> Token) -> STM Entry -> STM Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DynamicTable -> HIndex -> STM Entry
toIndexedEntry DynamicTable
dyntbl HIndex
hidx)
ByteString
val <- (Word8 -> Word8)
-> (Word8 -> Bool)
-> Offset
-> (ReadBuffer -> Offset -> IO ByteString)
-> ReadBuffer
-> IO ByteString
decodeS (Word8 -> Offset -> Word8
forall a. Bits a => a -> Offset -> a
`clearBit` Offset
7) (Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
7) Offset
7 ReadBuffer -> Offset -> IO ByteString
hufdec ReadBuffer
rbuf
let ret :: TokenHeader
ret = (Token
key, ByteString
val)
DynamicTable -> IO () -> IO ()
qpackDebug DynamicTable
dyntbl (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
DynamicTable -> HIndex -> IO ()
checkHIndex DynamicTable
dyntbl HIndex
hidx
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"LiteralFieldLineWithPostBaseNameReference ("
String -> String -> String
forall a. [a] -> [a] -> [a]
++ HIndex -> String
forall a. Show a => a -> String
show HIndex
hidx
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
") "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenHeader -> String
showTokenHeader TokenHeader
ret
TokenHeader -> IO TokenHeader
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TokenHeader
ret
decodeLiteralFieldLineWithLiteralName
:: ReadBuffer
-> DynamicTable
-> HuffmanDecoder
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithLiteralName :: ReadBuffer
-> DynamicTable
-> (ReadBuffer -> Offset -> IO ByteString)
-> BasePoint
-> Word8
-> IO TokenHeader
decodeLiteralFieldLineWithLiteralName ReadBuffer
rbuf DynamicTable
dyntbl ReadBuffer -> Offset -> IO ByteString
hufdec BasePoint
_bp Word8
_w8 = do
ReadBuffer -> Offset -> IO ()
forall a. Readable a => a -> Offset -> IO ()
ff ReadBuffer
rbuf (-Offset
1)
Token
key <- ByteString -> Token
toToken (ByteString -> Token) -> IO ByteString -> IO Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Word8 -> Word8)
-> (Word8 -> Bool)
-> Offset
-> (ReadBuffer -> Offset -> IO ByteString)
-> ReadBuffer
-> IO ByteString
decodeS (Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0b00000111) (Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
3) Offset
3 ReadBuffer -> Offset -> IO ByteString
hufdec ReadBuffer
rbuf
ByteString
val <- (Word8 -> Word8)
-> (Word8 -> Bool)
-> Offset
-> (ReadBuffer -> Offset -> IO ByteString)
-> ReadBuffer
-> IO ByteString
decodeS (Word8 -> Offset -> Word8
forall a. Bits a => a -> Offset -> a
`clearBit` Offset
7) (Word8 -> Offset -> Bool
forall a. Bits a => a -> Offset -> Bool
`testBit` Offset
7) Offset
7 ReadBuffer -> Offset -> IO ByteString
hufdec ReadBuffer
rbuf
let ret :: TokenHeader
ret = (Token
key, ByteString
val)
DynamicTable -> IO () -> IO ()
qpackDebug DynamicTable
dyntbl (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"LiteralFieldLineWithLiteralName " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TokenHeader -> String
showTokenHeader TokenHeader
ret
TokenHeader -> IO TokenHeader
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return TokenHeader
ret
showTokenHeader :: TokenHeader -> String
(Token
t, ByteString
val) = String
"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
key String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\" \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ ByteString -> String
BS8.unpack ByteString
val String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""
where
key :: String
key = ByteString -> String
BS8.unpack (ByteString -> String) -> ByteString -> String
forall a b. (a -> b) -> a -> b
$ CI ByteString -> ByteString
forall s. CI s -> s
foldedCase (CI ByteString -> ByteString) -> CI ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Token -> CI ByteString
tokenKey Token
t