http2-client-0.1.0.0: A native HTTP2 client library.

Safe HaskellNone
LanguageHaskell2010

Network.HTTP2.Client

Synopsis

Documentation

data Http2Client Source #

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

Constructors

Http2Client 

Fields

newHttp2Client Source #

Arguments

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

-> PushPromiseHandler a

Action to perform when a server sends a PUSH_PROMISE.

-> 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 a = StreamId -> Http2Stream -> IncomingFlowControl -> OutgoingFlowControl -> IO a 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).

data Http2Stream Source #

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

Constructors

Http2Stream 

Fields

  • _headers :: HeaderList -> (FrameFlags -> FrameFlags) -> IO StreamThread

    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.

  • _prio :: Priority -> IO ()

    Changes the PRIORITY of this stream.

  • _rst :: ErrorCodeId -> IO ()

    Resets this stream with a RST frame. You should not use this stream past this call.

  • _waitHeaders :: IO (FrameHeader, StreamId, Either ErrorCode HeaderList)

    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.

  • _waitData :: IO (FrameHeader, Either ErrorCode ByteString)

    Waits for a DATA frame chunk. A user should testEndStream on the frame header to know when the server is done with the stream.

  • _sendDataChunk :: (FrameFlags -> FrameFlags) -> ByteString -> IO ()

    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.

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 StreamDefinition a Source #

Defines a client stream.

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

Constructors

StreamDefinition 

Fields

  • _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.

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

Constructors

IncomingFlowControl 

Fields

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

Constructors

OutgoingFlowControl 

Fields

  • _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.