-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | HTTP/2 library including frames, priority queues and HPACK
--   
--   HTTP/2 library including frames, priority queues and HPACK.
@package http2
@version 1.6.3


-- | This is partial implementation of the priority of HTTP/2.
--   
--   This implementation does support structured priority queue but not
--   support re-structuring. This means that it is assumed that an entry
--   created by a Priority frame is never closed. The entry behaves an
--   intermediate node, not a leaf.
--   
--   This queue is fair for weight. Consider two weights: 201 and 101.
--   Repeating enqueue/dequeue probably produces 201, 201, 101, 201, 201,
--   101, ...
--   
--   Only one entry per stream should be enqueued.
module Network.HTTP2.Priority

-- | Internal representation of priority in priority queues. The precedence
--   of a dequeued entry should be specified to <a>enqueue</a> when the
--   entry is enqueued again.
data Precedence

-- | Default precedence.
defaultPrecedence :: Precedence

-- | Converting <a>Priority</a> to <a>Precedence</a>. When an entry is
--   enqueued at the first time, this function should be used.
toPrecedence :: Priority -> Precedence

-- | Abstract data type for priority trees.
data PriorityTree a

-- | Creating a new priority tree.
newPriorityTree :: IO (PriorityTree a)

-- | Bringing up the structure of the priority tree. This must be used for
--   Priority frame.
prepare :: PriorityTree a -> StreamId -> Priority -> IO ()

-- | Enqueuing an entry to the priority tree. This must be used for Header
--   frame.
enqueue :: PriorityTree a -> StreamId -> Precedence -> a -> IO ()

-- | Dequeuing an entry from the priority tree.
dequeue :: PriorityTree a -> IO (StreamId, Precedence, a)

-- | Dequeuing an entry from the priority tree.
dequeueSTM :: PriorityTree a -> STM (StreamId, Precedence, a)

-- | Checking if the priority tree is empty.
isEmpty :: PriorityTree a -> IO Bool

-- | Checking if the priority tree is empty.
isEmptySTM :: PriorityTree a -> STM Bool

-- | Deleting the entry corresponding to <a>StreamId</a>. <a>delete</a> and
--   <a>enqueue</a> are used to change the priority of a live stream.
delete :: PriorityTree a -> StreamId -> Precedence -> IO (Maybe a)


