http2-5.3.9: HTTP/2 library

Safe Haskell | None
Language | Haskell2010

Network.HTTP2.Client

Contents

- Runner
- Client configuration
- HTTP/2 setting
  - Rate limits
- Common configuration
- Error

Description

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 Control.Concurrent.Async
    import qualified Control.Exception as E

    import Network.HTTP2.Client

    serverName :: String
    serverName = "127.0.0.1"

    main :: IO ()
    main = runTCPClient serverName "80" $ runHTTP2Client serverName
      where
        cliconf host = defaultClientConfig { authority = 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"

Synopsis

- run :: ClientConfig -> Config -> Client a -> IO a
- data ClientConfig
- defaultClientConfig :: ClientConfig
- scheme :: ClientConfig -> Scheme
- authority :: ClientConfig -> Authority
- cacheLimit :: ClientConfig -> Int
- connectionWindowSize :: ClientConfig -> WindowSize
- settings :: ClientConfig -> Settings
- data Settings
- defaultSettings :: Settings
- headerTableSize :: Settings -> Int
- enablePush :: Settings -> Bool
- maxConcurrentStreams :: Settings -> Maybe Int
- initialWindowSize :: Settings -> WindowSize
- maxFrameSize :: Settings -> Int
- maxHeaderListSize :: Settings -> Maybe Int
- pingRateLimit :: Settings -> Int
- settingsRateLimit :: Settings -> Int
- emptyFrameRateLimit :: Settings -> Int
- rstRateLimit :: Settings -> Int
- data Config = Config {
  - confWriteBuffer :: Buffer
  - confBufferSize :: BufferSize
  - confSendAll :: ByteString -> IO ()
  - confReadN :: Int -> IO ByteString
  - confPositionReadMaker :: PositionReadMaker
  - confTimeoutManager :: Manager
  - confMySockAddr :: SockAddr
  - confPeerSockAddr :: SockAddr
  }
- allocSimpleConfig :: Socket -> BufferSize -> IO Config
- allocSimpleConfig' :: Socket -> BufferSize -> Int -> IO Config
- freeSimpleConfig :: Config -> IO ()
- module Network.HTTP.Semantics.Client
- data HTTP2Error
  - = ConnectionIsClosed
  - | ConnectionIsTimeout
  - | ConnectionErrorIsReceived ErrorCode StreamId ReasonPhrase
  - | ConnectionErrorIsSent ErrorCode StreamId ReasonPhrase
  - | StreamErrorIsReceived ErrorCode StreamId
  - | StreamErrorIsSent ErrorCode StreamId ReasonPhrase
  - | BadThingHappen SomeException
  - | GoAwayIsSent
- type ReasonPhrase = ShortByteString
- newtype ErrorCode where
  - ErrorCode Word32
  - 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

# Runner

run :: ClientConfig -> Config -> Client a -> IO a #

Running HTTP/2 client.

# Client configuration

data ClientConfig #

Client configuration

#### Instances

Instances details

Show ClientConfig # |
Instance details Defined in Network.HTTP2.Client.Run Methods showsPrec :: Int -> ClientConfig -> ShowS # show :: ClientConfig -> String # showList :: [ClientConfig] -> ShowS #
Eq ClientConfig # |
Instance details Defined in Network.HTTP2.Client.Run Methods (==) :: ClientConfig -> ClientConfig -> Bool # (/=) :: ClientConfig -> ClientConfig -> Bool #

defaultClientConfig :: 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 = 16777216, settings = Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10, emptyFrameRateLimit = 4, settingsRateLimit = 4, rstRateLimit = 4}}

scheme :: ClientConfig -> Scheme #

https or http

authority :: ClientConfig -> Authority #

Server name

cacheLimit :: ClientConfig -> Int #

The maximum number of incoming streams on the net

connectionWindowSize :: ClientConfig -> WindowSize #

The window size of connection.

settings :: ClientConfig -> Settings #

Settings

# HTTP/2 setting

data Settings #

HTTP/2 settings. See https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings.

#### Instances

Instances details

Show Settings # |
Instance details Defined in Network.HTTP2.H2.Settings Methods showsPrec :: Int -> Settings -> ShowS # show :: Settings -> String # showList :: [Settings] -> ShowS #
Eq Settings # |
Instance details Defined in Network.HTTP2.H2.Settings Methods (==) :: Settings -> Settings -> Bool # (/=) :: Settings -> Settings -> Bool #

defaultSettings :: Settings #

The default settings.

    >>> defaultSettings
    Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing, pingRateLimit = 10, emptyFrameRateLimit = 4, settingsRateLimit = 4, rstRateLimit = 4}

headerTableSize :: Settings -> Int #

SETTINGS_HEADER_TABLE_SIZE

enablePush :: Settings -> Bool #

SETTINGS_ENABLE_PUSH

