-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Second Transfer HTTP/2 web server -- @package second-transfer @version 0.2.0.0 module SecondTransfer.Exception -- | Abstract exception. All HTTP/2 exceptions derive from here data HTTP2SessionException HTTP2SessionException :: e -> HTTP2SessionException -- | Abstract exception. Thrown when encoding/decoding of a frame fails data FramerException FramerException :: e -> FramerException -- | Thrown when the HTTP/2 connection prefix doesn't match the expected -- prefix. data BadPrefaceException BadPrefaceException :: BadPrefaceException instance Typeable HTTP2SessionException instance Typeable FramerException instance Typeable BadPrefaceException instance Show BadPrefaceException instance Exception BadPrefaceException instance Exception FramerException instance Show FramerException instance Exception HTTP2SessionException instance Show HTTP2SessionException module SecondTransfer.Http2 -- | Thrown when the HTTP/2 connection prefix doesn't match the expected -- prefix. data BadPrefaceException -- | The type of this function is equivalent to: -- --
--   http2Attendant :: CoherentWorker -> PushAction -> PullAction -> CloseAction ->  IO ()
--   
-- -- Given a CoherentWorker, this function wraps it with flow -- control, multiplexing, and state maintenance needed to run an HTTP/2 -- session. http2Attendant :: SessionsContext -> CoherentWorker -> Attendant makeSessionsContext :: SessionsConfig -> IO SessionsContext -- | Creates a default sessions context. Modify as needed using the lenses -- interfaces defaultSessionsConfig :: SessionsConfig -- | Configuration information you can provide to the session maker. data SessionsConfig -- | Contains information that applies to all sessions created in the -- program. Use the lenses interface to access members of this struct. data SessionsContext -- | Callbacks that you can provide your sessions to notify you of -- interesting things happening in the server. data SessionsCallbacks -- | Used by this session engine to report an error at some component, in a -- particular session. type ErrorCallback = (SessionComponent, SessionCoordinates, SomeException) -> IO () -- | Lens to access sessionsCallbacks in the SessionsConfig object. sessionsCallbacks :: Lens' SessionsConfig SessionsCallbacks reportErrorCallback :: Iso' SessionsCallbacks (Maybe ErrorCallback) module SecondTransfer.MainLoop.Internal readNextChunkAndContinue :: Monad m => LengthCallback -> ByteString -> m ByteString -> m (ByteString, ByteString) http2FrameLength :: LengthCallback type OutputFrame = (EncodeInfo, FramePayload) type InputFrame = Frame module SecondTransfer.MainLoop -- | A function which takes three arguments: the first one says how to send -- data (on a socket or similar transport), and the second one how to -- receive data on said socket. The third argument encapsulates the -- sequence of steps needed for a clean shutdown. -- -- You can implement one of these to let somebody else supply the push, -- pull and close callbacks. In this library we supply callbacks for TLS -- sockets, so that you don't need to go through the drudgery of managing -- those yourself. -- -- Attendants encapsulate all the session book-keeping functionality, -- which for HTTP/2 is quite complicated. You use the function -- http2Attendant to create one of these from a -- CoherentWorker. type Attendant = PushAction -> PullAction -> CloseAction -> IO () -- | Callback type to pull data from a channel. The same as to PushAction -- applies to exceptions thrown from there. type PullAction = IO ByteString -- | Callback type to push data to a channel. Part of this interface is the -- abstract exception type IOProblem. Throw an instance of it from here -- to notify the session that the connection has been broken. There is no -- way to signal "normal termination", since HTTP/2's normal termination -- can be observed at a higher level when a GO_AWAY frame is seen. type PushAction = ByteString -> IO () -- | Callback that the session calls to realease resources associated with -- the channels. Take into account that your callback should be able to -- deal with non-clean shutdowns also, for example, if the connection to -- the remote peer is severed suddenly. type CloseAction = IO () -- | Throw exceptions derived from this (e.g, GenericIOProblem -- below) to have the HTTP/2 session to terminate gracefully. data IOProblem -- | A concrete case of the above exception. Throw one of this if you don't -- want to implement your own type. Use IOProblem in catch -- signatures. data GenericIOProblem -- | Simple function to open tlsServeWithALPN :: FilePath -> FilePath -> String -> [(String, Attendant)] -> Int -> IO () -- | Interruptible version of tlsServeWithALPN. Use the extra -- argument to notify the server of finishing. tlsServeWithALPNAndFinishOnRequest :: FilePath -> FilePath -> String -> [(String, Attendant)] -> Int -> MVar FinishRequest -> IO () -- | Exception inheriting from IOProblem. This is thrown by the -- OpenSSL subsystem to signal that the connection was broken or that -- otherwise there was a problem at the SSL layer. data TLSLayerGenericProblem TLSLayerGenericProblem :: String -> TLSLayerGenericProblem -- | Singleton type. Used in conjunction with an MVar. If the MVar -- is full, the fuction tlsServeWithALPNAndFinishOnRequest knows -- that it should finish at its earliest convenience and call the -- CloseAction for any open sessions. data FinishRequest FinishRequest :: FinishRequest -- | This library implements enough of the HTTP/2 to build compliant HTTP/2 -- servers. The library -- -- -- -- Setting up TLS for HTTP/2 correctly is enough of a shore, so I have -- bundled here the TLS setup logic. -- -- Frame encoding and decoding is done with Kazu Yamamoto's http2 -- package. -- -- Here is how you create a very basic HTTP/2 webserver: -- --
--   import SecondTransfer(
--       CoherentWorker
--       , Footers
--       , DataAndConclusion
--       , tlsServeWithALPN
--       , http2Attendant
--       )
--   import SecondTransfer.Http2(
--         makeSessionsContext
--       , defaultSessionsConfig
--       )
--   
--   import Data.Conduit
--   
--   
--   saysHello :: DataAndConclusion
--   saysHello = do 
--       yield "Hello world!"
--       -- No footers
--       return []
--   
--   
--   helloWorldWorker :: CoherentWorker
--   helloWorldWorker request = return (
--       [
--           (":status", "200")
--       ],
--       [], -- No pushed streams
--       saysHello
--       )
--   
--   
--   -- For this program to work, it should be run from the top of 
--   -- the developement directory.
--   main = do 
--       sessions_context <- makeSessionsContext defaultSessionsConfig
--       let 
--           http2_attendant = http2Attendant sessions_context helloWorldWorker
--       tlsServeWithALPN
--           "tests/support/servercert.pem"   -- Server certificate
--           "tests/support/privkey.pem"      -- Certificate private key
--           "127.0.0.1"                      -- On which interface to bind
--           [
--               ("h2-14", http2_attendant),  -- Protocols present in the ALPN negotiation
--               ("h2",    http2_attendant)   -- they may be slightly different, but for this 
--                                            -- test it doesn't matter.
--           ]
--           8000 
--   
-- -- CoherentWorker is the type of the basic callback function that -- you need to implement. The callback is used to handle all requests to -- the server on a given negotiated ALPN protocol. If you need routing -- functionality (and you most certainly will need it), you need to build -- that functionality inside the callback. -- -- The above program uses a test certificate by a fake certificate -- authority. The certificate is valid for the server name ("authority", -- in HTTP/2 lingo) www.httpdos.com. So, in order for the above program -- to run, you probably need to add an alias to your /etc/hosts file. You -- also need very up-to-date versions of OpenSSL (I'm using OpenSSL -- 1.0.2) to be compliant with the cipher suites demanded by HTTP/2. The -- easiest way to test the above program is using a fairly recent version -- of curl. If everything is allright, you should be able to do: -- --
--   $ curl -k --http2 https://www.httpdos.com:8000/
--   Hello world!
--   
module SecondTransfer -- | List of headers. The first part of each tuple is the header name (be -- sure to conform to the HTTP/2 convention of using lowercase) and the -- second part is the headers contents. This list needs to include the -- special :method, :scheme, :authority and :path pseudo-headers for -- requests; and :status (with a plain numeric value represented in ascii -- digits) for responses. type Headers = [(ByteString, ByteString)] -- | A request is a set of headers and a request body.... which will -- normally be empty, except for POST and PUT requests. But this library -- enforces none of that. type Request = (Headers, Maybe InputDataStream) -- | Finalization headers type Footers = FinalizationHeaders -- | Main type of this library. You implement one of these for your server. -- Basically this is a callback that the library calls as soon as it has -- all the headers of a request. For GET requests that's the entire -- request basically, but for POST and PUT requests this is just before -- the data starts arriving to the server. type CoherentWorker = Request -> IO PrincipalStream -- | You use this type to answer a request. The Headers are thus -- response headers and they should contain the :status pseudo-header. -- The PushedStreams is a list of pushed streams...(I don't thaink -- that I'm handling those yet) type PrincipalStream = (Headers, PushedStreams, DataAndConclusion) -- | A list of pushed streams type PushedStreams = [IO PushedStream] -- | A pushed stream, represented by a list of request headers, a list of -- response headers, and the usual response body (which may include final -- footers (not implemented yet)). type PushedStream = (Headers, Headers, DataAndConclusion) -- | A source-like conduit with the data returned in the response. The -- return value of the conduit is a list of footers. For now that list -- can be anything (even bottom), I'm not handling it just yet. type DataAndConclusion = ConduitM () ByteString IO Footers -- | This is a Source conduit (see Haskell Data.Conduit library from -- Michael Snoyman) that you can use to retrieve the data sent by the -- client piece-wise. type InputDataStream = Source IO ByteString -- | Finalization headers. If you don't know what they are, chances are -- that you don't need to worry about them for now. The support in this -- library for those are at best sketchy. type FinalizationHeaders = Headers -- | A function which takes three arguments: the first one says how to send -- data (on a socket or similar transport), and the second one how to -- receive data on said socket. The third argument encapsulates the -- sequence of steps needed for a clean shutdown. -- -- You can implement one of these to let somebody else supply the push, -- pull and close callbacks. In this library we supply callbacks for TLS -- sockets, so that you don't need to go through the drudgery of managing -- those yourself. -- -- Attendants encapsulate all the session book-keeping functionality, -- which for HTTP/2 is quite complicated. You use the function -- http2Attendant to create one of these from a -- CoherentWorker. type Attendant = PushAction -> PullAction -> CloseAction -> IO () -- | Callback type to pull data from a channel. The same as to PushAction -- applies to exceptions thrown from there. type PullAction = IO ByteString -- | Callback type to push data to a channel. Part of this interface is the -- abstract exception type IOProblem. Throw an instance of it from here -- to notify the session that the connection has been broken. There is no -- way to signal "normal termination", since HTTP/2's normal termination -- can be observed at a higher level when a GO_AWAY frame is seen. type PushAction = ByteString -> IO () -- | Callback that the session calls to realease resources associated with -- the channels. Take into account that your callback should be able to -- deal with non-clean shutdowns also, for example, if the connection to -- the remote peer is severed suddenly. type CloseAction = IO () -- | The type of this function is equivalent to: -- --
--   http2Attendant :: CoherentWorker -> PushAction -> PullAction -> CloseAction ->  IO ()
--   
-- -- Given a CoherentWorker, this function wraps it with flow -- control, multiplexing, and state maintenance needed to run an HTTP/2 -- session. http2Attendant :: SessionsContext -> CoherentWorker -> Attendant -- | Throw exceptions derived from this (e.g, GenericIOProblem -- below) to have the HTTP/2 session to terminate gracefully. data IOProblem -- | A concrete case of the above exception. Throw one of this if you don't -- want to implement your own type. Use IOProblem in catch -- signatures. data GenericIOProblem -- | Simple function to open tlsServeWithALPN :: FilePath -> FilePath -> String -> [(String, Attendant)] -> Int -> IO () -- | Interruptible version of tlsServeWithALPN. Use the extra -- argument to notify the server of finishing. tlsServeWithALPNAndFinishOnRequest :: FilePath -> FilePath -> String -> [(String, Attendant)] -> Int -> MVar FinishRequest -> IO () -- | Exception inheriting from IOProblem. This is thrown by the -- OpenSSL subsystem to signal that the connection was broken or that -- otherwise there was a problem at the SSL layer. data TLSLayerGenericProblem TLSLayerGenericProblem :: String -> TLSLayerGenericProblem -- | Singleton type. Used in conjunction with an MVar. If the MVar -- is full, the fuction tlsServeWithALPNAndFinishOnRequest knows -- that it should finish at its earliest convenience and call the -- CloseAction for any open sessions. data FinishRequest FinishRequest :: FinishRequest