-- | Framing in HTTP/2(<a>https://tools.ietf.org/html/rfc7540</a>).
module Network.HTTP2

-- | The data type for HTTP/2 frames.
data Frame
Frame :: !FrameHeader -> !FramePayload -> Frame
[frameHeader] :: Frame -> !FrameHeader
[framePayload] :: Frame -> !FramePayload

-- | The data type for HTTP/2 frame headers.
data FrameHeader
FrameHeader :: !Int -> !FrameFlags -> !StreamId -> FrameHeader
[payloadLength] :: FrameHeader -> !Int
[flags] :: FrameHeader -> !FrameFlags
[streamId] :: FrameHeader -> !StreamId

-- | The data type for HTTP/2 frame payloads.
data FramePayload
DataFrame :: !ByteString -> FramePayload
HeadersFrame :: !(Maybe Priority) -> !HeaderBlockFragment -> FramePayload
PriorityFrame :: !Priority -> FramePayload
RSTStreamFrame :: !ErrorCodeId -> FramePayload
SettingsFrame :: !SettingsList -> FramePayload
PushPromiseFrame :: !StreamId -> !HeaderBlockFragment -> FramePayload
PingFrame :: !ByteString -> FramePayload
GoAwayFrame :: !StreamId -> !ErrorCodeId -> !ByteString -> FramePayload
WindowUpdateFrame :: !WindowSize -> FramePayload
ContinuationFrame :: !HeaderBlockFragment -> FramePayload
UnknownFrame :: !FrameType -> !ByteString -> FramePayload

-- | The type for fragments of a header encoded with HPACK.
type HeaderBlockFragment = ByteString

-- | The type for padding in payloads.
type Padding = ByteString

-- | Checking if padding is defined in this frame type.
--   
--   <pre>
--   &gt;&gt;&gt; isPaddingDefined $ DataFrame ""
--   True
--   
--   &gt;&gt;&gt; isPaddingDefined $ PingFrame ""
--   False
--   </pre>
isPaddingDefined :: FramePayload -> Bool

-- | Encoding an HTTP/2 frame to <a>ByteString</a>. This function is not
--   efficient enough for high performace program because of the
--   concatenation of <a>ByteString</a>.
--   
--   <pre>
--   &gt;&gt;&gt; encodeFrame (encodeInfo id 1) (DataFrame "body")
--   "\NUL\NUL\EOT\NUL\NUL\NUL\NUL\NUL\SOHbody"
--   </pre>
encodeFrame :: EncodeInfo -> FramePayload -> ByteString

-- | Encoding an HTTP/2 frame to [<a>ByteString</a>]. This is suitable for
--   sendMany.
encodeFrameChunks :: EncodeInfo -> FramePayload -> [ByteString]

-- | Encoding an HTTP/2 frame header. The frame header must be completed.
encodeFrameHeader :: FrameTypeId -> FrameHeader -> ByteString

-- | Writing an encoded HTTP/2 frame header to the buffer. The length of
--   the buffer must be larger than or equal to 9 bytes.
encodeFrameHeaderBuf :: FrameTypeId -> FrameHeader -> Ptr Word8 -> IO ()

-- | Encoding an HTTP/2 frame payload. This returns a complete frame header
--   and chunks of payload.
encodeFramePayload :: EncodeInfo -> FramePayload -> (FrameHeader, [ByteString])

-- | Auxiliary information for frame encoding.
data EncodeInfo
EncodeInfo :: !FrameFlags -> !StreamId -> !(Maybe Padding) -> EncodeInfo

-- | Flags to be set in a frame header
[encodeFlags] :: EncodeInfo -> !FrameFlags

-- | Stream id to be set in a frame header
[encodeStreamId] :: EncodeInfo -> !StreamId

-- | Padding if any. In the case where this value is set but the priority
--   flag is not set, this value gets preference over the priority flag.
--   So, if this value is set, the priority flag is also set.
[encodePadding] :: EncodeInfo -> !(Maybe Padding)

-- | A smart builder of <a>EncodeInfo</a>.
--   
--   <pre>
--   &gt;&gt;&gt; encodeInfo setAck 0
--   EncodeInfo {encodeFlags = 1, encodeStreamId = 0, encodePadding = Nothing}
--   </pre>
encodeInfo :: (FrameFlags -> FrameFlags) -> Int -> EncodeInfo

-- | Decoding an HTTP/2 frame to <a>ByteString</a>. The second argument
--   must be include the entire of frame. So, this function is not useful
--   for real applications but useful for testing.
decodeFrame :: Settings -> ByteString -> Either HTTP2Error Frame

-- | Decoding an HTTP/2 frame header. Must supply 9 bytes.
decodeFrameHeader :: ByteString -> (FrameTypeId, FrameHeader)

-- | Checking a frame header and reporting an error if any.
--   
--   <pre>
--   &gt;&gt;&gt; checkFrameHeader defaultSettings (FrameData,(FrameHeader 100 0 0))
--   Left (ConnectionError ProtocolError "cannot used in control stream")
--   </pre>
checkFrameHeader :: Settings -> (FrameTypeId, FrameHeader) -> Either HTTP2Error (FrameTypeId, FrameHeader)

-- | Decoding an HTTP/2 frame payload. This function is considered to
--   return a frame payload decoder according to a frame type.
decodeFramePayload :: FrameTypeId -> FramePayloadDecoder

-- | The type for frame payload decoder.
type FramePayloadDecoder = FrameHeader -> ByteString -> Either HTTP2Error FramePayload

-- | Frame payload decoder for DATA frame.
decodeDataFrame :: FramePayloadDecoder

-- | Frame payload decoder for HEADERS frame.
decodeHeadersFrame :: FramePayloadDecoder

-- | Frame payload decoder for PRIORITY frame.
decodePriorityFrame :: FramePayloadDecoder

-- | Frame payload decoder for RST_STREAM frame.
decoderstStreamFrame :: FramePayloadDecoder

-- | Frame payload decoder for SETTINGS frame.
decodeSettingsFrame :: FramePayloadDecoder

-- | Frame payload decoder for PUSH_PROMISE frame.
decodePushPromiseFrame :: FramePayloadDecoder

-- | Frame payload decoder for PING frame.
decodePingFrame :: FramePayloadDecoder

-- | Frame payload decoder for GOAWAY frame.
decodeGoAwayFrame :: FramePayloadDecoder

-- | Frame payload decoder for WINDOW_UPDATE frame.
decodeWindowUpdateFrame :: FramePayloadDecoder

-- | Frame payload decoder for CONTINUATION frame.
decodeContinuationFrame :: FramePayloadDecoder

-- | The type for frame type.
data FrameTypeId
FrameData :: FrameTypeId
FrameHeaders :: FrameTypeId
FramePriority :: FrameTypeId
FrameRSTStream :: FrameTypeId
FrameSettings :: FrameTypeId
FramePushPromise :: FrameTypeId
FramePing :: FrameTypeId
FrameGoAway :: FrameTypeId
FrameWindowUpdate :: FrameTypeId
FrameContinuation :: FrameTypeId
FrameUnknown :: FrameType -> FrameTypeId

-- | Getting <a>FrameType</a> from <a>FramePayload</a>.
--   
--   <pre>
--   &gt;&gt;&gt; framePayloadToFrameTypeId (DataFrame "body")
--   FrameData
--   </pre>
framePayloadToFrameTypeId :: FramePayload -> FrameTypeId

-- | The type for raw frame type.
type FrameType = Word8

-- | Converting <a>FrameTypeId</a> to <a>FrameType</a>.
--   
--   <pre>
--   &gt;&gt;&gt; fromFrameTypeId FrameData
--   0
--   
--   &gt;&gt;&gt; fromFrameTypeId FrameContinuation
--   9
--   
--   &gt;&gt;&gt; fromFrameTypeId (FrameUnknown 10)
--   10
--   </pre>
fromFrameTypeId :: FrameTypeId -> FrameType

-- | Converting <a>FrameType</a> to <a>FrameTypeId</a>.
--   
--   <pre>
--   &gt;&gt;&gt; toFrameTypeId 0
--   FrameData
--   
--   &gt;&gt;&gt; toFrameTypeId 9
--   FrameContinuation
--   
--   &gt;&gt;&gt; toFrameTypeId 10
--   FrameUnknown 10
--   </pre>
toFrameTypeId :: FrameType -> FrameTypeId

-- | Type for stream priority
data Priority
Priority :: !Bool -> !StreamId -> !Weight -> Priority
[exclusive] :: Priority -> !Bool
[streamDependency] :: Priority -> !StreamId
[weight] :: Priority -> !Weight

-- | The type for weight in priority. Its values are from 1 to 256.
type Weight = Int

-- | Default priority which depends on stream 0.
--   
--   <pre>
--   &gt;&gt;&gt; defaultPriority
--   Priority {exclusive = False, streamDependency = 0, weight = 16}
--   </pre>
defaultPriority :: Priority

-- | Highest priority which depends on stream 0.
--   
--   <pre>
--   &gt;&gt;&gt; highestPriority
--   Priority {exclusive = False, streamDependency = 0, weight = 256}
--   </pre>
highestPriority :: Priority

-- | The type for stream identifier
type StreamId = Int

-- | Checking if the stream identifier for control.
--   
--   <pre>
--   &gt;&gt;&gt; isControl 0
--   True
--   
--   &gt;&gt;&gt; isControl 1
--   False
--   </pre>
isControl :: StreamId -> Bool

-- | Checking if the stream identifier for request.
--   
--   <pre>
--   &gt;&gt;&gt; isRequest 0
--   False
--   
--   &gt;&gt;&gt; isRequest 1
--   True
--   </pre>
isRequest :: StreamId -> Bool

-- | Checking if the stream identifier for response.
--   
--   <pre>
--   &gt;&gt;&gt; isResponse 0
--   False
--   
--   &gt;&gt;&gt; isResponse 2
--   True
--   </pre>
isResponse :: StreamId -> Bool

-- | Checking if the exclusive flag is set.
testExclusive :: StreamId -> Bool

-- | Setting the exclusive flag.
setExclusive :: StreamId -> StreamId

-- | Clearing the exclusive flag.
clearExclusive :: StreamId -> StreamId

-- | The type for flags.
type FrameFlags = Word8

-- | The initial value of flags. No flags are set.
--   
--   <pre>
--   &gt;&gt;&gt; defaultFlags
--   0
--   </pre>
defaultFlags :: FrameFlags

-- | Checking if the END_STREAM flag is set. &gt;&gt;&gt; testEndStream 0x1
--   True
testEndStream :: FrameFlags -> Bool

-- | Checking if the ACK flag is set. &gt;&gt;&gt; testAck 0x1 True
testAck :: FrameFlags -> Bool

-- | Checking if the END_HEADERS flag is set.
--   
--   <pre>
--   &gt;&gt;&gt; testEndHeader 0x4
--   True
--   </pre>
testEndHeader :: FrameFlags -> Bool

-- | Checking if the PADDED flag is set.
--   
--   <pre>
--   &gt;&gt;&gt; testPadded 0x8
--   True
--   </pre>
testPadded :: FrameFlags -> Bool

-- | Checking if the PRIORITY flag is set.
--   
--   <pre>
--   &gt;&gt;&gt; testPriority 0x20
--   True
--   </pre>
testPriority :: FrameFlags -> Bool

-- | Setting the END_STREAM flag.
--   
--   <pre>
--   &gt;&gt;&gt; setEndStream 0
--   1
--   </pre>
setEndStream :: FrameFlags -> FrameFlags

-- | Setting the ACK flag.
--   
--   <pre>
--   &gt;&gt;&gt; setAck 0
--   1
--   </pre>
setAck :: FrameFlags -> FrameFlags

-- | Setting the END_HEADERS flag.
--   
--   <pre>
--   &gt;&gt;&gt; setEndHeader 0
--   4
--   </pre>
setEndHeader :: FrameFlags -> FrameFlags

-- | Setting the PADDED flag.
--   
--   <pre>
--   &gt;&gt;&gt; setPadded 0
--   8
--   </pre>
setPadded :: FrameFlags -> FrameFlags

-- | Setting the PRIORITY flag.
--   
--   <pre>
--   &gt;&gt;&gt; setPriority 0
--   32
--   </pre>
setPriority :: FrameFlags -> FrameFlags

-- | Association list of SETTINGS.
type SettingsList = [(SettingsKeyId, SettingsValue)]

-- | The type for SETTINGS key.
data SettingsKeyId
SettingsHeaderTableSize :: SettingsKeyId
SettingsEnablePush :: SettingsKeyId
SettingsMaxConcurrentStreams :: SettingsKeyId
SettingsInitialWindowSize :: SettingsKeyId
SettingsMaxFrameSize :: SettingsKeyId
SettingsMaxHeaderBlockSize :: SettingsKeyId

-- | The type for raw SETTINGS value.
type SettingsValue = Int

-- | Converting <a>SettingsKeyId</a> to raw value.
--   
--   <pre>
--   &gt;&gt;&gt; fromSettingsKeyId SettingsHeaderTableSize
--   1
--   
--   &gt;&gt;&gt; fromSettingsKeyId SettingsMaxHeaderBlockSize
--   6
--   </pre>
fromSettingsKeyId :: SettingsKeyId -> Word16

-- | Converting raw value to <a>SettingsKeyId</a>.
--   
--   <pre>
--   &gt;&gt;&gt; toSettingsKeyId 0
--   Nothing
--   
--   &gt;&gt;&gt; toSettingsKeyId 1
--   Just SettingsHeaderTableSize
--   
--   &gt;&gt;&gt; toSettingsKeyId 6
--   Just SettingsMaxHeaderBlockSize
--   
--   &gt;&gt;&gt; toSettingsKeyId 7
--   Nothing
--   </pre>
toSettingsKeyId :: Word16 -> Maybe SettingsKeyId

-- | Checking <a>SettingsList</a> and reporting an error if any.
--   
--   <pre>
--   &gt;&gt;&gt; checkSettingsList [(SettingsEnablePush,2)]
--   Just (ConnectionError ProtocolError "enable push must be 0 or 1")
--   </pre>
checkSettingsList :: SettingsList -> Maybe HTTP2Error

-- | Cooked version of settings. This is suitable to be stored in a HTTP/2
--   context.
data Settings
Settings :: !Int -> !Bool -> !(Maybe Int) -> !WindowSize -> !Int -> !(Maybe Int) -> Settings
[headerTableSize] :: Settings -> !Int
[enablePush] :: Settings -> !Bool
[maxConcurrentStreams] :: Settings -> !(Maybe Int)
[initialWindowSize] :: Settings -> !WindowSize
[maxFrameSize] :: Settings -> !Int
[maxHeaderBlockSize] :: Settings -> !(Maybe Int)

-- | The default settings.
--   
--   <pre>
--   &gt;&gt;&gt; defaultSettings
--   Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Nothing, initialWindowSize = 65535, maxFrameSize = 16384, maxHeaderBlockSize = Nothing}
--   </pre>
defaultSettings :: Settings

