-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | HTTP senmatics libarry -- -- Version-independent common parts of HTTP @package http-semantics @version 0.0.0 module Network.HTTP.Semantics.Server.Internal -- | Request from client. newtype Request Request :: InpObj -> Request -- | Response from server. newtype Response Response :: OutObj -> Response -- | Additional information. data Aux Aux :: Handle -> SockAddr -> SockAddr -> Aux -- | Time handle for the worker processing this request and response. [auxTimeHandle] :: Aux -> Handle -- | Local socket address copied from Config. [auxMySockAddr] :: Aux -> SockAddr -- | Remove socket address copied from Config. [auxPeerSockAddr] :: Aux -> SockAddr instance GHC.Show.Show Network.HTTP.Semantics.Server.Internal.Request instance GHC.Show.Show Network.HTTP.Semantics.Server.Internal.Response module Network.HTTP.Semantics.Client.Internal -- | Request from client. newtype Request Request :: OutObj -> Request -- | Response from server. newtype Response Response :: InpObj -> Response -- | Additional information. data Aux Aux :: IO Int -> Aux -- | How many streams can be created without blocking. [auxPossibleClientStreams] :: Aux -> IO Int instance GHC.Show.Show Network.HTTP.Semantics.Client.Internal.Request instance GHC.Show.Show Network.HTTP.Semantics.Client.Internal.Response -- | Library for HTTP Semantics (RFC9110), version-independent -- common parts. For low-level headers, Token is used. For -- upper-level headers, HeaderName should be used. module Network.HTTP.Semantics -- | Input object data InpObj InpObj :: TokenHeaderTable -> Maybe Int -> InpBody -> IORef (Maybe TokenHeaderTable) -> InpObj -- | Accessor for headers. [inpObjHeaders] :: InpObj -> TokenHeaderTable -- | Accessor for body length specified in content-length:. [inpObjBodySize] :: InpObj -> Maybe Int -- | Accessor for body. [inpObjBody] :: InpObj -> InpBody -- | Accessor for trailers. [inpObjTrailers] :: InpObj -> IORef (Maybe TokenHeaderTable) type InpBody = IO ByteString -- | Output object data OutObj OutObj :: [Header] -> OutBody -> TrailersMaker -> OutObj -- | Accessor for header. [outObjHeaders] :: OutObj -> [Header] -- | Accessor for outObj body. [outObjBody] :: OutObj -> OutBody -- | Accessor for trailers maker. [outObjTrailers] :: OutObj -> TrailersMaker data OutBody OutBodyNone :: OutBody -- | Streaming body takes a write action and a flush action. OutBodyStreaming :: ((Builder -> IO ()) -> IO () -> IO ()) -> OutBody -- | Like OutBodyStreaming, but with a callback to unmask expections -- -- This is used in the client: we spawn the new thread for the request -- body with exceptions masked, and provide the body of -- OutBodyStreamingUnmask with a callback to unmask them again -- (typically after installing an exception handler). -- -- We do NOT support this in the server, as here the scope of the -- thread that is spawned for the server is the entire handler, not just -- the response streaming body. -- -- TODO: The analogous change for the server-side would be to provide a -- similar unmask callback as the first argument in the -- Server type alias. OutBodyStreamingUnmask :: ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> OutBody OutBodyBuilder :: Builder -> OutBody OutBodyFile :: FileSpec -> OutBody -- | 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 --type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker -- | TrailersMake to create no trailers. defaultTrailersMaker :: TrailersMaker -- | Either the next trailers maker or final trailers. data NextTrailersMaker NextTrailersMaker :: TrailersMaker -> NextTrailersMaker Trailers :: [Header] -> NextTrailersMaker -- | Offset for file. type FileOffset = Int64 -- | How many bytes to read type ByteCount = Int64 -- | File specification. data FileSpec FileSpec :: FilePath -> FileOffset -> ByteCount -> FileSpec -- | "http" or "https". type Scheme = ByteString -- | Authority. type Authority = String -- | Path. type Path = ByteString -- | Field name. Internal usage only. type FieldName = ByteString -- | Field value. type FieldValue = ByteString -- | TokenBased header. type TokenHeader = (Token, FieldValue) -- | TokenBased header list. type TokenHeaderList = [TokenHeader] -- | A pair of token list and value table. type TokenHeaderTable = (TokenHeaderList, ValueTable) -- | An array to get FieldValue quickly. getHeaderValue -- should be used. Internally, the key is tokenIx. type ValueTable = Array Int (Maybe FieldValue) -- | Accessing FieldValue with Token. getFieldValue :: Token -> ValueTable -> Maybe FieldValue -- | A pair of token list and value table. -- | Deprecated: use TokenHeaderTable instead type HeaderTable = (TokenHeaderList, ValueTable) -- | Header value. -- | Deprecated: use FieldValue instead type HeaderValue = ByteString -- | Accessing FieldValue with Token. -- | Deprecated: use geFieldValue instead getHeaderValue :: Token -> ValueTable -> Maybe FieldValue -- | Internal representation for header keys. data Token Token :: Int -> Bool -> Bool -> HeaderName -> Token -- | Index for value table [tokenIx] :: Token -> Int -- | should be indexed in HPACK [shouldBeIndexed] :: Token -> Bool -- | is this a pseudo header key? [isPseudo] :: Token -> Bool -- | Case insensitive header key [tokenKey] :: Token -> HeaderName -- | Extracting a case insensitive header key from a token. tokenCIKey :: Token -> ByteString -- | Extracting a folded header key from a token. tokenFoldedKey :: Token -> ByteString -- | Making a token from a header key. -- --
-- >>> toToken ":authority" == tokenAuthority
-- True
--
-- >>> toToken "foo"
-- Token {tokenIx = 73, shouldBeIndexed = True, isPseudo = False, tokenKey = "foo"}
--
-- >>> toToken ":bar"
-- Token {tokenIx = 73, shouldBeIndexed = True, isPseudo = True, tokenKey = ":bar"}
--
toToken :: ByteString -> Token
-- | Minimum token index.
minTokenIx :: Int
-- | Maximun token index defined in the static table.
maxStaticTokenIx :: Int
-- | Maximum token index.
maxTokenIx :: Int
-- | Token index for tokenCookie.
cookieTokenIx :: Int
-- | Is this token ix to be held in the place holder?
isMaxTokenIx :: Int -> Bool
-- | Is this token ix for Cookie?
isCookieTokenIx :: Int -> Bool
-- | Is this token ix for a header not defined in the static table?
isStaticTokenIx :: Int -> Bool
-- | Is this token for a header not defined in the static table?
isStaticToken :: Token -> Bool
tokenAuthority :: Token
tokenMethod :: Token
tokenPath :: Token
tokenScheme :: Token
tokenStatus :: Token
tokenAcceptCharset :: Token
tokenAcceptEncoding :: Token
tokenAcceptLanguage :: Token
tokenAcceptRanges :: Token
tokenAccept :: Token
tokenAccessControlAllowOrigin :: Token
tokenAge :: Token
tokenAllow :: Token
tokenAuthorization :: Token
tokenCacheControl :: Token
tokenContentDisposition :: Token
tokenContentEncoding :: Token
tokenContentLanguage :: Token
tokenContentLength :: Token
tokenContentLocation :: Token
tokenContentRange :: Token
tokenContentType :: Token
tokenCookie :: Token
tokenDate :: Token
tokenEtag :: Token
tokenExpect :: Token
tokenExpires :: Token
tokenFrom :: Token
tokenHost :: Token
tokenIfMatch :: Token
tokenIfModifiedSince :: Token
tokenIfNoneMatch :: Token
tokenIfRange :: Token
tokenIfUnmodifiedSince :: Token
tokenLastModified :: Token
tokenLink :: Token
tokenLocation :: Token
tokenMaxForwards :: Token
tokenProxyAuthenticate :: Token
tokenProxyAuthorization :: Token
tokenRange :: Token
tokenReferer :: Token
tokenRefresh :: Token
tokenRetryAfter :: Token
tokenServer :: Token
tokenSetCookie :: Token
tokenStrictTransportSecurity :: Token
tokenTransferEncoding :: Token
tokenUserAgent :: Token
tokenVary :: Token
tokenVia :: Token
tokenWwwAuthenticate :: Token
-- | A place holder to hold header keys not defined in the static table. |
-- For Warp
tokenConnection :: Token
tokenTE :: Token
tokenMax :: Token
-- | For QPACK
tokenAccessControlAllowCredentials :: Token
tokenAccessControlAllowHeaders :: Token
tokenAccessControlAllowMethods :: Token
tokenAccessControlExposeHeaders :: Token
tokenAccessControlRequestHeaders :: Token
tokenAccessControlRequestMethod :: Token
tokenAltSvc :: Token
tokenContentSecurityPolicy :: Token
tokenEarlyData :: Token
tokenExpectCt :: Token
tokenForwarded :: Token
tokenOrigin :: Token
tokenPurpose :: Token
tokenTimingAllowOrigin :: Token
tokenUpgradeInsecureRequests :: Token
tokenXContentTypeOptions :: Token
tokenXForwardedFor :: Token
tokenXFrameOptions :: Token
tokenXXssProtection :: Token
module Network.HTTP.Semantics.Server
-- | Server type. Server takes a HTTP request, should generate a HTTP
-- response and push promises, then should give them to the sending
-- function. The sending function would throw exceptions so that they can
-- be logged.
type Server = Request -> Aux -> (Response -> [PushPromise] -> IO ()) -> IO ()
-- | Request from client.
data Request
-- | Getting the method from a request.
requestMethod :: Request -> Maybe Method
-- | Getting the path from a request.
requestPath :: Request -> Maybe Path
-- | Getting the authority from a request.
requestAuthority :: Request -> Maybe Authority
-- | Getting the scheme from a request.
requestScheme :: Request -> Maybe Scheme
-- | Getting the headers from a request.
requestHeaders :: Request -> TokenHeaderTable
-- | Getting the body size from a request.
requestBodySize :: Request -> Maybe Int
-- | Reading a chunk of the request body. An empty ByteString
-- returned when finished.
getRequestBodyChunk :: Request -> IO ByteString
-- | Reading request trailers. This function must be called after
-- getRequestBodyChunk returns an empty.
getRequestTrailers :: Request -> IO (Maybe TokenHeaderTable)
-- | Additional information.
data Aux
-- | Time handle for the worker processing this request and response.
auxTimeHandle :: Aux -> Handle
-- | Local socket address copied from Config.
auxMySockAddr :: Aux -> SockAddr
-- | Remove socket address copied from Config.
auxPeerSockAddr :: Aux -> SockAddr
-- | Response from server.
data Response
-- | Creating response without body.
responseNoBody :: Status -> ResponseHeaders -> Response
-- | Creating response with file.
responseFile :: Status -> ResponseHeaders -> FileSpec -> Response
-- | Creating response with streaming.
responseStreaming :: Status -> ResponseHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Response
-- | Creating response with builder.
responseBuilder :: Status -> ResponseHeaders -> Builder -> Response
-- | Getter for response body size. This value is available for file body.
responseBodySize :: Response -> Maybe Int
-- | 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 --type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker -- | Either the next trailers maker or final trailers. data NextTrailersMaker NextTrailersMaker :: TrailersMaker -> NextTrailersMaker Trailers :: [Header] -> NextTrailersMaker -- | TrailersMake to create no trailers. defaultTrailersMaker :: TrailersMaker -- | Setting TrailersMaker to Response. setResponseTrailersMaker :: Response -> TrailersMaker -> Response -- | HTTP/2 push promise or sever push. Pseudo REQUEST headers in push -- promise is automatically generated. Then, a server push is sent -- according to promiseResponse. data PushPromise PushPromise :: ByteString -> Response -> PushPromise -- | Accessor for a URL path in a push promise (a virtual request from a -- server). E.g. "/style/default.css". [promiseRequestPath] :: PushPromise -> ByteString -- | Accessor for response actually pushed from a server. [promiseResponse] :: PushPromise -> Response -- | Creating push promise. The third argument is traditional, not used. pushPromise :: ByteString -> Response -> Int -> PushPromise -- | Path. type Path = ByteString -- | Authority. type Authority = String -- | "http" or "https". type Scheme = ByteString -- | File specification. data FileSpec FileSpec :: FilePath -> FileOffset -> ByteCount -> FileSpec -- | Offset for file. type FileOffset = Int64 -- | How many bytes to read type ByteCount = Int64 -- | Reading n bytes. type ReadN = Int -> IO ByteString -- | Naive implementation for readN. defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN -- | Position read for files. type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount -- | Making a position read and its closer. type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) data Sentinel -- | Closing a file resource. Its refresher is automatiaclly generated by -- the internal timer. Closer :: IO () -> Sentinel -- | Refreshing a file resource while reading. Closing the file must be -- done by its own timer or something. Refresher :: IO () -> Sentinel -- | Position read based on Handle. defaultPositionReadMaker :: PositionReadMaker module Network.HTTP.Semantics.Client -- | Client type. type Client a = SendRequest -> Aux -> IO a -- | Send a request and receive its response. type SendRequest = forall r. Request -> (Response -> IO r) -> IO r -- | Request from client. data Request -- | Creating request without body. requestNoBody :: Method -> Path -> RequestHeaders -> Request -- | Creating request with file. requestFile :: Method -> Path -> RequestHeaders -> FileSpec -> Request -- | Creating request with streaming. requestStreaming :: Method -> Path -> RequestHeaders -> ((Builder -> IO ()) -> IO () -> IO ()) -> Request -- | Like requestStreaming, but run the action with exceptions -- masked requestStreamingUnmask :: Method -> Path -> RequestHeaders -> ((forall x. IO x -> IO x) -> (Builder -> IO ()) -> IO () -> IO ()) -> Request -- | Creating request with builder. requestBuilder :: Method -> Path -> RequestHeaders -> Builder -> Request -- | 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 --type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker -- | Either the next trailers maker or final trailers. data NextTrailersMaker NextTrailersMaker :: TrailersMaker -> NextTrailersMaker Trailers :: [Header] -> NextTrailersMaker -- | TrailersMake to create no trailers. defaultTrailersMaker :: TrailersMaker -- | Setting TrailersMaker to Response. setRequestTrailersMaker :: Request -> TrailersMaker -> Request -- | Response from server. data Response -- | Getting the status of a response. responseStatus :: Response -> Maybe Status -- | Getting the headers from a response. responseHeaders :: Response -> TokenHeaderTable -- | Getting the body size from a response. responseBodySize :: Response -> Maybe Int -- | Reading a chunk of the response body. An empty ByteString -- returned when finished. getResponseBodyChunk :: Response -> IO ByteString -- | Reading response trailers. This function must be called after -- getResponseBodyChunk returns an empty. getResponseTrailers :: Response -> IO (Maybe TokenHeaderTable) -- | Additional information. data Aux -- | How many streams can be created without blocking. auxPossibleClientStreams :: Aux -> IO Int -- | "http" or "https". type Scheme = ByteString -- | Authority. type Authority = String -- | HTTP method (flat ByteString type). type Method = ByteString -- | Path. type Path = ByteString -- | File specification. data FileSpec FileSpec :: FilePath -> FileOffset -> ByteCount -> FileSpec -- | Offset for file. type FileOffset = Int64 -- | How many bytes to read type ByteCount = Int64 -- | Reading n bytes. type ReadN = Int -> IO ByteString -- | Naive implementation for readN. defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN -- | Position read for files. type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount -- | Making a position read and its closer. type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) data Sentinel -- | Closing a file resource. Its refresher is automatiaclly generated by -- the internal timer. Closer :: IO () -> Sentinel -- | Refreshing a file resource while reading. Closing the file must be -- done by its own timer or something. Refresher :: IO () -> Sentinel -- | Position read based on Handle. defaultPositionReadMaker :: PositionReadMaker module Network.HTTP.Semantics.IO -- | Reading n bytes. type ReadN = Int -> IO ByteString -- | Naive implementation for readN. defaultReadN :: Socket -> IORef (Maybe ByteString) -> ReadN -- | Position read for files. type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount -- | Making a position read and its closer. type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel) data Sentinel -- | Closing a file resource. Its refresher is automatiaclly generated by -- the internal timer. Closer :: IO () -> Sentinel -- | Refreshing a file resource while reading. Closing the file must be -- done by its own timer or something. Refresher :: IO () -> Sentinel -- | Position read based on Handle. defaultPositionReadMaker :: PositionReadMaker data Next Next :: BytesFilled -> Bool -> Maybe DynaNext -> Next type DynaNext = Buffer -> BufferSize -> Int -> IO Next type BytesFilled = Int data StreamingChunk StreamingFinished :: IO () -> StreamingChunk StreamingFlush :: StreamingChunk StreamingBuilder :: Builder -> StreamingChunk fillBuilderBodyGetNext :: Builder -> DynaNext fillFileBodyGetNext :: PositionRead -> FileOffset -> ByteCount -> IO () -> DynaNext fillStreamBodyGetNext :: IO (Maybe StreamingChunk) -> DynaNext -- | 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 --type TrailersMaker = Maybe ByteString -> IO NextTrailersMaker -- | TrailersMake to create no trailers. defaultTrailersMaker :: TrailersMaker -- | Either the next trailers maker or final trailers. data NextTrailersMaker NextTrailersMaker :: TrailersMaker -> NextTrailersMaker Trailers :: [Header] -> NextTrailersMaker -- | Running trailers-maker. -- --
-- bufferIO buf siz $ \bs -> tlrmkr (Just bs) --runTrailersMaker :: TrailersMaker -> Buffer -> Int -> IO NextTrailersMaker