-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | A native HTTP2 client library.
--
-- Please read the README.md at the homepage.
@package http2-client
@version 0.2.0.0
module Network.HTTP2.Client.RawConnection
data RawHttp2Connection
RawHttp2Connection :: (ByteString -> IO ()) -> (Int -> IO ByteString) -> IO () -> RawHttp2Connection
-- | Function to send raw data to the server.
[_sendRaw] :: RawHttp2Connection -> ByteString -> IO ()
-- | Function to block reading a datachunk of a given size from the server.
[_nextRaw] :: RawHttp2Connection -> Int -> IO ByteString
[_close] :: RawHttp2Connection -> IO ()
-- | Initiates a RawHttp2Connection with a server.
--
-- The current code does not handle closing the connexion, yikes.
newRawHttp2Connection :: HostName -> PortNumber -> ClientParams -> IO RawHttp2Connection
module Network.HTTP2.Client.FrameConnection
data Http2FrameConnection
-- | Creates a new Http2FrameConnection to a given host for a
-- frame-to-frame communication.
newHttp2FrameConnection :: HostName -> PortNumber -> ClientParams -> IO Http2FrameConnection
data Http2FrameClientStream
Http2FrameClientStream :: ([(FrameFlags -> FrameFlags, FramePayload)] -> IO ()) -> StreamId -> Http2FrameClientStream
-- | Sends a frame to the server. The first argument is a FrameFlags
-- modifier (e.g., to sed the end-of-stream flag).
[_sendFrames] :: Http2FrameClientStream -> [(FrameFlags -> FrameFlags, FramePayload)] -> IO ()
[_getStreamId] :: Http2FrameClientStream -> StreamId
-- | Creates a client stream.
makeFrameClientStream :: Http2FrameConnection -> StreamId -> Http2FrameClientStream
-- | Sends a frame to the server.
sendOne :: Http2FrameClientStream -> (FrameFlags -> FrameFlags) -> FramePayload -> IO ()
-- | Sends multiple back-to-back frames to the server.
sendBackToBack :: Http2FrameClientStream -> [(FrameFlags -> FrameFlags, FramePayload)] -> IO ()
-- | Waits for the next frame from the server.
next :: Http2FrameConnection -> IO (FrameHeader, Either HTTP2Error FramePayload)
-- | Closes the Http2FrameConnection abruptly.
closeConnection :: Http2FrameConnection -> IO ()
module Network.HTTP2.Client
-- | Record holding functions one can call while in an HTTP2 client
-- session.
data Http2Client
Http2Client :: (ByteString -> IO (IO (FrameHeader, FramePayload))) -> (SettingsList -> IO (IO (FrameHeader, FramePayload))) -> (ErrorCodeId -> ByteString -> IO ()) -> (forall a. StreamStarter a) -> IncomingFlowControl -> OutgoingFlowControl -> IO PayloadSplitter -> Http2Client
-- | Send a PING, the payload size must be exactly eight bytes. Returns an
-- IO to wait for a ping reply. No timeout is provided. Only the first
-- call to this IO will return if a reply is received. Hence we recommend
-- wrapping this IO in an Async (e.g., with race (threadDelay
-- timeout).)
[_ping] :: Http2Client -> ByteString -> IO (IO (FrameHeader, FramePayload))
-- | Sends a SETTINGS. Returns an IO to wait for a settings reply. No
-- timeout is provided. Only the first call to this IO will return if a
-- reply is received. Hence we recommend wrapping this IO in an Async
-- (e.g., with race (threadDelay timeout).)
[_settings] :: Http2Client -> SettingsList -> IO (IO (FrameHeader, FramePayload))
-- | Sends a GOAWAY.
[_goaway] :: Http2Client -> ErrorCodeId -> ByteString -> IO ()
-- | Spawns new streams. See StreamStarter.
[_startStream] :: Http2Client -> forall a. StreamStarter a
-- | Simple getter for the IncomingFlowControl for the whole client
-- connection.
[_incomingFlowControl] :: Http2Client -> IncomingFlowControl
-- | Simple getter for the OutgoingFlowControl for the whole client
-- connection.
[_outgoingFlowControl] :: Http2Client -> OutgoingFlowControl
-- | Returns a function to split a payload.
[_paylodSplitter] :: Http2Client -> IO PayloadSplitter
-- | Starts a new Http2Client with a remote Host/Port. TLS ClientParams are
-- mandatory because we only support TLS-protected streams for now.
newHttp2Client :: HostName -> PortNumber -> Int -> Int -> ClientParams -> SettingsList -> IO Http2Client
-- | Handler upon receiving a PUSH_PROMISE from the server.
--
-- The functions for Http2Stream are similar to those used in ''.
-- But callers shall not use _headers to initialize the
-- PUSH_PROMISE stream. Rather, callers should waitHeaders or
-- _rst to reject the PUSH_PROMISE.
--
-- The StreamId corresponds to the parent stream as PUSH_PROMISEs are
-- tied to a client-initiated stream. Longer term we may move passing
-- this handler to the _startStream instead of
-- newHttp2Client (as it is for now).
type PushPromiseHandler = StreamId -> Http2Stream -> IncomingFlowControl -> OutgoingFlowControl -> IO ()
-- | Defines a client stream.
--
-- Please red the doc for this record fields and then see
-- StreamStarter.
data StreamDefinition a
StreamDefinition :: IO StreamThread -> (IncomingFlowControl -> OutgoingFlowControl -> IO a) -> StreamDefinition a
-- | Function to initialize a new client stream. This function runs in a
-- exclusive-access section of the code and may prevent other threads to
-- initialize new streams. Hence, you should ensure this IO does not wait
-- for long periods of time.
[_initStream] :: StreamDefinition a -> IO StreamThread
-- | Function to operate with the stream. IncomingFlowControl currently is
-- credited on your behalf as soon as a DATA frame arrives (and before
-- you handle it with _waitData). However we do not send
-- WINDOW_UPDATE with _updateWindow. This design may change in the
-- future to give more leeway to library users.
[_handleStream] :: StreamDefinition a -> IncomingFlowControl -> OutgoingFlowControl -> IO a
-- | Type alias for callback-based functions starting new streams.
--
-- The callback a user must provide takes an Http2Stream and
-- returns a StreamDefinition. This construction may seem wrong
-- because a StreamDefinition contains an initialization and a
-- handler functions. The explanation for this twistedness is as follows:
-- in HTTP2 stream-ids must be monotonically increasing, if we want to
-- support multi-threaded clients we need to serialize access to a
-- critical region of the code when clients send HEADERS+CONTINUATIONs
-- frames.
--
-- Passing the Http2Stream object as part of the callback avoids
-- leaking the implementation of the critical region, meanwhile, the
-- StreamDefinition delimits this critical region.
type StreamStarter a = (Http2Stream -> StreamDefinition a) -> IO (Either TooMuchConcurrency a)
-- | Whether or not the client library believes the server will reject the
-- new stream. The Int content corresponds to the number of streams that
-- should end before accepting more streams. A reason this number can be
-- more than zero is that servers can change (and hence reduce) the
-- advertised number of allowed maxConcurrentStreams at any time.
newtype TooMuchConcurrency
TooMuchConcurrency :: Int -> TooMuchConcurrency
[_getStreamRoomNeeded] :: TooMuchConcurrency -> Int
-- | Opaque proof that a client stream was initialized.
--
-- This type is only useful to force calling _headers in
-- _initStream and contains no information.
data StreamThread
-- | Record holding functions one can call while in an HTTP2 client stream.
data Http2Stream
Http2Stream :: (HeaderList -> (FrameFlags -> FrameFlags) -> IO StreamThread) -> (Priority -> IO ()) -> (ErrorCodeId -> IO ()) -> IO (FrameHeader, StreamId, Either ErrorCode HeaderList) -> IO (FrameHeader, Either ErrorCode ByteString) -> ((FrameFlags -> FrameFlags) -> ByteString -> IO ()) -> (PushPromiseHandler -> IO ()) -> Http2Stream
-- | Starts the stream with HTTP headers. Flags modifier can use
-- setEndStream if no data is required passed the last block of
-- headers. Usually, this is the only call needed to build an
-- _initStream.
[_headers] :: Http2Stream -> HeaderList -> (FrameFlags -> FrameFlags) -> IO StreamThread
-- | Changes the PRIORITY of this stream.
[_prio] :: Http2Stream -> Priority -> IO ()
-- | Resets this stream with a RST frame. You should not use this stream
-- past this call.
[_rst] :: Http2Stream -> ErrorCodeId -> IO ()
-- | Waits for HTTP headers from the server. This function also passes the
-- last frame header of the PUSH-PROMISE, HEADERS, or CONTINUATION
-- sequence of frames. Waiting more than once per stream will hang as
-- headers are sent only one time.
[_waitHeaders] :: Http2Stream -> IO (FrameHeader, StreamId, Either ErrorCode HeaderList)
-- | Waits for a DATA frame chunk. A user should testEndStream on the frame
-- header to know when the server is done with the stream.
[_waitData] :: Http2Stream -> IO (FrameHeader, Either ErrorCode ByteString)
-- | Sends a DATA frame chunk. You can use send empty frames with only
-- headers modifiers to close streams. This function is oblivious to
-- framing and hence does not respect the RFC if sending large blocks.
-- Use sendData to chunk and send naively according to server's
-- preferences. This function can be useful if you intend to handle the
-- framing yourself.
[_sendDataChunk] :: Http2Stream -> (FrameFlags -> FrameFlags) -> ByteString -> IO ()
[_waitPushPromise] :: Http2Stream -> PushPromiseHandler -> IO ()
sendData :: Http2Client -> Http2Stream -> (FrameFlags -> FrameFlags) -> ByteString -> IO ()
-- | Offers credit-based flow-control.
--
-- Any mutable changes are atomic and hence work as intended in a
-- multithreaded setup.
--
-- The design of the flow-control mechanism is subject to changes. One
-- important thing to keep in mind with current implementation is that
-- both the connection and streams are credited with _addCredit as
-- soon as DATA frames arrive, hence no-need to account for the DATA
-- frames (but you can account for delay-bandwidth product for instance).
data IncomingFlowControl
IncomingFlowControl :: (WindowSize -> IO ()) -> (WindowSize -> IO Int) -> IO Bool -> IncomingFlowControl
-- | Add credit (using a hidden mutable reference underneath). This
-- function only does accounting, the IO only does mutable changes. See
-- _updateWindow.
[_addCredit] :: IncomingFlowControl -> WindowSize -> IO ()
-- | Consumes some credit and returns the credit left.
[_consumeCredit] :: IncomingFlowControl -> WindowSize -> IO Int
-- | Sends a WINDOW_UPDATE frame crediting it with the whole amount
-- credited since the last _updateWindow call. The boolean tells whether
-- an update was actually sent or not. A reason for not sending an update
-- is if there is no credit in the flow-control system.
[_updateWindow] :: IncomingFlowControl -> IO Bool
-- | Receives credit-based flow-control or block.
--
-- There is no way to observe the total amount of credit and
-- receive/withdraw are atomic hence this object is thread-safe. However
-- we plan to propose an STM-based API to allow withdrawing atomically
-- from both the connection and a per-stream OutgoingFlowControl
-- objects at a same time. Without such atomicity one must ensure
-- consumers do not exhaust the connection credit before taking the
-- per-stream credit (else they might prevent others sending data without
-- taking any).
--
-- Longer term we plan to hide outgoing-flow-control increment/decrement
-- altogether because exception between withdrawing credit and sending
-- DATA could mean lost credit (and hence hanging streams).
data OutgoingFlowControl
OutgoingFlowControl :: (WindowSize -> IO ()) -> (WindowSize -> IO WindowSize) -> OutgoingFlowControl
-- | Add credit (using a hidden mutable reference underneath).
[_receiveCredit] :: OutgoingFlowControl -> WindowSize -> IO ()
-- | Wait until we can take credit from stash. The returned value
-- correspond to the amount that could be withdrawn, which is
-- min(current, wanted). A caller should withdraw credit to send DATA
-- chunks and put back any unused credit with _receiveCredit.
[_withdrawCredit] :: OutgoingFlowControl -> WindowSize -> IO WindowSize
-- | Synonym of _goaway.
--
-- https://github.com/http2/http2-spec/pull/366
_gtfo :: Http2Client -> ErrorCodeId -> ByteString -> IO ()
instance GHC.Show.Show Network.HTTP2.Client.TooMuchConcurrency
module Network.HTTP2.Client.Helpers
-- | Opaque type to express an action which timed out.
data TimedOut
TimedOut :: TimedOut
-- | Result for a ping.
type PingReply = (UTCTime, UTCTime, Either TimedOut (FrameHeader, FramePayload))
-- | Performs a ping and waits for a reply up to a given timeout (in
-- microseconds).
ping :: Http2Client -> Int -> ByteString -> IO PingReply
-- | Result containing the unpacked headers and all frames received in on a
-- stream. See StreamResponse and fromStreamResult to get a
-- higher-level utility.
type StreamResult = (Either ErrorCode HeaderList, [Either ErrorCode ByteString])
-- | An HTTP2 response, once fully received, is made of headers and a
-- payload.
type StreamResponse = (HeaderList, ByteString)
-- | Wait for a stream until completion.
--
-- This function is fine if you don't want to consume results in chunks.
waitStream :: Http2Stream -> IncomingFlowControl -> IO StreamResult
-- | Converts a StreamResult to a StramResponse, stopping at the first
-- error using the `Either HTTP2.ErrorCode` monad.
fromStreamResult :: StreamResult -> Either ErrorCode StreamResponse
-- | Sequentially wait for every push-promise with a handler.
--
-- This function runs forever and you should wrap it with
-- withAsync.
onPushPromise :: Http2Stream -> PushPromiseHandler -> IO ()
instance GHC.Show.Show Network.HTTP2.Client.Helpers.TimedOut