-- | Updating settings.
--   
--   <pre>
--   &gt;&gt;&gt; updateSettings defaultSettings [(SettingsEnablePush,0),(SettingsMaxHeaderBlockSize,200)]
--   Settings {headerTableSize = 4096, enablePush = False, maxConcurrentStreams = Nothing, initialWindowSize = 65535, maxFrameSize = 16384, maxHeaderBlockSize = Just 200}
--   </pre>
updateSettings :: Settings -> SettingsList -> Settings

-- | The type for window size.
type WindowSize = Int

-- | The default initial window size.
--   
--   <pre>
--   &gt;&gt;&gt; defaultInitialWindowSize
--   65535
--   </pre>
defaultInitialWindowSize :: WindowSize

-- | The maximum window size.
--   
--   <pre>
--   &gt;&gt;&gt; maxWindowSize
--   2147483647
--   </pre>
maxWindowSize :: WindowSize

-- | Checking if a window size exceeds the maximum window size.
--   
--   <pre>
--   &gt;&gt;&gt; isWindowOverflow 10
--   False
--   
--   &gt;&gt;&gt; isWindowOverflow maxWindowSize
--   False
--   
--   &gt;&gt;&gt; isWindowOverflow (maxWindowSize + 1)
--   True
--   </pre>
isWindowOverflow :: WindowSize -> Bool

