http-semantics-0.3.0: HTTP senmatics libarry

Safe Haskell | None
Language | Haskell2010

Network.HTTP.Semantics.Client

Contents

- HTTP client
- Request
- Creating request
  - Generalized streaming interface
  - Trailers maker
- Response
  - Accessing response
- Aux
- Types

Synopsis

- type Client a = SendRequest -> Aux -> IO a
- type SendRequest = forall r. Request -> (Response -> IO r) -> IO r
- 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
- data OutBodyIface = OutBodyIface {
  - outBodyUnmask :: forall x. IO x -> IO x
  - outBodyPush :: Builder -> IO ()
  - outBodyPushFinal :: Builder -> IO ()
  - outBodyCancel :: Maybe SomeException -> IO ()
  - outBodyFlush :: IO ()
  }
- requestStreamingIface :: Method -> Path -> RequestHeaders -> (OutBodyIface -> IO ()) -> Request
- type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker
- data NextTrailersMaker
  - = NextTrailersMaker TrailersMaker
  - | Trailers [Header]
- defaultTrailersMaker :: TrailersMaker
- setRequestTrailersMaker :: Request -> TrailersMaker -> Request
- data Response
- responseStatus :: Response -> Maybe Status
- responseHeaders :: Response -> TokenHeaderTable
- responseBodySize :: Response -> Maybe Int
- getResponseBodyChunk :: Response -> IO ByteString
- getResponseBodyChunk' :: Response -> IO (ByteString, Bool)
- getResponseTrailers :: Response -> IO (Maybe TokenHeaderTable)
- data Aux
- auxPossibleClientStreams :: Aux -> IO Int
- type Scheme = ByteString
- type Authority = String
- type Method = ByteString
- type Path = ByteString
- data FileSpec = FileSpec FilePath FileOffset ByteCount
- type FileOffset = Int64
- type ByteCount = Int64
- type ReadN = Int -> IO ByteString
- defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN
- type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount
- type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel)
- data Sentinel
  - = Closer (IO ())
  - | Refresher (IO ())
- defaultPositionReadMaker :: PositionReadMaker

# HTTP client

type Client a = SendRequest -> Aux -> IO a Source #

Client type.

type SendRequest = forall r. Request -> (Response -> IO r) -> IO r Source #

Send a request and receive its response.

# Request

data Request Source #

Request from client.

#### Instances

Instances details

Show Request Source # |
Instance details Defined in Network.HTTP.Semantics.Client.Internal Methods showsPrec :: Int -> Request -> ShowS Source # show :: Request -> String Source # showList :: [Request] -> ShowS Source #

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

## Generalized streaming interface

data OutBodyIface Source #

Constructors

OutBodyIface |

Fields

- outBodyUnmask :: forall x. IO x -> IO x

  Unmask exceptions in the thread spawned for the request body

  This is used in the client: we spawn the new thread for the request body with exceptions masked, and provide the body of `OutBodyStreamingIface` with a callback to unmask them again (typically after installing an exception handler).

  Unmasking in the server is a no-op, as here the scope of the thread that is spawned for the server is the entire handler, not just the response streaming body.

- outBodyPush :: Builder -> IO ()

  Push a new chunk

  In `http2`, there is no direct correspondence between chunks and the resulting `DATA` frames sent: the chunks are collected (written to an internal write buffer) until we can fill a frame.

  See also `outBodyFlush`.

- outBodyPushFinal :: Builder -> IO ()

  Push the final chunk

  Using this function instead of `outBodyPush` can be used to guarantee that the final HTTP2 DATA frame is marked end-of-stream; with `outBodyPush` it may happen that an additional empty DATA frame is used for this purpose. Additionally, after calling this function, `outBodyCancel` will be a no-op.