maxConcurrentStreams :: Settings -> Maybe Int #

SETTINGS_MAX_CONCURRENT_STREAMS

initialWindowSize :: Settings -> WindowSize #

SETTINGS_INITIAL_WINDOW_SIZE

maxFrameSize :: Settings -> Int #

SETTINGS_MAX_FRAME_SIZE

maxHeaderListSize :: Settings -> Maybe Int #

SETTINGS_MAX_HEADER_LIST_SIZE

## Rate limits

pingRateLimit :: Settings -> Int #

Maximum number of pings allowed per second (CVE-2019-9512)

settingsRateLimit :: Settings -> Int #

Maximum number of settings frames allowed per second (CVE-2019-9515)

emptyFrameRateLimit :: Settings -> Int #

Maximum number of empty data frames allowed per second (CVE-2019-9518)

rstRateLimit :: Settings -> Int #

Maximum number of reset frames allowed per second (CVE-2023-44487)

# Common configuration

data Config #

HTTP/2 configuration.

Constructors

Config |

Fields

- confWriteBuffer :: Buffer

  This is used only by frameSender. This MUST be freed after frameSender is terminated.

- confBufferSize :: BufferSize

  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.

- confSendAll :: ByteString -> IO ()
- confReadN :: Int -> IO ByteString
- confPositionReadMaker :: PositionReadMaker
- confTimeoutManager :: Manager
- confMySockAddr :: SockAddr

  This is copied into `Aux`, if exist, on server.

- confPeerSockAddr :: SockAddr

  This is copied into `Aux`, if exist, on server.

allocSimpleConfig :: Socket -> BufferSize -> IO Config #

Making simple configuration whose IO is not efficient. A write buffer is allocated internally. WAI timeout manger is initialized with 30_000_000 microseconds.

allocSimpleConfig' :: Socket -> BufferSize -> Int -> IO Config #

Making simple configuration whose IO is not efficient. A write buffer is allocated internally. The third argument is microseconds to initialize WAI timeout manager.

freeSimpleConfig :: Config -> IO () #

Deallocating the resource of the simple configuration.

module Network.HTTP.Semantics.Client

# Error

data HTTP2Error #

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.

Constructors

ConnectionIsClosed |
ConnectionIsTimeout |
ConnectionErrorIsReceived ErrorCode StreamId ReasonPhrase |
ConnectionErrorIsSent ErrorCode StreamId ReasonPhrase |
StreamErrorIsReceived ErrorCode StreamId |
StreamErrorIsSent ErrorCode StreamId ReasonPhrase |
BadThingHappen SomeException |
GoAwayIsSent |

#### Instances

Instances details

Exception HTTP2Error # |
Instance details Defined in Network.HTTP2.H2.Types Methods toException :: HTTP2Error -> SomeException # fromException :: SomeException -> Maybe HTTP2Error # displayException :: HTTP2Error -> String # backtraceDesired :: HTTP2Error -> Bool #
Show HTTP2Error # |
Instance details Defined in Network.HTTP2.H2.Types Methods showsPrec :: Int -> HTTP2Error -> ShowS # show :: HTTP2Error -> String # showList :: [HTTP2Error] -> ShowS #

type ReasonPhrase = ShortByteString #

newtype ErrorCode #

The type for raw error code.

Constructors

ErrorCode Word32 |

Bundled Patterns

pattern NoError :: ErrorCode | The type for error code. See https://www.rfc-editor.org/rfc/rfc9113#ErrorCodes.
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 |

#### Instances

Instances details

Read ErrorCode # |
Instance details Defined in Network.HTTP2.Frame.Types Methods readsPrec :: Int -> ReadS ErrorCode # readList :: ReadS [ErrorCode] # readPrec :: ReadPrec ErrorCode # readListPrec :: ReadPrec [ErrorCode] #
Show ErrorCode # |
Instance details Defined in Network.HTTP2.Frame.Types Methods showsPrec :: Int -> ErrorCode -> ShowS # show :: ErrorCode -> String # showList :: [ErrorCode] -> ShowS #
Eq ErrorCode # |
Instance details Defined in Network.HTTP2.Frame.Types Methods (==) :: ErrorCode -> ErrorCode -> Bool # (/=) :: ErrorCode -> ErrorCode -> Bool #
Ord ErrorCode # |
Instance details Defined in Network.HTTP2.Frame.Types Methods compare :: ErrorCode -> ErrorCode -> Ordering # (<) :: ErrorCode -> ErrorCode -> Bool # (<=) :: ErrorCode -> ErrorCode -> Bool # (>) :: ErrorCode -> ErrorCode -> Bool # (>=) :: ErrorCode -> ErrorCode -> Bool # max :: ErrorCode -> ErrorCode -> ErrorCode # min :: ErrorCode -> ErrorCode -> ErrorCode #