-- | The type for raw error code.
type ErrorCode = Word32

-- | The type for error code. See
--   <a>https://tools.ietf.org/html/rfc7540#section-7</a>.
data ErrorCodeId
NoError :: ErrorCodeId
ProtocolError :: ErrorCodeId
InternalError :: ErrorCodeId
FlowControlError :: ErrorCodeId
SettingsTimeout :: ErrorCodeId
StreamClosed :: ErrorCodeId
FrameSizeError :: ErrorCodeId
RefusedStream :: ErrorCodeId
Cancel :: ErrorCodeId
CompressionError :: ErrorCodeId
ConnectError :: ErrorCodeId
EnhanceYourCalm :: ErrorCodeId
InadequateSecurity :: ErrorCodeId
HTTP11Required :: ErrorCodeId
UnknownErrorCode :: ErrorCode -> ErrorCodeId

-- | Converting <a>ErrorCodeId</a> to <a>ErrorCode</a>.
--   
--   <pre>
--   &gt;&gt;&gt; fromErrorCodeId NoError
--   0
--   
--   &gt;&gt;&gt; fromErrorCodeId InadequateSecurity
--   12
--   </pre>
fromErrorCodeId :: ErrorCodeId -> ErrorCode

-- | Converting <a>ErrorCode</a> to <a>ErrorCodeId</a>.
--   
--   <pre>
--   &gt;&gt;&gt; toErrorCodeId 0
--   NoError
--   
--   &gt;&gt;&gt; toErrorCodeId 0xc
--   InadequateSecurity
--   
--   &gt;&gt;&gt; toErrorCodeId 0xe
--   UnknownErrorCode 14
--   </pre>
toErrorCodeId :: ErrorCode -> ErrorCodeId