- outBodyCancel :: Maybe SomeException -> IO ()

  Cancel the stream

  Sends a `RST_STREAM` to the peer. If cancelling as the result of an exception, a `Just` should be provided which specifies the exception which will be stored locally as the reason for cancelling the stream; in this case, the error code sent with the `RST_STREAM` will be `INTERNAL_ERROR` (see https://datatracker.ietf.org/doc/html/rfc7540#section-7). If `Nothing` is given, the error code will be `CANCEL`.

  If there is a partially constructed `DATA` frame at the time of cancellation, this frame is discarded. If this is undesirable, you should call `outBodyFlush` prior to cancelling.

- outBodyFlush :: IO ()

  Flush

  This can be used to emit a DATA frame with the data collected so far (using `outBodyPush`), even if that DATA frame has not yet reached the maximum frame size. Calling `outBodyFlush` unnecessarily can therefore result in excessive overhead from frame headers.

  If no data is available to send, this is a no-op.

requestStreamingIface :: Method -> Path -> RequestHeaders -> (OutBodyIface -> IO ()) -> Request Source #

Generalized version of `requestStreaming`,

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

Constructors

NextTrailersMaker TrailersMaker |
Trailers [Header] |

defaultTrailersMaker :: TrailersMaker Source #

TrailersMake to create no trailers.

setRequestTrailersMaker :: Request -> TrailersMaker -> Request Source #

Setting `TrailersMaker` to `Response`.

# Response

data Response Source #

Response from server.

#### Instances

Instances details

Show Response Source # |
Instance details Defined in Network.HTTP.Semantics.Client.Internal Methods showsPrec :: Int -> Response -> ShowS Source # show :: Response -> String Source # showList :: [Response] -> ShowS Source #

## Accessing response

responseStatus :: Response -> Maybe Status Source #

Getting the status of a response.

responseHeaders :: Response -> TokenHeaderTable Source #

Getting the headers from a response.

responseBodySize :: Response -> Maybe Int Source #

Getting the body size from a response.

getResponseBodyChunk :: Response -> IO ByteString Source #

Reading a chunk of the response body. An empty `ByteString` returned when finished.

getResponseBodyChunk' :: Response -> IO (ByteString, Bool) Source #

Generalization of `getResponseBodyChunk` which also returns if the `ByteString` is the final one

getResponseTrailers :: Response -> IO (Maybe TokenHeaderTable) Source #

Reading response trailers. This function must be called after `getResponseBodyChunk` returns an empty.

# Aux

data Aux Source #

Additional information.

auxPossibleClientStreams :: Aux -> IO Int Source #

How many streams can be created without blocking.

# Types

type Scheme = ByteString Source #

"http" or "https".

type Authority = String Source #

Authority.

type Method = ByteString Source #

HTTP method (flat `ByteString` type).

type Path = ByteString Source #

Path.

data FileSpec Source #

File specification.

Constructors

FileSpec FilePath FileOffset ByteCount |

#### Instances

Instances details

Show FileSpec Source # |
Instance details Defined in Network.HTTP.Semantics.Types Methods showsPrec :: Int -> FileSpec -> ShowS Source # show :: FileSpec -> String Source # showList :: [FileSpec] -> ShowS Source #
Eq FileSpec Source # |
Instance details Defined in Network.HTTP.Semantics.Types Methods (==) :: FileSpec -> FileSpec -> Bool Source # (/=) :: FileSpec -> FileSpec -> Bool Source #

type FileOffset = Int64 Source #

Offset for file.

type ByteCount = Int64 Source #

How many bytes to read

type ReadN = Int -> IO ByteString Source #

Reading n bytes.

defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN Source #

Naive implementation for readN.

NOTE: This function is intended to be used by a single thread only. (It is probably quite rare anyway to want concurrent reads from the same network socket.)

type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount Source #

Position read for files.

type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) Source #

Making a position read and its closer.

data Sentinel Source #

Constructors

Closer (IO ()) | Closing a file resource. Its refresher is automatiaclly generated by the internal timer.
Refresher (IO ()) | Refreshing a file resource while reading. Closing the file must be done by its own timer or something.

defaultPositionReadMaker :: PositionReadMaker Source #

Position read based on `Handle`.