salvia-0.1: src/Network/Salvia/Handler/Environment.hs
module Network.Salvia.Handler.Environment (
hDefaultEnv
, hSessionEnv
) where
import Control.Concurrent.STM
import Network.Protocol.Http
import Network.Salvia.Handler.Banner
import Network.Salvia.Handler.Counter
import Network.Salvia.Handler.Close
import Network.Salvia.Handler.Error
import Network.Salvia.Handler.Head
import Network.Salvia.Handler.Log
import Network.Salvia.Handler.Parser
import Network.Salvia.Handler.Printer
import Network.Salvia.Handler.Session
import Network.Salvia.Httpd
import System.IO
{- |
This is the default stateless handler evnironment. It takes care of request
parsing (`hParser`), response printing (`hPrinter`), request logging (`hLog`),
connection keep-alives (`hKeepAlive`), handling `HEAD` requests (`hHead`) and
printing the `salvia-httpd` server banner (`hBanner`).
-}
hDefaultEnv
:: Handler () -- ^ Handler to run in the default environment.
-> Handler ()
hDefaultEnv handler =
hKeepAlive $
hParser (1000 * 15)
(wrapper Nothing . parseError)
(wrapper Nothing $ hHead handler)
{- |
This function is a more advanced version of the `hDefaultEnv` handler
environment that takes a global state into account. It takes a shared variable
containg the connection counter (used by `hCounter`) and a variable containing
all session information (used by `hSession`). Handlers that run in this
environment take should be parametrized with a session.
-}
hSessionEnv
:: TVar Int -- ^ Request count variable.
-> Sessions a -- ^ Session collection variable.
-> SessionHandler a () -- ^ Handler parametrized with current session.
-> Handler ()
hSessionEnv count sessions handler =
hKeepAlive $
hParser (1000 * 15)
(wrapper (Just count) . parseError)
(wrapper (Just count) $
do session <- hSession sessions 300
hHead (handler session))
-- Helper functions.
before :: Handler ()
before = hBanner "salvia-httpd"
after :: Maybe (TVar Int) -> Handler ()
after mc =
do hPrinter
maybe
(hLog stdout)
(\c -> hCounter c >> hLogWithCounter c stdout)
mc
wrapper :: Maybe (TVar Int) -> Handler a -> Handler ()
wrapper c h = before >> h >> after c
parseError :: String -> Handler ()
parseError err =
do hError BadRequest
sendStrLn []
sendStrLn err