-- | The connection error or the stream error.
data HTTP2Error
ConnectionError :: !ErrorCodeId -> !ByteString -> HTTP2Error
StreamError :: !ErrorCodeId -> !StreamId -> HTTP2Error

-- | Obtaining <a>ErrorCodeId</a> from <a>HTTP2Error</a>.
errorCodeId :: HTTP2Error -> ErrorCodeId

-- | The preface of HTTP/2.
--   
--   <pre>
--   &gt;&gt;&gt; connectionPreface
--   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
--   </pre>
connectionPreface :: ByteString

-- | Length of the preface.
--   
--   <pre>
--   &gt;&gt;&gt; connectionPrefaceLength
--   24
--   </pre>
connectionPrefaceLength :: Int

-- | The length of HTTP/2 frame header.
--   
--   <pre>
--   &gt;&gt;&gt; frameHeaderLength
--   9
--   </pre>
frameHeaderLength :: Int

-- | The maximum length of HTTP/2 payload.
--   
--   <pre>
--   &gt;&gt;&gt; maxPayloadLength
--   16384
--   </pre>
maxPayloadLength :: Int

-- | Default concurrency.
--   
--   <pre>
--   &gt;&gt;&gt; recommendedConcurrency
--   100
--   </pre>
recommendedConcurrency :: Int

