salvia-0.1: src/Network/Salvia/Handler/Close.hs
module Network.Salvia.Handler.Close (
hCloseConn
, hKeepAlive
) where
import Control.Monad.State
import Data.Maybe
import Data.Record.Label
import Network.Protocol.Http
import Network.Salvia.Httpd
import System.IO
{- |
Run a handler once and close the connection afterwards.
-}
hCloseConn :: Handler () -> Handler ()
hCloseConn h = h >> getM sock >>= liftIO . hClose
{- |
Run a handler and keep the connection open for potential consecutive requests.
The connection will only be closed after a request finished and one or more of
the following criteria are met:
* There is no `contentLength` set in the response headers. When this is the
case the connection cannot be kept alive.
* The client has set the `connection` header field to 'close'.
* The connection has already been closed, possible due to IO errors.
-}
hKeepAlive :: Handler () -> Handler ()
hKeepAlive handler =
do handler
h <- getM sock
conn <- getM (connection % request)
len <- getM (contentLength % response)
closed <- liftIO (hIsClosed h)
if or [closed, conn == "Close", isNothing (len::Maybe Integer) ]
then liftIO (hClose h)
else resetContext >> hKeepAlive handler
resetContext :: Handler ()
resetContext =
do setM request emptyRequest
setM response emptyResponse
setM queue []