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


-- | HTTP/2.0 library including frames and HPACK
--   
--   HTTP/2.0 library including frames and HPACK. Currently HTTP/2 16
--   framing and HPACK 10 is supported.
@package http2
@version 1.0.4


-- | 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, ... based on randomness.
--   
--   Only one entry per stream should be enqueued. If multiple entries for
--   a stream are inserted, the ordering is not preserved because of the
--   randomness.
module Network.HTTP2.Priority

-- | 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 element to the priority tree. This must be used for
--   Header frame.
enqueue :: PriorityTree a -> a -> Priority -> IO ()

-- | Dequeuing an element from the priority tree.
dequeue :: PriorityTree a -> IO (a, Priority)


-- | Framing in HTTP/2.
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

-- | Checking if padding is defined in this frame type.
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.
decodeFramePayload :: FrameTypeId -> FramePayloadDecoder
type FramePayloadDecoder = FrameHeader -> ByteString -> Either HTTP2Error FramePayload
decodeDataFrame :: FramePayloadDecoder
decodeHeadersFrame :: FramePayloadDecoder
decodePriorityFrame :: FramePayloadDecoder
decoderstStreamFrame :: FramePayloadDecoder
decodeSettingsFrame :: FramePayloadDecoder
decodePushPromiseFrame :: FramePayloadDecoder
decodePingFrame :: FramePayloadDecoder
decodeGoAwayFrame :: FramePayloadDecoder
decodeWindowUpdateFrame :: FramePayloadDecoder
decodeContinuationFrame :: FramePayloadDecoder
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
type FrameType = Word8

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

-- | <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 HeaderBlockFragment = ByteString
type Padding = ByteString
type Weight = Int
data Priority
Priority :: Bool -> StreamId -> Weight -> Priority
[exclusive] :: Priority -> Bool
[streamDependency] :: Priority -> StreamId
[weight] :: Priority -> Weight

-- | 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
type StreamId = Int

-- | <pre>
--   &gt;&gt;&gt; isControl 0
--   True
--   
--   &gt;&gt;&gt; isControl 1
--   False
--   </pre>
isControl :: StreamId -> Bool

-- | <pre>
--   &gt;&gt;&gt; isRequest 0
--   False
--   
--   &gt;&gt;&gt; isRequest 1
--   True
--   </pre>
isRequest :: StreamId -> Bool

-- | <pre>
--   &gt;&gt;&gt; isResponse 0
--   False
--   
--   &gt;&gt;&gt; isResponse 2
--   True
--   </pre>
isResponse :: StreamId -> Bool
testExclusive :: Int -> Bool
setExclusive :: Int -> Int
clearExclusive :: Int -> Int
type FrameFlags = Word8

-- | <pre>
--   &gt;&gt;&gt; defaultFlags
--   0
--   </pre>
defaultFlags :: FrameFlags

-- | <pre>
--   &gt;&gt;&gt; testEndStream 0x1
--   True
--   </pre>
testEndStream :: FrameFlags -> Bool

-- | <pre>
--   &gt;&gt;&gt; testAck 0x1
--   True
--   </pre>
testAck :: FrameFlags -> Bool

-- | <pre>
--   &gt;&gt;&gt; testEndHeader 0x4
--   True
--   </pre>
testEndHeader :: FrameFlags -> Bool

-- | <pre>
--   &gt;&gt;&gt; testPadded 0x8
--   True
--   </pre>
testPadded :: FrameFlags -> Bool

-- | <pre>
--   &gt;&gt;&gt; testPriority 0x20
--   True
--   </pre>
testPriority :: FrameFlags -> Bool

-- | <pre>
--   &gt;&gt;&gt; setEndStream 0
--   1
--   </pre>
setEndStream :: FrameFlags -> FrameFlags

-- | <pre>
--   &gt;&gt;&gt; setAck 0
--   1
--   </pre>
setAck :: FrameFlags -> FrameFlags

-- | <pre>
--   &gt;&gt;&gt; setEndHeader 0
--   4
--   </pre>
setEndHeader :: FrameFlags -> FrameFlags

-- | <pre>
--   &gt;&gt;&gt; setPadded 0
--   8
--   </pre>
setPadded :: FrameFlags -> FrameFlags

-- | <pre>
--   &gt;&gt;&gt; setPriority 0
--   32
--   </pre>
setPriority :: FrameFlags -> FrameFlags

-- | Settings containing raw values.
type SettingsList = [(SettingsKeyId, SettingsValue)]
type SettingsValue = Int
data SettingsKeyId
SettingsHeaderTableSize :: SettingsKeyId
SettingsEnablePush :: SettingsKeyId
SettingsMaxConcurrentStreams :: SettingsKeyId
SettingsInitialWindowSize :: SettingsKeyId
SettingsMaxFrameSize :: SettingsKeyId
SettingsMaxHeaderBlockSize :: SettingsKeyId

-- | <pre>
--   &gt;&gt;&gt; fromSettingsKeyId SettingsHeaderTableSize
--   1
--   
--   &gt;&gt;&gt; fromSettingsKeyId SettingsMaxHeaderBlockSize
--   6
--   </pre>
fromSettingsKeyId :: SettingsKeyId -> Word16

-- | <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
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

-- | Default concurrency.
--   
--   <pre>
--   &gt;&gt;&gt; recommendedConcurrency
--   100
--   </pre>
recommendedConcurrency :: Int
type ErrorCode = Word32
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

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

-- | <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


-- | HPACK: encoding and decoding a header list.
module Network.HPACK

-- | HPACK encoding from <a>HeaderList</a> to <a>ByteString</a>.
type HPACKEncoding = DynamicTable -> HeaderList -> IO (DynamicTable, ByteString)

-- | HPACK decoding from <a>ByteString</a> to <a>HeaderList</a>.
type HPACKDecoding = DynamicTable -> ByteString -> IO (DynamicTable, HeaderList)

-- | Converting <a>HeaderList</a> for HTTP header to the low level format.
encodeHeader :: EncodeStrategy -> HPACKEncoding

-- | Converting the low level format for HTTP header to <a>HeaderList</a>.
--   <a>DecodeError</a> would be thrown.
decodeHeader :: HPACKDecoding

-- | HPACK encoding from <a>HeaderList</a> to <a>Builder</a>.
type HPACKEncodingBuilder = DynamicTable -> HeaderList -> IO (DynamicTable, Builder)

-- | Converting <a>HeaderList</a> for HTTP header to bytestring builder.
encodeHeaderBuilder :: EncodeStrategy -> HPACKEncodingBuilder

-- | 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>.
newDynamicTableForEncoding :: Size -> IO DynamicTable

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

-- | Compression algorithms for HPACK encoding.
data CompressionAlgo

-- | No compression
Naive :: CompressionAlgo

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

-- | Using indices only
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 = True}
--   </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

-- | Header block is empty
EmptyBlock :: DecodeError

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

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

-- | Header name.
type HeaderName = ByteString

-- | Header value.
type HeaderValue = ByteString

-- | Size in bytes.
type Size = Int

-- | Index for table.
type Index = Int
