http2-client- A native HTTP2 client library.

Safe HaskellNone




Creating a client

data Http2Client Source #

Record holding functions one can call while in an HTTP2 client session.




newHttp2Client Source #


:: HostName

Host to connect to.

-> PortNumber

Port number to connect to (usually 443 on the web).

-> Int

The buffersize for the Network.HPACK encoder.

-> Int

The buffersize for the Network.HPACK decoder.

-> ClientParams

The TLS client parameters (e.g., to allow some certificates).

-> SettingsList

Initial SETTINGS that are sent as first frame.

-> IO Http2Client 

Starts a new Http2Client with a remote Host/Port. TLS ClientParams are mandatory because we only support TLS-protected streams for now.

type PushPromiseHandler = StreamId -> Http2Stream -> IncomingFlowControl -> OutgoingFlowControl -> IO () Source #

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

Starting streams

data StreamDefinition a Source #

Defines a client stream.

Please red the doc for this record fields and then see StreamStarter.




  • _initStream :: IO StreamThread

    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.

  • _handleStream :: IncomingFlowControl -> OutgoingFlowControl -> IO a

    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.

type StreamStarter a = (Http2Stream -> StreamDefinition a) -> IO (Either TooMuchConcurrency a) Source #

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.

newtype TooMuchConcurrency Source #

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.

data StreamThread Source #

Opaque proof that a client stream was initialized.

This type is only useful to force calling _headers in _initStream and contains no information.

data Http2Stream Source #

Record holding functions one can call while in an HTTP2 client stream.




Sending data for POSTs.

Flow control

data IncomingFlowControl Source #

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




  • _addCredit :: WindowSize -> IO ()

    Add credit (using a hidden mutable reference underneath). This function only does accounting, the IO only does mutable changes. See _updateWindow.

  • _consumeCredit :: WindowSize -> IO Int

    Consumes some credit and returns the credit left.

  • _updateWindow :: IO Bool

    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.

data OutgoingFlowControl Source #

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




  • _receiveCredit :: WindowSize -> IO ()

    Add credit (using a hidden mutable reference underneath).

  • _withdrawCredit :: WindowSize -> IO WindowSize

    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.


Convenience re-exports