-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | HTTP/2 library -- -- HTTP/2 library including frames, priority queues, HPACK, client and -- server. @package http2 @version 5.2.1 module Network.HPACK.Token module Network.HPACK.Internal -- | Integer encoding with a write buffer. encodeI :: WriteBuffer -> (Word8 -> Word8) -> Int -> Int -> IO () -- | Encoding integer with a temporary buffer whose size is 4096. No prefix -- is set. -- --
--   >>> BS.unpack <$> encodeInteger 5 10
--   [10]
--   
--   >>> BS.unpack <$> encodeInteger 5 1337
--   [31,154,10]
--   
--   >>> BS.unpack <$> encodeInteger 8 42
--   [42]
--   
encodeInteger :: Int -> Int -> IO ByteString -- | Integer decoding with a read buffer. The first argument is N of -- prefix. decodeI :: Int -> Word8 -> ReadBuffer -> IO Int -- | Integer decoding. The first argument is N of prefix. -- --
--   >>> decodeInteger 5 10 $ BS.empty
--   10
--   
--   >>> decodeInteger 5 31 $ BS.pack [154,10]
--   1337
--   
--   >>> decodeInteger 8 42 $ BS.empty
--   42
--   
decodeInteger :: Int -> Word8 -> ByteString -> IO Int -- | String encoding (7+) with a temporary buffer whose size is 4096. encodeString :: Bool -> ByteString -> IO ByteString -- | String encoding. The algorithm based on copy avoidance and selection -- of better result of huffman or raw. encodeS :: WriteBuffer -> Bool -> (Word8 -> Word8) -> (Word8 -> Word8) -> Int -> ByteString -> IO () -- | String decoding (7+) with a temporal Huffman decoder whose buffer is -- 4096. decodeString :: ReadBuffer -> IO ByteString -- | Converting a header list of the http-types style to -- TokenHeaderList and ValueTable. toTokenHeaderTable :: [Header] -> IO TokenHeaderTable -- | String decoding with Huffman decoder. decodeS :: (Word8 -> Word8) -> (Word8 -> Bool) -> Int -> HuffmanDecoder -> ReadBuffer -> IO ByteString -- | Converting to '[Header]'. -- -- decodeSimple :: (Word8 -> ReadBuffer -> IO TokenHeader) -> ReadBuffer -> IO [Header] -- | Converting to TokenHeaderList and ValueTable. -- -- decodeSophisticated :: (Word8 -> ReadBuffer -> IO TokenHeader) -> ReadBuffer -> IO TokenHeaderTable -- | Huffman encoding. encodeH :: WriteBuffer -> ByteString -> IO Int -- | Huffman encoding with a temporary buffer whose size is 4096. encodeHuffman :: ByteString -> IO ByteString -- | Huffman decoding. decodeH :: GCBuffer -> BufferSize -> ReadBuffer -> Int -> IO ByteString -- | Huffman decoding with a temporary buffer whose size is 4096. decodeHuffman :: ByteString -> IO ByteString -- | Huffman decoding. type HuffmanDecoder = ReadBuffer -> Int -> IO ByteString -- | Low devel Huffman decoding in a write buffer. decH :: WriteBuffer -> ReadBuffer -> Int -> IO () type GCBuffer = ForeignPtr Word8 -- | Size in bytes. type Size = Int -- | Type for table entry. Size includes the 32 bytes magic number. data Entry Entry :: Size -> Token -> FieldValue -> Entry -- | Field value. type FieldValue = ByteString -- | Index for table. type Index = Int -- | From Header to Entry. toEntry :: Header -> Entry toEntryToken :: Token -> FieldValue -> Entry -- | Getting the size of Entry. entrySize :: Entry -> Size -- | Getting TokenHeader. entryTokenHeader :: Entry -> TokenHeader -- | Getting Token. entryToken :: Entry -> Token -- | Getting HeaderName. entryHeaderName :: Entry -> HeaderName -- | Getting FieldValue. entryFieldValue :: Entry -> FieldValue -- | Dummy Entry to initialize a dynamic table. dummyEntry :: Entry -- | How many entries can be stored in a dynamic table? maxNumbers :: Size -> Int -- | 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 -- | HPACK(https://tools.ietf.org/html/rfc7541) encoding and -- decoding a header list. module Network.HPACK -- | Converting '[Header]' to the HPACK format. This function has overhead -- of allocating/freeing a temporary buffer. BufferOverrun will be -- thrown if the temporary buffer is too small. encodeHeader :: EncodeStrategy -> Size -> DynamicTable -> [Header] -> IO ByteString -- | Converting the HPACK format to '[Header]'. -- -- decodeHeader :: DynamicTable -> ByteString -> IO [Header] -- | A full HTTP header field with the name and value separated. -- -- E.g. "Content-Length: 28" parsed into a Header would -- turn into ("Content-Length", "28") type Header = (HeaderName, ByteString) -- | Retrieve the original string-like value. original :: CI s -> s -- | Retrieve the case folded string-like value. (Also see -- foldCase). foldedCase :: CI s -> s -- | Make the given string-like value case insensitive. mk :: FoldCase s => s -> CI s -- | Converting TokenHeaderList to the HPACK format directly in the -- buffer. -- -- When calling this function for a new TokenHeaderList, 4th -- argument must be True. -- -- The return value is a pair of leftover TokenHeaderList 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 False. -- -- 4th argument is relating to dynamic table size update. If True -- and the limit is set by setLimitForEncoding, dynamic table size -- update is generated at the beginning of the HPACK format. encodeTokenHeader :: Buffer -> BufferSize -> EncodeStrategy -> Bool -> DynamicTable -> TokenHeaderList -> IO (TokenHeaderList, Int) -- | Converting the HPACK format to TokenHeaderList and -- ValueTable. -- -- decodeTokenHeader :: DynamicTable -> ByteString -> IO TokenHeaderTable -- | Type for dynamic table. data DynamicTable -- | Default dynamic table size. The value is 4,096 bytes: an array has 128 -- entries. -- --
--   >>> defaultDynamicTableSize
--   4096
--   
defaultDynamicTableSize :: Int -- | Creating DynamicTable for encoding. newDynamicTableForEncoding :: Size -> IO DynamicTable -- | Creating DynamicTable for decoding. newDynamicTableForDecoding :: Size -> Size -> IO DynamicTable -- | Creating DynamicTable for encoding, performing the action and -- clearing the DynamicTable. withDynamicTableForEncoding :: Size -> (DynamicTable -> IO a) -> IO a -- | Creating DynamicTable for decoding, performing the action and -- clearing the DynamicTable. 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 EncodeStrategy. -- --
--   >>> defaultEncodeStrategy
--   EncodeStrategy {compressionAlgo = Linear, useHuffman = False}
--   
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 -- | 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 TooLargeHeader :: DecodeError -- | Buffer overrun exception. data () => BufferOverrun -- | The buffer size is not enough BufferOverrun :: BufferOverrun -- | Field value. type FieldValue = ByteString -- | TokenBased header. type TokenHeader = (Token, FieldValue) -- | TokenBased header list. type TokenHeaderList = [TokenHeader] -- | Converting a header list of the http-types style to -- TokenHeaderList and ValueTable. toTokenHeaderTable :: [Header] -> IO TokenHeaderTable -- | An array to get FieldValue quickly. getHeaderValue -- should be used. Internally, the key is tokenIx. type ValueTable = Array Int Maybe FieldValue -- | A pair of token list and value table. type TokenHeaderTable = (TokenHeaderList, ValueTable) -- | Accessing FieldValue with Token. getFieldValue :: Token -> ValueTable -> Maybe FieldValue -- | Accessing FieldValue with Token. getHeaderValue :: Token -> ValueTable -> Maybe FieldValue -- | Size in bytes. type Size = Int -- | Index for table. type Index = Int -- | A pointer to Word8. type Buffer = Ptr Word8 -- | Size of a buffer. type BufferSize = Int -- | Framing in HTTP/2(https://www.rfc-editor.org/rfc/rfc9113). module Network.HTTP2.Frame -- | 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 :: ErrorCode -> FramePayload SettingsFrame :: SettingsList -> FramePayload PushPromiseFrame :: StreamId -> HeaderBlockFragment -> FramePayload PingFrame :: ByteString -> FramePayload GoAwayFrame :: StreamId -> ErrorCode -> 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. -- --
--   >>> isPaddingDefined $ DataFrame ""
--   True
--   
--   >>> isPaddingDefined $ PingFrame ""
--   False
--   
isPaddingDefined :: FramePayload -> Bool -- | Encoding an HTTP/2 frame to ByteString. This function is not -- efficient enough for high performace program because of the -- concatenation of ByteString. -- --
--   >>> encodeFrame (encodeInfo id 1) (DataFrame "body")
--   "\NUL\NUL\EOT\NUL\NUL\NUL\NUL\NUL\SOHbody"
--   
encodeFrame :: EncodeInfo -> FramePayload -> ByteString -- | Encoding an HTTP/2 frame to [ByteString]. This is suitable for -- sendMany. encodeFrameChunks :: EncodeInfo -> FramePayload -> [ByteString] -- | Encoding an HTTP/2 frame header. The frame header must be completed. encodeFrameHeader :: FrameType -> 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 :: FrameType -> 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 EncodeInfo. -- --
--   >>> encodeInfo setAck 0
--   EncodeInfo {encodeFlags = 1, encodeStreamId = 0, encodePadding = Nothing}
--   
encodeInfo :: (FrameFlags -> FrameFlags) -> Int -> EncodeInfo -- | Decoding an HTTP/2 frame to ByteString. The second argument -- must be include the entire of frame. So, this function is not useful -- for real applications but useful for testing. decodeFrame :: ByteString -> Either FrameDecodeError Frame -- | Decoding an HTTP/2 frame header. Must supply 9 bytes. decodeFrameHeader :: ByteString -> (FrameType, FrameHeader) -- | Checking a frame header and reporting an error if any. -- --
--   >>> checkFrameHeader (FrameData,(FrameHeader 100 0 0))
--   Left (FrameDecodeError ProtocolError 0 "cannot used in control stream")
--   
checkFrameHeader :: (FrameType, FrameHeader) -> Either FrameDecodeError (FrameType, FrameHeader) data FrameDecodeError FrameDecodeError :: ErrorCode -> StreamId -> ShortByteString -> FrameDecodeError -- | Decoding an HTTP/2 frame payload. This function is considered to -- return a frame payload decoder according to a frame type. decodeFramePayload :: FrameType -> FramePayloadDecoder -- | The type for frame payload decoder. type FramePayloadDecoder = FrameHeader -> ByteString -> Either FrameDecodeError 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 raw frame type. newtype FrameType FrameType :: Word8 -> FrameType pattern FrameData :: FrameType pattern FrameHeaders :: FrameType pattern FramePriority :: FrameType pattern FrameRSTStream :: FrameType pattern FrameSettings :: FrameType pattern FramePushPromise :: FrameType pattern FramePing :: FrameType pattern FrameGoAway :: FrameType pattern FrameWindowUpdate :: FrameType pattern FrameContinuation :: FrameType -- | Converting FrameType to Word8. -- --
--   >>> fromFrameType FrameData
--   0
--   
--   >>> fromFrameType FrameContinuation
--   9
--   
fromFrameType :: FrameType -> Word8 toFrameType :: Word8 -> FrameType minFrameType :: FrameType maxFrameType :: FrameType -- | Getting FrameType from FramePayload. -- --
--   >>> framePayloadToFrameType (DataFrame "body")
--   FrameData
--   
framePayloadToFrameType :: FramePayload -> FrameType -- | Type for stream priority. Deprecated in RFC 9113 but provided for -- FrameHeaders. 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. -- Deprecated in RFC 9113. type Weight = Int -- | The type for stream identifier type StreamId = Int -- | Checking if the stream identifier for control. -- --
--   >>> isControl 0
--   True
--   
--   >>> isControl 1
--   False
--   
isControl :: StreamId -> Bool -- | Checking if the stream identifier is from a client. -- --
--   >>> isClientInitiated 0
--   False
--   
--   >>> isClientInitiated 1
--   True
--   
isClientInitiated :: StreamId -> Bool -- | Checking if the stream identifier is from a server. -- --
--   >>> isServerInitiated 0
--   False
--   
--   >>> isServerInitiated 2
--   True
--   
isServerInitiated :: 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. -- --
--   >>> defaultFlags
--   0
--   
defaultFlags :: FrameFlags -- | Checking if the END_STREAM flag is set. >>> testEndStream 0x1 -- True testEndStream :: FrameFlags -> Bool -- | Checking if the ACK flag is set. >>> testAck 0x1 True testAck :: FrameFlags -> Bool -- | Checking if the END_HEADERS flag is set. -- --
--   >>> testEndHeader 0x4
--   True
--   
testEndHeader :: FrameFlags -> Bool -- | Checking if the PADDED flag is set. -- --
--   >>> testPadded 0x8
--   True
--   
testPadded :: FrameFlags -> Bool -- | Checking if the PRIORITY flag is set. -- --
--   >>> testPriority 0x20
--   True
--   
testPriority :: FrameFlags -> Bool -- | Setting the END_STREAM flag. -- --
--   >>> setEndStream 0
--   1
--   
setEndStream :: FrameFlags -> FrameFlags -- | Setting the ACK flag. -- --
--   >>> setAck 0
--   1
--   
setAck :: FrameFlags -> FrameFlags -- | Setting the END_HEADERS flag. -- --
--   >>> setEndHeader 0
--   4
--   
setEndHeader :: FrameFlags -> FrameFlags -- | Setting the PADDED flag. -- --
--   >>> setPadded 0
--   8
--   
setPadded :: FrameFlags -> FrameFlags -- | Setting the PRIORITY flag. -- --
--   >>> setPriority 0
--   32
--   
setPriority :: FrameFlags -> FrameFlags -- | Association list of SETTINGS. type SettingsList = [(SettingsKey, SettingsValue)] -- | The type for SETTINGS key. newtype SettingsKey SettingsKey :: Word16 -> SettingsKey pattern SettingsTokenHeaderTableSize :: SettingsKey pattern SettingsEnablePush :: SettingsKey pattern SettingsMaxConcurrentStreams :: SettingsKey pattern SettingsInitialWindowSize :: SettingsKey pattern SettingsMaxFrameSize :: SettingsKey pattern SettingsMaxHeaderListSize :: SettingsKey -- | The type for raw SETTINGS value. type SettingsValue = Int fromSettingsKey :: SettingsKey -> Word16 toSettingsKey :: Word16 -> SettingsKey -- | The default payload length of HTTP/2 payload. -- --
--   >>> defaultPayloadLength
--   16384
--   
defaultPayloadLength :: Int -- | The maximum payload length of HTTP/2 payload. -- --
--   >>> maxPayloadLength
--   16777215
--   
maxPayloadLength :: Int -- | Window size. type WindowSize = Int -- | The default initial window size. -- --
--   >>> defaultWindowSize
--   65535
--   
defaultWindowSize :: WindowSize -- | The maximum window size. -- --
--   >>> maxWindowSize
--   2147483647
--   
maxWindowSize :: WindowSize -- | Checking if a window size exceeds the maximum window size. -- --
--   >>> isWindowOverflow 10
--   False
--   
--   >>> isWindowOverflow maxWindowSize
--   False
--   
--   >>> isWindowOverflow (maxWindowSize + 1)
--   True
--   
isWindowOverflow :: WindowSize -> Bool -- | The type for raw error code. newtype ErrorCode ErrorCode :: Word32 -> ErrorCode -- | The type for error code. See -- https://www.rfc-editor.org/rfc/rfc9113#ErrorCodes. pattern NoError :: ErrorCode pattern ProtocolError :: ErrorCode pattern InternalError :: ErrorCode pattern FlowControlError :: ErrorCode pattern SettingsTimeout :: ErrorCode pattern StreamClosed :: ErrorCode pattern FrameSizeError :: ErrorCode pattern RefusedStream :: ErrorCode pattern Cancel :: ErrorCode pattern CompressionError :: ErrorCode pattern ConnectError :: ErrorCode pattern EnhanceYourCalm :: ErrorCode pattern InadequateSecurity :: ErrorCode pattern HTTP11Required :: ErrorCode fromErrorCode :: ErrorCode -> Word32 toErrorCode :: Word32 -> ErrorCode -- | The preface of HTTP/2. -- --
--   >>> connectionPreface
--   "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
--   
connectionPreface :: ByteString -- | Length of the preface. -- --
--   >>> connectionPrefaceLength
--   24
--   
connectionPrefaceLength :: Int -- | The length of HTTP/2 frame header. -- --
--   >>> frameHeaderLength
--   9
--   
frameHeaderLength :: Int -- | Default concurrency. -- --
--   >>> recommendedConcurrency
--   100
--   
recommendedConcurrency :: Int type ErrorCodeId = ErrorCode type SettingsKeyId = SettingsKey type FrameTypeId = FrameType module Network.HTTP2.Client.Internal -- | Request from client. newtype () => Request Request :: OutObj -> Request -- | Response from server. newtype () => Response Response :: InpObj -> Response -- | Client configuration data ClientConfig ClientConfig :: Scheme -> Authority -> Int -> WindowSize -> Settings -> ClientConfig -- | https or http [scheme] :: ClientConfig -> Scheme -- | Server name [authority] :: ClientConfig -> Authority -- | The maximum number of incoming streams on the net [cacheLimit] :: ClientConfig -> Int -- | The window size of connection. [connectionWindowSize] :: ClientConfig -> WindowSize -- | Settings [settings] :: ClientConfig -> Settings -- | HTTP/2 settings. See -- https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings. data Settings Settings :: Int -> Bool -> Maybe Int -> WindowSize -> Int -> Maybe Int -> Int -> Settings -- | SETTINGS_HEADER_TABLE_SIZE [headerTableSize] :: Settings -> Int -- | SETTINGS_ENABLE_PUSH [enablePush] :: Settings -> Bool -- | SETTINGS_MAX_CONCURRENT_STREAMS [maxConcurrentStreams] :: Settings -> Maybe Int -- | SETTINGS_INITIAL_WINDOW_SIZE [initialWindowSize] :: Settings -> WindowSize -- | SETTINGS_MAX_FRAME_SIZE [maxFrameSize] :: Settings -> Int -- | SETTINGS_MAX_HEADER_LIST_SIZE [maxHeaderListSize] :: Settings -> Maybe Int -- | Maximum number of pings allowed per second (CVE-2019-9512) [pingRateLimit] :: Settings -> Int -- | Additional information. data () => Aux Aux :: IO Int -> Aux -- | How many streams can be created without blocking. [auxPossibleClientStreams] :: Aux -> IO Int data Stream data ClientIO ClientIO :: SockAddr -> SockAddr -> (Request -> IO (StreamId, Stream)) -> (Stream -> IO Response) -> (ByteString -> IO ()) -> IO (StreamId, Stream) -> ClientIO [cioMySockAddr] :: ClientIO -> SockAddr [cioPeerSockAddr] :: ClientIO -> SockAddr [cioWriteRequest] :: ClientIO -> Request -> IO (StreamId, Stream) [cioReadResponse] :: ClientIO -> Stream -> IO Response [cioWriteBytes] :: ClientIO -> ByteString -> IO () [cioCreateStream] :: ClientIO -> IO (StreamId, Stream) -- | Launching a receiver and a sender. runIO :: ClientConfig -> Config -> (ClientIO -> IO (IO a)) -> IO a -- | HTTP/2 client library. -- -- Example: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   {-# LANGUAGE RankNTypes #-}
--   
--   module Main where
--   
--   import qualified Data.ByteString.Char8 as C8
--   import Network.HTTP.Types
--   import Network.Run.TCP (runTCPClient) -- network-run
--   import UnliftIO.Async -- unliftio
--   import qualified UnliftIO.Exception as E -- unliftio
--   
--   import Network.HTTP2.Client
--   
--   serverName :: String
--   serverName = "127.0.0.1"
--   
--   main :: IO ()
--   main = runTCPClient serverName "80" $ runHTTP2Client serverName
--     where
--       cliconf host = defaultClientConfig { authority = C8.pack host }
--       runHTTP2Client host s = E.bracket (allocSimpleConfig s 4096)
--                                         freeSimpleConfig
--                                         (\conf -> run (cliconf host) conf client)
--       client :: Client ()
--       client sendRequest _aux = do
--           let req0 = requestNoBody methodGet "/" []
--               client0 = sendRequest req0 $ \rsp -> do
--                   print rsp
--                   getResponseBodyChunk rsp >>= C8.putStrLn
--               req1 = requestNoBody methodGet "/foo" []
--               client1 = sendRequest req1 $ \rsp -> do
--                   print rsp
--                   getResponseBodyChunk rsp >>= C8.putStrLn
--           ex <- E.try $ concurrently_ client0 client1
--           case ex of
--             Left  e  -> print (e :: HTTP2Error)
--             Right () -> putStrLn "OK"
--   
module Network.HTTP2.Client -- | Running HTTP/2 client. run :: ClientConfig -> Config -> Client a -> IO a -- | Client configuration data ClientConfig -- | The default client config. -- -- The authority field will be used to set the HTTP2 -- :authority pseudo-header. In most cases you will want to -- override it to be equal to host. -- -- Further background on authority: RFC 3986 also allows -- host:port, and most servers will accept this too. However, -- when using TLS, many servers will expect the TLS SNI server name and -- the :authority pseudo-header to be equal, and for TLS SNI the -- server name should not include the port. Note that HTTP2 explicitly -- disallows using userinfo@ as part of the authority. -- --
--   >>> defaultClientConfig
--   ClientConfig {scheme = "http", authority = "localhost", cacheLimit = 64, connectionWindowSize = 1048576, settings = Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10}}
--   
defaultClientConfig :: ClientConfig -- | https or http scheme :: ClientConfig -> Scheme -- | Server name authority :: ClientConfig -> Authority -- | The maximum number of incoming streams on the net cacheLimit :: ClientConfig -> Int -- | The window size of connection. connectionWindowSize :: ClientConfig -> WindowSize -- | Settings settings :: ClientConfig -> Settings -- | HTTP/2 settings. See -- https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings. data Settings -- | The default settings. -- --
--   >>> defaultSettings
--   Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10}
--   
defaultSettings :: Settings -- | SETTINGS_HEADER_TABLE_SIZE headerTableSize :: Settings -> Int -- | SETTINGS_ENABLE_PUSH enablePush :: Settings -> Bool -- | SETTINGS_MAX_CONCURRENT_STREAMS maxConcurrentStreams :: Settings -> Maybe Int -- | SETTINGS_INITIAL_WINDOW_SIZE initialWindowSize :: Settings -> WindowSize -- | SETTINGS_MAX_FRAME_SIZE maxFrameSize :: Settings -> Int -- | SETTINGS_MAX_HEADER_LIST_SIZE maxHeaderListSize :: Settings -> Maybe Int -- | Maximum number of pings allowed per second (CVE-2019-9512) pingRateLimit :: Settings -> Int -- | HTTP/2 configuration. data Config Config :: Buffer -> BufferSize -> (ByteString -> IO ()) -> (Int -> IO ByteString) -> PositionReadMaker -> Manager -> SockAddr -> SockAddr -> Config -- | This is used only by frameSender. This MUST be freed after frameSender -- is terminated. [confWriteBuffer] :: Config -> Buffer -- | The size of the write buffer. We assume that the read buffer is the -- same size. So, this value is announced via SETTINGS_MAX_FRAME_SIZE to -- the peer. [confBufferSize] :: Config -> BufferSize [confSendAll] :: Config -> ByteString -> IO () [confReadN] :: Config -> Int -> IO ByteString [confPositionReadMaker] :: Config -> PositionReadMaker [confTimeoutManager] :: Config -> Manager -- | This is copied into Aux, if exist, on server. [confMySockAddr] :: Config -> SockAddr -- | This is copied into Aux, if exist, on server. [confPeerSockAddr] :: Config -> SockAddr -- | Making simple configuration whose IO is not efficient. A write buffer -- is allocated internally. allocSimpleConfig :: Socket -> BufferSize -> IO Config -- | Deallocating the resource of the simple configuration. freeSimpleConfig :: Config -> IO () -- | The connection error or the stream error. Stream errors are treated as -- connection errors since there are no good recovery ways. -- ErrorCode in connection errors should be the highest stream -- identifier but in this implementation it identifies the stream that -- caused this error. data HTTP2Error ConnectionIsClosed :: HTTP2Error ConnectionIsTimeout :: HTTP2Error ConnectionErrorIsReceived :: ErrorCode -> StreamId -> ReasonPhrase -> HTTP2Error ConnectionErrorIsSent :: ErrorCode -> StreamId -> ReasonPhrase -> HTTP2Error StreamErrorIsReceived :: ErrorCode -> StreamId -> HTTP2Error StreamErrorIsSent :: ErrorCode -> StreamId -> ReasonPhrase -> HTTP2Error BadThingHappen :: SomeException -> HTTP2Error GoAwayIsSent :: HTTP2Error type ReasonPhrase = ShortByteString -- | The type for raw error code. newtype ErrorCode ErrorCode :: Word32 -> ErrorCode -- | The type for error code. See -- https://www.rfc-editor.org/rfc/rfc9113#ErrorCodes. pattern NoError :: ErrorCode pattern ProtocolError :: ErrorCode pattern InternalError :: ErrorCode pattern FlowControlError :: ErrorCode pattern SettingsTimeout :: ErrorCode pattern StreamClosed :: ErrorCode pattern FrameSizeError :: ErrorCode pattern RefusedStream :: ErrorCode pattern Cancel :: ErrorCode pattern CompressionError :: ErrorCode pattern ConnectError :: ErrorCode pattern EnhanceYourCalm :: ErrorCode pattern InadequateSecurity :: ErrorCode pattern HTTP11Required :: ErrorCode module Network.HTTP2.Internal -- | Manager to manage the thread and the timer. data Manager -- | Action to be spawned by the manager. type Action = IO () -- | Starting a thread manager. Its action is initially set to 'return ()' -- and should be set by setAction. This allows that the action can -- include the manager itself. start :: Manager -> IO Manager -- | Setting the action to be spawned. setAction :: Manager -> Action -> IO () -- | Stopping the manager. stopAfter :: Manager -> IO a -> (Either SomeException a -> IO b) -> IO b -- | Spawning the action. spawnAction :: Manager -> IO () -- | Fork managed thread -- -- This guarantees that the thread ID is added to the manager's queue -- before the thread starts, and is removed again when the thread -- terminates (normally or abnormally). forkManaged :: Manager -> IO () -> IO () -- | Like forkManaged, but run action with exceptions masked forkManagedUnmask :: Manager -> ((forall x. IO x -> IO x) -> IO ()) -> IO () -- | Killing the IO action of the second argument on timeout. timeoutKillThread :: Manager -> (Handle -> IO a) -> IO a -- | Registering closer for a resource and returning a timer refresher. timeoutClose :: Manager -> IO () -> IO (IO ()) data KilledByHttp2ThreadManager KilledByHttp2ThreadManager :: Maybe SomeException -> KilledByHttp2ThreadManager incCounter :: Manager -> IO () decCounter :: Manager -> IO () waitCounter0 :: Manager -> IO () module Network.HTTP2.Server.Internal -- | Request from client. newtype () => Request Request :: InpObj -> Request -- | Response from server. newtype () => Response Response :: OutObj -> Response -- | Additional information. data () => Aux Aux :: Handle -> SockAddr -> SockAddr -> Aux -- | Time handle for the worker processing this request and response. [auxTimeHandle] :: Aux -> Handle -- | Local socket address copied from Config. [auxMySockAddr] :: Aux -> SockAddr -- | Remove socket address copied from Config. [auxPeerSockAddr] :: Aux -> SockAddr data Stream data ServerIO ServerIO :: SockAddr -> SockAddr -> IO (StreamId, Stream, Request) -> (Stream -> Response -> IO ()) -> (ByteString -> IO ()) -> ServerIO [sioMySockAddr] :: ServerIO -> SockAddr [sioPeerSockAddr] :: ServerIO -> SockAddr [sioReadRequest] :: ServerIO -> IO (StreamId, Stream, Request) [sioWriteResponse] :: ServerIO -> Stream -> Response -> IO () [sioWriteBytes] :: ServerIO -> ByteString -> IO () -- | Launching a receiver and a sender without workers. Any frames can be -- sent with sioWriteBytes. runIO :: ServerConfig -> Config -> (ServerIO -> IO (IO ())) -> IO () -- | HTTP/2 server library. -- -- Example: -- --
--   {-# LANGUAGE OverloadedStrings #-}
--   module Main (main) where
--   
--   import qualified UnliftIO.Exception as E
--   import Data.ByteString.Builder (byteString)
--   import Network.HTTP.Types (ok200)
--   import Network.Run.TCP (runTCPServer) -- network-run
--   
--   import Network.HTTP2.Server
--   
--   main :: IO ()
--   main = runTCPServer Nothing "80" runHTTP2Server
--     where
--       runHTTP2Server s = E.bracket (allocSimpleConfig s 4096)
--                                    freeSimpleConfig
--                                    (\config -> run defaultServerConfig config server)
--       server _req _aux sendResponse = sendResponse response []
--         where
--           response = responseBuilder ok200 header body
--           header = [("Content-Type", "text/plain")]
--           body = byteString "Hello, world!\n"
--   
module Network.HTTP2.Server -- | Running HTTP/2 server. run :: ServerConfig -> Config -> Server -> IO () -- | Server configuration data ServerConfig -- | The default server config. -- --
--   >>> defaultServerConfig
--   ServerConfig {numberOfWorkers = 8, connectionWindowSize = 1048576, settings = Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10}}
--   
defaultServerConfig :: ServerConfig -- | The number of workers numberOfWorkers :: ServerConfig -> Int -- | The window size of incoming streams connectionWindowSize :: ServerConfig -> WindowSize -- | Settings settings :: ServerConfig -> Settings -- | HTTP/2 settings. See -- https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings. data Settings -- | The default settings. -- --
--   >>> defaultSettings
--   Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10}
--   
defaultSettings :: Settings -- | SETTINGS_HEADER_TABLE_SIZE headerTableSize :: Settings -> Int -- | SETTINGS_ENABLE_PUSH enablePush :: Settings -> Bool -- | SETTINGS_MAX_CONCURRENT_STREAMS maxConcurrentStreams :: Settings -> Maybe Int -- | SETTINGS_INITIAL_WINDOW_SIZE initialWindowSize :: Settings -> WindowSize -- | SETTINGS_MAX_FRAME_SIZE maxFrameSize :: Settings -> Int -- | SETTINGS_MAX_HEADER_LIST_SIZE maxHeaderListSize :: Settings -> Maybe Int -- | HTTP/2 configuration. data Config Config :: Buffer -> BufferSize -> (ByteString -> IO ()) -> (Int -> IO ByteString) -> PositionReadMaker -> Manager -> SockAddr -> SockAddr -> Config -- | This is used only by frameSender. This MUST be freed after frameSender -- is terminated. [confWriteBuffer] :: Config -> Buffer -- | The size of the write buffer. We assume that the read buffer is the -- same size. So, this value is announced via SETTINGS_MAX_FRAME_SIZE to -- the peer. [confBufferSize] :: Config -> BufferSize [confSendAll] :: Config -> ByteString -> IO () [confReadN] :: Config -> Int -> IO ByteString [confPositionReadMaker] :: Config -> PositionReadMaker [confTimeoutManager] :: Config -> Manager -- | This is copied into Aux, if exist, on server. [confMySockAddr] :: Config -> SockAddr -- | This is copied into Aux, if exist, on server. [confPeerSockAddr] :: Config -> SockAddr -- | Making simple configuration whose IO is not efficient. A write buffer -- is allocated internally. allocSimpleConfig :: Socket -> BufferSize -> IO Config -- | Deallocating the resource of the simple configuration. freeSimpleConfig :: Config -> IO ()