Safe Haskell | None |
---|---|
Language | Haskell2010 |
Network.HTTP2.Client
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 ()
- type Client a = SendRequest -> Aux -> IO a
- data Request
- data Response
- data Aux
- data NextTrailersMaker
- type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker
- defaultTrailersMaker :: TrailersMaker
- type Authority = String
- type ByteCount = Int64
- type FileOffset = Int64
- data FileSpec = FileSpec FilePath FileOffset ByteCount
- data OutBodyIface = OutBodyIface {
- outBodyUnmask :: forall x. IO x -> IO x
- outBodyPush :: Builder -> IO ()
- outBodyPushFinal :: Builder -> IO ()
- outBodyCancel :: Maybe SomeException -> IO ()
- outBodyFlush :: IO ()
- type Path = ByteString
- type Scheme = ByteString
- type Method = ByteString
- type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel)
- data Sentinel
- type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount
- defaultPositionReadMaker :: PositionReadMaker
- type ReadN = Int -> IO ByteString
- defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN
- getResponseBodyChunk :: Response -> IO ByteString
- getResponseBodyChunk' :: Response -> IO (ByteString, Bool)
- getResponseTrailers :: Response -> IO (Maybe TokenHeaderTable)
- requestBuilder :: Method -> Path -> RequestHeaders -> Builder -> Request
- requestFile :: Method -> Path -> RequestHeaders -> FileSpec -> Request
- requestNoBody :: Method -> Path -> RequestHeaders -> Request
- requestStreaming :: Method -> Path -> RequestHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Request
- requestStreamingIface :: Method -> Path -> RequestHeaders -> (OutBodyIface -> IO ()) -> Request
- requestStreamingUnmask :: Method -> Path -> RequestHeaders -> ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> Request
- responseBodySize :: Response -> Maybe Int
- responseHeaders :: Response -> TokenHeaderTable
- responseStatus :: Response -> Maybe Status
- setRequestTrailersMaker :: Request -> TrailersMaker -> Request
- type SendRequest = forall r. Request -> (Response -> IO r) -> IO r
- data HTTP2Error
- 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
Client configuration
data ClientConfig Source #
Client configuration
Instances
Show ClientConfig Source # | |
Defined in Network.HTTP2.Client.Run Methods showsPrec :: Int -> ClientConfig -> ShowS show :: ClientConfig -> String showList :: [ClientConfig] -> ShowS | |
Eq ClientConfig Source # | |
Defined in Network.HTTP2.Client.Run |
defaultClientConfig :: ClientConfig Source #
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 Source #
https or http
authority :: ClientConfig -> Authority Source #
Server name
cacheLimit :: ClientConfig -> Int Source #
The maximum number of incoming streams on the net
connectionWindowSize :: ClientConfig -> WindowSize Source #
The window size of connection.
settings :: ClientConfig -> Settings Source #
Settings
HTTP/2 setting
HTTP/2 settings. See https://datatracker.ietf.org/doc/html/rfc9113#name-defined-settings.
Instances
defaultSettings :: Settings Source #
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 Source #
SETTINGS_HEADER_TABLE_SIZE
enablePush :: Settings -> Bool Source #
SETTINGS_ENABLE_PUSH
maxConcurrentStreams :: Settings -> Maybe Int Source #
SETTINGS_MAX_CONCURRENT_STREAMS
initialWindowSize :: Settings -> WindowSize Source #
SETTINGS_INITIAL_WINDOW_SIZE
maxFrameSize :: Settings -> Int Source #
SETTINGS_MAX_FRAME_SIZE
maxHeaderListSize :: Settings -> Maybe Int Source #
SETTINGS_MAX_HEADER_LIST_SIZE
Rate limits
pingRateLimit :: Settings -> Int Source #
Maximum number of pings allowed per second (CVE-2019-9512)
settingsRateLimit :: Settings -> Int Source #
Maximum number of settings frames allowed per second (CVE-2019-9515)
emptyFrameRateLimit :: Settings -> Int Source #
Maximum number of empty data frames allowed per second (CVE-2019-9518)
rstRateLimit :: Settings -> Int Source #
Maximum number of reset frames allowed per second (CVE-2023-44487)
Common configuration
HTTP/2 configuration.
Constructors
Config | |
Fields
|
allocSimpleConfig :: Socket -> BufferSize -> IO Config Source #
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 Source #
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 () Source #
Deallocating the resource of the simple configuration.
type Client a = SendRequest -> Aux -> IO a #
data NextTrailersMaker #
Constructors
NextTrailersMaker TrailersMaker | |
Trailers [Header] |
type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker #
type FileOffset = Int64 #
Constructors
FileSpec FilePath FileOffset ByteCount |
data OutBodyIface #
Constructors
OutBodyIface | |
Fields
|
type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) #
type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount #
defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN #
getResponseBodyChunk :: Response -> IO ByteString #
getResponseBodyChunk' :: Response -> IO (ByteString, Bool) #
getResponseTrailers :: Response -> IO (Maybe TokenHeaderTable) #
requestBuilder :: Method -> Path -> RequestHeaders -> Builder -> Request #
requestNoBody :: Method -> Path -> RequestHeaders -> Request #
requestStreaming :: Method -> Path -> RequestHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Request #
requestStreamingIface :: Method -> Path -> RequestHeaders -> (OutBodyIface -> IO ()) -> Request #
requestStreamingUnmask :: Method -> Path -> RequestHeaders -> ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> Request #
responseBodySize :: Response -> Maybe Int #
responseStatus :: Response -> Maybe Status #
setRequestTrailersMaker :: Request -> TrailersMaker -> Request #
type SendRequest = forall r. Request -> (Response -> IO r) -> IO r #
Error
data HTTP2Error Source #
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
Instances
Exception HTTP2Error Source # | |
Defined in Network.HTTP2.H2.Types Methods toException :: HTTP2Error -> SomeException fromException :: SomeException -> Maybe HTTP2Error displayException :: HTTP2Error -> String backtraceDesired :: HTTP2Error -> Bool | |
Show HTTP2Error Source # | |
Defined in Network.HTTP2.H2.Types Methods showsPrec :: Int -> HTTP2Error -> ShowS show :: HTTP2Error -> String showList :: [HTTP2Error] -> ShowS |
type ReasonPhrase = ShortByteString Source #
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 |