module Network.HPACK.Token

-- | Internal representation for header keys.
data Token
Token :: !Int -> !Bool -> !Bool -> !(CI ByteString) -> Token

-- | Index for value table
[ix] :: Token -> !Int

-- | should be indexed in HPACK
[shouldBeIndexed] :: Token -> !Bool

-- | is this a pseudo header key?
[isPseudo] :: Token -> !Bool

-- | Case insensitive header key
[tokenKey] :: Token -> !(CI ByteString)

-- | Extracting an index from a token.
tokenIx :: Token -> Int

-- | Extracting a case insensitive header key from a token.
tokenCIKey :: Token -> ByteString

-- | Extracting a folded header key from a token.
tokenFoldedKey :: Token -> ByteString

-- | Making a token from a header key.
--   
--   <pre>
--   &gt;&gt;&gt; toToken ":authority" == tokenAuthority
--   True
--   
--   &gt;&gt;&gt; toToken "foo"
--   Token {ix = 54, shouldBeIndexed = True, isPseudo = False, tokenKey = "foo"}
--   
--   &gt;&gt;&gt; toToken ":bar"
--   Token {ix = 54, shouldBeIndexed = True, isPseudo = True, tokenKey = ":bar"}
--   </pre>
toToken :: ByteString -> Token

-- | Minimum token index.
minTokenIx :: Int

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

-- | Maximum token index.
maxTokenIx :: Int

