Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
HTTP/2 client library.
Example:
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} module Main where import Control.Concurrent.Async import qualified Control.Exception as E import qualified Data.ByteString.Char8 as C8 import Network.HTTP.Types import Network.Run.TCP (runTCPClient) -- network-run import Network.HTTP2.Client serverName :: String serverName = "127.0.0.1" main :: IO () main = runTCPClient serverName "80" $ runHTTP2Client serverName where cliconf host = defaultClientConfig { authority = C8.pack 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
- type Scheme = ByteString
- type Authority = ByteString
- 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
- data Config = Config {}
- allocSimpleConfig :: Socket -> BufferSize -> IO Config
- freeSimpleConfig :: Config -> IO ()
- type Client a = (forall b. Request -> (Response -> IO b) -> IO b) -> Aux -> IO a
- data Request
- requestNoBody :: Method -> Path -> RequestHeaders -> Request
- requestFile :: Method -> Path -> RequestHeaders -> FileSpec -> Request
- requestStreaming :: Method -> Path -> RequestHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Request
- requestStreamingUnmask :: Method -> Path -> RequestHeaders -> ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> Request
- requestBuilder :: Method -> Path -> RequestHeaders -> Builder -> Request
- type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker
- data NextTrailersMaker
- defaultTrailersMaker :: TrailersMaker
- setRequestTrailersMaker :: Request -> TrailersMaker -> Request
- data Response
- responseStatus :: Response -> Maybe Status
- responseHeaders :: Response -> HeaderTable
- responseBodySize :: Response -> Maybe Int
- getResponseBodyChunk :: Response -> IO ByteString
- getResponseTrailers :: Response -> IO (Maybe HeaderTable)
- data Aux
- auxPossibleClientStreams :: Aux -> IO Int
- type Method = ByteString
- type Path = ByteString
- data FileSpec = FileSpec FilePath FileOffset ByteCount
- type FileOffset = Int64
- type ByteCount = Int64
- 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
- defaultReadN :: Socket -> IORef (Maybe ByteString) -> Int -> IO ByteString
- type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel)
- type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount
- data Sentinel
- defaultPositionReadMaker :: PositionReadMaker
Runner
Client configuration
type Scheme = ByteString Source #
"http" or "https".
type Authority = ByteString Source #
Authority.
data ClientConfig Source #
Client configuration
Instances
Show ClientConfig Source # | |
Defined in Network.HTTP2.Client.Run showsPrec :: Int -> ClientConfig -> ShowS # show :: ClientConfig -> String # showList :: [ClientConfig] -> ShowS # | |
Eq ClientConfig Source # | |
Defined in Network.HTTP2.Client.Run (==) :: ClientConfig -> ClientConfig -> Bool # (/=) :: ClientConfig -> ClientConfig -> Bool # |
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 = 1048576, settings = Settings {headerTableSize = 4096, enablePush = True, maxConcurrentStreams = Just 64, initialWindowSize = 262144, maxFrameSize = 16384, maxHeaderListSize = Nothing}}
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}
headerTableSize :: Settings -> Int Source #
SETTINGS_HEADER_TABLE_SIZE
enablePush :: Settings -> Bool Source #
SETTINGS_ENABLE_PUSH
initialWindowSize :: Settings -> WindowSize Source #
SETTINGS_INITIAL_WINDOW_SIZE
maxFrameSize :: Settings -> Int Source #
SETTINGS_MAX_FRAME_SIZE
Common configuration
HTTP/2 configuration.
Config | |
|
allocSimpleConfig :: Socket -> BufferSize -> IO Config Source #
Making simple configuration whose IO is not efficient. A write buffer is allocated internally.
freeSimpleConfig :: Config -> IO () Source #
Deallocating the resource of the simple configuration.
HTTP/2 client
type Client a = (forall b. Request -> (Response -> IO b) -> IO b) -> Aux -> IO a Source #
Client type.
Request
Request from client.
Creating request
requestNoBody :: Method -> Path -> RequestHeaders -> Request Source #
Creating request without body.
requestFile :: Method -> Path -> RequestHeaders -> FileSpec -> Request Source #
Creating request with file.
requestStreaming :: Method -> Path -> RequestHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Request Source #
Creating request with streaming.
requestStreamingUnmask :: Method -> Path -> RequestHeaders -> ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> Request Source #
Like requestStreaming
, but run the action with exceptions masked
requestBuilder :: Method -> Path -> RequestHeaders -> Builder -> Request Source #
Creating request with builder.
Trailers maker
type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker Source #
Trailers maker. A chunks of the response body is passed
with Just
. The maker should update internal state
with the ByteString
and return the next trailers maker.
When response body reaches its end,
Nothing
is passed and the maker should generate
trailers. An example:
{-# LANGUAGE BangPatterns #-} import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as C8 import Crypto.Hash (Context, SHA1) -- cryptonite import qualified Crypto.Hash as CH -- Strictness is important for Context. trailersMaker :: Context SHA1 -> Maybe ByteString -> IO NextTrailersMaker trailersMaker ctx Nothing = return $ Trailers [("X-SHA1", sha1)] where !sha1 = C8.pack $ show $ CH.hashFinalize ctx trailersMaker ctx (Just bs) = return $ NextTrailersMaker $ trailersMaker ctx' where !ctx' = CH.hashUpdate ctx bs
Usage example:
let h2rsp = responseFile ... maker = trailersMaker (CH.hashInit :: Context SHA1) h2rsp' = setResponseTrailersMaker h2rsp maker
data NextTrailersMaker Source #
Either the next trailers maker or final trailers.
defaultTrailersMaker :: TrailersMaker Source #
TrailersMake to create no trailers.
setRequestTrailersMaker :: Request -> TrailersMaker -> Request Source #
Setting TrailersMaker
to Response
.
Response
Response from server.
Accessing response
responseHeaders :: Response -> HeaderTable Source #
Getting the headers from a response.
getResponseBodyChunk :: Response -> IO ByteString Source #
Reading a chunk of the response body.
An empty ByteString
returned when finished.
getResponseTrailers :: Response -> IO (Maybe HeaderTable) Source #
Reading response trailers.
This function must be called after getResponseBodyChunk
returns an empty.
Aux
Types
type Method = ByteString #
HTTP method (flat ByteString
type).
type Path = ByteString Source #
Path.
File specification.
type FileOffset = Int64 Source #
Offset for file.
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.
Instances
Exception HTTP2Error Source # | |
Defined in Network.HTTP2.H2.Types toException :: HTTP2Error -> SomeException # fromException :: SomeException -> Maybe HTTP2Error # displayException :: HTTP2Error -> String # | |
Show HTTP2Error Source # | |
Defined in Network.HTTP2.H2.Types showsPrec :: Int -> HTTP2Error -> ShowS # show :: HTTP2Error -> String # showList :: [HTTP2Error] -> ShowS # |
type ReasonPhrase = ShortByteString Source #
The type for raw error code.
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 |
RecvN
defaultReadN :: Socket -> IORef (Maybe ByteString) -> Int -> IO ByteString Source #
Naive implementation for readN.
Position read for files
type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) Source #
Making a position read and its closer.
type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount Source #
Position read for files.
Manipulating a file resource.
defaultPositionReadMaker :: PositionReadMaker Source #
Position read based on Handle
.