-- | Token index for <a>tokenCookie</a>.
cookieTokenIx :: Int

-- | Is this token ix to be held in the place holder?
isMaxTokenIx :: Int -> Bool

-- | Is this token ix for Cookie?
isCookieTokenIx :: Int -> Bool

-- | Is this token ix for a header not defined in the static table?
isStaticTokenIx :: Int -> Bool

-- | Is this token for a header not defined in the static table?
isStaticToken :: Token -> Bool
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

-- | Not defined in the static table.
tokenConnection :: Token

-- | Not defined in the static table.
tokenTE :: Token

-- | A place holder to hold header keys not defined in the static table.
tokenMax :: Token
instance GHC.Show.Show Network.HPACK.Token.Token
instance GHC.Classes.Eq Network.HPACK.Token.Token


-- | HPACK(<a>https://tools.ietf.org/html/rfc7541</a>) encoding and
--   decoding a header list.
module Network.HPACK

-- | Converting <a>HeaderList</a> to the HPACK format. This function has
--   overhead of allocating/freeing a temporary buffer.
--   <a>BufferOverrun</a> will be thrown if the temporary buffer is too
--   small.
encodeHeader :: EncodeStrategy -> Size -> DynamicTable -> HeaderList -> IO ByteString

-- | Converting the HPACK format to <a>HeaderList</a>.
--   
--   <ul>
--   <li>Headers are decoded as is.</li>
--   <li><a>DecodeError</a> would be thrown if the HPACK format is
--   broken.</li>
--   <li><a>BufferOverrun</a> will be thrown if the temporary buffer for
--   Huffman decoding is too small.</li>
--   </ul>
decodeHeader :: DynamicTable -> ByteString -> IO HeaderList

-- | Converting <a>TokenHeaderList</a> to the HPACK format directly in the
--   buffer.
--   
--   4th argument is relating to dynamic table size update. When calling
--   this function for a new <a>TokenHeaderList</a>, it must be
--   <a>True</a>. If <a>True</a> and set by <a>setLimitForEncoding</a>,
--   dynamic table size update is generated at the beginning of the HPACK
--   format.
--   
--   The return value is a pair of leftover <a>TokenHeaderList</a> and how
--   many bytes are filled in the buffer. If the leftover is empty, the
--   encoding is finished. Otherwise, this function should be called with
--   it again. 4th argument must be <a>False</a>.
encodeTokenHeader :: Buffer -> BufferSize -> EncodeStrategy -> Bool -> DynamicTable -> TokenHeaderList -> IO (TokenHeaderList, Int)

-- | Converting the HPACK format to <a>TokenHeaderList</a> and
--   <a>ValueTable</a>.
--   
--   <ul>
--   <li>Multiple values of Cookie: are concatenated.</li>
--   <li>If a pseudo header appears multiple times,
--   <a>IllegalHeaderName</a> is thrown.</li>
--   <li>If unknown pseudo headers appear, <a>IllegalHeaderName</a> is
--   thrown.</li>
--   <li>If pseudo headers are found after normal headers,
--   <a>IllegalHeaderName</a> is thrown.</li>
--   <li>If a header key contains capital letters, <a>IllegalHeaderName</a>
--   is thrown.</li>
--   <li><a>DecodeError</a> would be thrown if the HPACK format is
--   broken.</li>
--   <li><a>BufferOverrun</a> will be thrown if the temporary buffer for
--   Huffman decoding is too small.</li>
--   </ul>
decodeTokenHeader :: DynamicTable -> ByteString -> IO (TokenHeaderList, ValueTable)

-- | Type for dynamic table.
data DynamicTable

-- | Default dynamic table size. The value is 4,096 bytes: an array has 128
--   entries.
--   
--   <pre>
--   &gt;&gt;&gt; defaultDynamicTableSize
--   4096
--   </pre>
defaultDynamicTableSize :: Int

-- | Creating <a>DynamicTable</a> for encoding.
newDynamicTableForEncoding :: Size -> IO DynamicTable

-- | Creating <a>DynamicTable</a> for decoding.
newDynamicTableForDecoding :: Size -> Size -> IO DynamicTable

-- | Clearing <a>DynamicTable</a>. Currently, this frees the temporary
--   buffer for Huffman decoding.
clearDynamicTable :: DynamicTable -> IO ()

-- | Creating <a>DynamicTable</a> for encoding, performing the action and
--   clearing the <a>DynamicTable</a>.
withDynamicTableForEncoding :: Size -> (DynamicTable -> IO a) -> IO a

-- | Creating <a>DynamicTable</a> for decoding, performing the action and
--   clearing the <a>DynamicTable</a>.
withDynamicTableForDecoding :: Size -> Size -> (DynamicTable -> IO a) -> IO a

-- | When SETTINGS_HEADER_TABLE_SIZE is received from a peer, its value
--   should be set by this function.
setLimitForEncoding :: Size -> DynamicTable -> IO ()

-- | Compression algorithms for HPACK encoding.
data CompressionAlgo

-- | No compression
Naive :: CompressionAlgo

-- | Using indices in the static table only
Static :: CompressionAlgo

-- | Using indices
Linear :: CompressionAlgo

-- | Strategy for HPACK encoding.
data EncodeStrategy
EncodeStrategy :: !CompressionAlgo -> !Bool -> EncodeStrategy

-- | Which compression algorithm is used.
[compressionAlgo] :: EncodeStrategy -> !CompressionAlgo

-- | Whether or not to use Huffman encoding for strings.
[useHuffman] :: EncodeStrategy -> !Bool

-- | Default <a>EncodeStrategy</a>.
--   
--   <pre>
--   &gt;&gt;&gt; defaultEncodeStrategy
--   EncodeStrategy {compressionAlgo = Linear, useHuffman = False}
--   </pre>
defaultEncodeStrategy :: EncodeStrategy

-- | Errors for decoder.
data DecodeError

-- | Index is out of range
IndexOverrun :: Index -> DecodeError

-- | Eos appears in the middle of huffman string
EosInTheMiddle :: DecodeError

-- | Non-eos appears in the end of huffman string
IllegalEos :: DecodeError

-- | Eos of huffman string is more than 7 bits
TooLongEos :: DecodeError

-- | Encoded string has no length
EmptyEncodedString :: DecodeError

-- | A peer set the dynamic table size less than 32
TooSmallTableSize :: DecodeError

-- | A peer tried to change the dynamic table size over the limit
TooLargeTableSize :: DecodeError

-- | Table size update at the non-beginning
IllegalTableSizeUpdate :: DecodeError
HeaderBlockTruncated :: DecodeError
IllegalHeaderName :: DecodeError
data BufferOverrun

-- | The buffer size is not enough
BufferOverrun :: BufferOverrun

-- | Header list.
type HeaderList = [Header]

-- | Header.
type Header = (HeaderName, HeaderValue)

-- | Header name.
type HeaderName = ByteString

-- | Header value.
type HeaderValue = ByteString
type TokenHeaderList = [TokenHeader]
type TokenHeader = (Token, HeaderValue)

-- | An array for <a>HeaderValue</a>.
type ValueTable = Array Int (Maybe HeaderValue)

-- | Accessing <a>HeaderValue</a> with <a>Token</a>.
getHeaderValue :: Token -> ValueTable -> Maybe HeaderValue

-- | Converting a header list of the http-types style to
--   <a>TokenHeaderList</a> and <a>ValueTable</a>.
toHeaderTable :: [(CI HeaderName, HeaderValue)] -> IO (TokenHeaderList, ValueTable)

-- | Size in bytes.
type Size = Int

-- | Index for table.
type Index = Int

-- | Buffer type.
type Buffer = Ptr Word8

-- | The size of buffer.
type BufferSize = Int
