Removed ErrorT from Handler
This commit is contained in:
parent
15055a8d43
commit
ce31a9c8ab
@ -8,6 +8,7 @@
|
|||||||
{-# LANGUAGE FunctionalDependencies #-}
|
{-# LANGUAGE FunctionalDependencies #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
--
|
--
|
||||||
-- Module : Yesod.Handler
|
-- Module : Yesod.Handler
|
||||||
@ -127,12 +128,11 @@ import Data.Time (UTCTime)
|
|||||||
import Control.Exception hiding (Handler, catch, finally)
|
import Control.Exception hiding (Handler, catch, finally)
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
|
||||||
import Control.Monad (liftM, join, MonadPlus)
|
import Control.Monad (liftM)
|
||||||
|
|
||||||
import Control.Monad.IO.Class
|
import Control.Monad.IO.Class
|
||||||
import Control.Monad.Trans.Class
|
import Control.Monad.Trans.Class
|
||||||
import Control.Monad.Trans.RWS
|
import Control.Monad.Trans.RWS
|
||||||
import Control.Monad.Trans.Error (throwError, ErrorT (..), Error (..))
|
|
||||||
|
|
||||||
import System.IO
|
import System.IO
|
||||||
import qualified Network.Wai as W
|
import qualified Network.Wai as W
|
||||||
@ -146,8 +146,6 @@ import Data.Text.Encoding (encodeUtf8, decodeUtf8With)
|
|||||||
import Data.Text.Encoding.Error (lenientDecode)
|
import Data.Text.Encoding.Error (lenientDecode)
|
||||||
import qualified Data.Text.Lazy as TL
|
import qualified Data.Text.Lazy as TL
|
||||||
|
|
||||||
import Control.Monad.IO.Control (MonadControlIO)
|
|
||||||
import Control.Monad.Trans.Control (MonadTransControl, liftControl)
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
@ -171,6 +169,7 @@ import Yesod.Internal.TestApi (catchIter)
|
|||||||
|
|
||||||
import qualified Yesod.Internal.Cache as Cache
|
import qualified Yesod.Internal.Cache as Cache
|
||||||
import Yesod.Internal.Cache (mkCacheKey, CacheKey)
|
import Yesod.Internal.Cache (mkCacheKey, CacheKey)
|
||||||
|
import Data.Typeable (Typeable)
|
||||||
|
|
||||||
-- | The type-safe URLs associated with a site argument.
|
-- | The type-safe URLs associated with a site argument.
|
||||||
type family Route a
|
type family Route a
|
||||||
@ -208,7 +207,7 @@ handlerSubDataMaybe tm ts route hd = hd
|
|||||||
withReaderT :: (HandlerData s m -> HandlerData s' m)
|
withReaderT :: (HandlerData s m -> HandlerData s' m)
|
||||||
-> GGHandler s' m mo a
|
-> GGHandler s' m mo a
|
||||||
-> GGHandler s m mo a
|
-> GGHandler s m mo a
|
||||||
withReaderT f (GHandler (ErrorT m)) = GHandler $ ErrorT $ withRWST (\r s -> (f r, s)) m
|
withReaderT f = withRWST (\r s -> (f r, s))
|
||||||
|
|
||||||
-- | Used internally for promoting subsite handler functions to master site
|
-- | Used internally for promoting subsite handler functions to master site
|
||||||
-- handler functions. Should not be needed by users.
|
-- handler functions. Should not be needed by users.
|
||||||
@ -253,14 +252,7 @@ toMasterHandlerMaybe tm ts route = withReaderT (handlerSubDataMaybe tm ts route)
|
|||||||
-- 'WriterT' for headers and session, and an 'MEitherT' monad for handling
|
-- 'WriterT' for headers and session, and an 'MEitherT' monad for handling
|
||||||
-- special responses. It is declared as a newtype to make compiler errors more
|
-- special responses. It is declared as a newtype to make compiler errors more
|
||||||
-- readable.
|
-- readable.
|
||||||
newtype GGHandler sub master m a =
|
type GGHandler sub master = RWST (HandlerData sub master) (Endo [Header]) GHState
|
||||||
GHandler
|
|
||||||
{ unGHandler :: GHInner sub master m a
|
|
||||||
}
|
|
||||||
deriving (Functor, Applicative, Monad, MonadIO, MonadControlIO, MonadPlus)
|
|
||||||
|
|
||||||
instance MonadTrans (GGHandler s m) where
|
|
||||||
lift = GHandler . lift . lift
|
|
||||||
|
|
||||||
type GHandler sub master = GGHandler sub master (Iteratee ByteString IO)
|
type GHandler sub master = GGHandler sub master (Iteratee ByteString IO)
|
||||||
|
|
||||||
@ -271,12 +263,6 @@ data GHState = GHState
|
|||||||
, ghsCache :: Cache.Cache
|
, ghsCache :: Cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
type GHInner s m monad =
|
|
||||||
ErrorT HandlerContents (
|
|
||||||
RWST (HandlerData s m) (Endo [Header]) GHState
|
|
||||||
monad
|
|
||||||
)
|
|
||||||
|
|
||||||
type SessionMap = Map.Map Text Text
|
type SessionMap = Map.Map Text Text
|
||||||
|
|
||||||
-- | An extension of the basic WAI 'W.Application' datatype to provide extra
|
-- | An extension of the basic WAI 'W.Application' datatype to provide extra
|
||||||
@ -302,25 +288,27 @@ data HandlerContents =
|
|||||||
| HCRedirect RedirectType Text
|
| HCRedirect RedirectType Text
|
||||||
| HCCreated Text
|
| HCCreated Text
|
||||||
| HCWai W.Response
|
| HCWai W.Response
|
||||||
|
deriving Typeable
|
||||||
|
|
||||||
instance Error HandlerContents where
|
instance Show HandlerContents where
|
||||||
strMsg = HCError . InternalError . T.pack
|
show _ = "Cannot show a HandlerContents"
|
||||||
|
instance Exception HandlerContents
|
||||||
|
|
||||||
getRequest :: Monad mo => GGHandler s m mo Request
|
getRequest :: Monad mo => GGHandler s m mo Request
|
||||||
getRequest = handlerRequest `liftM` gask
|
getRequest = handlerRequest `liftM` ask
|
||||||
|
|
||||||
instance Monad monad => Failure ErrorResponse (GGHandler sub master monad) where
|
instance MonadIO monad => Failure ErrorResponse (GGHandler sub master monad) where
|
||||||
failure = GHandler . throwError . HCError
|
failure = liftIO . throwIO . HCError
|
||||||
|
|
||||||
runRequestBody :: GHandler s m RequestBodyContents
|
runRequestBody :: GHandler s m RequestBodyContents
|
||||||
runRequestBody = do
|
runRequestBody = do
|
||||||
x <- GHandler $ lift get
|
x <- get
|
||||||
case ghsRBC x of
|
case ghsRBC x of
|
||||||
Just rbc -> return rbc
|
Just rbc -> return rbc
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
rr <- waiRequest
|
rr <- waiRequest
|
||||||
rbc <- lift $ rbHelper rr
|
rbc <- lift $ rbHelper rr
|
||||||
GHandler $ lift $ put x { ghsRBC = Just rbc }
|
put x { ghsRBC = Just rbc }
|
||||||
return rbc
|
return rbc
|
||||||
|
|
||||||
rbHelper :: W.Request -> Iteratee ByteString IO RequestBodyContents
|
rbHelper :: W.Request -> Iteratee ByteString IO RequestBodyContents
|
||||||
@ -335,36 +323,33 @@ rbHelper req =
|
|||||||
|
|
||||||
-- | Get the sub application argument.
|
-- | Get the sub application argument.
|
||||||
getYesodSub :: Monad m => GGHandler sub master m sub
|
getYesodSub :: Monad m => GGHandler sub master m sub
|
||||||
getYesodSub = handlerSub `liftM` gask
|
getYesodSub = handlerSub `liftM` ask
|
||||||
|
|
||||||
-- | Get the master site appliation argument.
|
-- | Get the master site appliation argument.
|
||||||
getYesod :: Monad m => GGHandler sub master m master
|
getYesod :: Monad m => GGHandler sub master m master
|
||||||
getYesod = handlerMaster `liftM` gask
|
getYesod = handlerMaster `liftM` ask
|
||||||
|
|
||||||
-- | Get the URL rendering function.
|
-- | Get the URL rendering function.
|
||||||
getUrlRender :: Monad m => GGHandler sub master m (Route master -> Text)
|
getUrlRender :: Monad m => GGHandler sub master m (Route master -> Text)
|
||||||
getUrlRender = do
|
getUrlRender = do
|
||||||
x <- handlerRender `liftM` gask
|
x <- handlerRender `liftM` ask
|
||||||
return $ flip x []
|
return $ flip x []
|
||||||
|
|
||||||
gask :: Monad m => GGHandler sub master m (HandlerData sub master)
|
|
||||||
gask = GHandler (lift ask)
|
|
||||||
|
|
||||||
-- | The URL rendering function with query-string parameters.
|
-- | The URL rendering function with query-string parameters.
|
||||||
getUrlRenderParams
|
getUrlRenderParams
|
||||||
:: Monad m
|
:: Monad m
|
||||||
=> GGHandler sub master m (Route master -> [(Text, Text)] -> Text)
|
=> GGHandler sub master m (Route master -> [(Text, Text)] -> Text)
|
||||||
getUrlRenderParams = handlerRender `liftM` gask
|
getUrlRenderParams = handlerRender `liftM` ask
|
||||||
|
|
||||||
-- | Get the route requested by the user. If this is a 404 response- where the
|
-- | Get the route requested by the user. If this is a 404 response- where the
|
||||||
-- user requested an invalid route- this function will return 'Nothing'.
|
-- user requested an invalid route- this function will return 'Nothing'.
|
||||||
getCurrentRoute :: Monad m => GGHandler sub master m (Maybe (Route sub))
|
getCurrentRoute :: Monad m => GGHandler sub master m (Maybe (Route sub))
|
||||||
getCurrentRoute = handlerRoute `liftM` gask
|
getCurrentRoute = handlerRoute `liftM` ask
|
||||||
|
|
||||||
-- | Get the function to promote a route for a subsite to a route for the
|
-- | Get the function to promote a route for a subsite to a route for the
|
||||||
-- master site.
|
-- master site.
|
||||||
getRouteToMaster :: Monad m => GGHandler sub master m (Route sub -> Route master)
|
getRouteToMaster :: Monad m => GGHandler sub master m (Route sub -> Route master)
|
||||||
getRouteToMaster = handlerToMaster `liftM` gask
|
getRouteToMaster = handlerToMaster `liftM` ask
|
||||||
|
|
||||||
-- | Function used internally by Yesod in the process of converting a
|
-- | Function used internally by Yesod in the process of converting a
|
||||||
-- 'GHandler' into an 'W.Application'. Should not be needed by users.
|
-- 'GHandler' into an 'W.Application'. Should not be needed by users.
|
||||||
@ -392,11 +377,13 @@ runHandler handler mrender sroute tomr ma sa =
|
|||||||
}
|
}
|
||||||
let initSession' = GHState initSession Nothing 1 mempty
|
let initSession' = GHState initSession Nothing 1 mempty
|
||||||
(contents', finalSession, headers) <- catchIter (
|
(contents', finalSession, headers) <- catchIter (
|
||||||
fmap (\(a, b, c) -> (a, ghsSession b, c))
|
fmap (\(a, b, c) -> (Right a, ghsSession b, c))
|
||||||
$ (\m -> runRWST m hd initSession')
|
$ runRWST handler hd initSession'
|
||||||
$ runErrorT
|
) (\e -> return (
|
||||||
$ unGHandler handler
|
case fromException e of
|
||||||
) (\e -> return (Left $ HCError $ toErrorHandler e, initSession, mempty))
|
Just x -> Left x
|
||||||
|
Nothing -> Left $ HCError $ toErrorHandler e
|
||||||
|
, initSession, mempty))
|
||||||
let contents = either id (HCContent H.status200 . chooseRep) contents'
|
let contents = either id (HCContent H.status200 . chooseRep) contents'
|
||||||
let handleError e = do
|
let handleError e = do
|
||||||
yar <- unYesodApp (eh e) safeEh rr cts finalSession
|
yar <- unYesodApp (eh e) safeEh rr cts finalSession
|
||||||
@ -441,11 +428,11 @@ safeEh er = YesodApp $ \_ _ _ session -> do
|
|||||||
session
|
session
|
||||||
|
|
||||||
-- | Redirect to the given route.
|
-- | Redirect to the given route.
|
||||||
redirect :: Monad mo => RedirectType -> Route master -> GGHandler sub master mo a
|
redirect :: MonadIO mo => RedirectType -> Route master -> GGHandler sub master mo a
|
||||||
redirect rt url = redirectParams rt url []
|
redirect rt url = redirectParams rt url []
|
||||||
|
|
||||||
-- | Redirects to the given route with the associated query-string parameters.
|
-- | Redirects to the given route with the associated query-string parameters.
|
||||||
redirectParams :: Monad mo
|
redirectParams :: MonadIO mo
|
||||||
=> RedirectType -> Route master -> [(Text, Text)]
|
=> RedirectType -> Route master -> [(Text, Text)]
|
||||||
-> GGHandler sub master mo a
|
-> GGHandler sub master mo a
|
||||||
redirectParams rt url params = do
|
redirectParams rt url params = do
|
||||||
@ -453,8 +440,8 @@ redirectParams rt url params = do
|
|||||||
redirectString rt $ r url params
|
redirectString rt $ r url params
|
||||||
|
|
||||||
-- | Redirect to the given URL.
|
-- | Redirect to the given URL.
|
||||||
redirectString, redirectText :: Monad mo => RedirectType -> Text -> GGHandler sub master mo a
|
redirectString, redirectText :: MonadIO mo => RedirectType -> Text -> GGHandler sub master mo a
|
||||||
redirectText rt = GHandler . throwError . HCRedirect rt
|
redirectText rt = liftIO . throwIO . HCRedirect rt
|
||||||
redirectString = redirectText
|
redirectString = redirectText
|
||||||
{-# DEPRECATED redirectString "Use redirectText instead" #-}
|
{-# DEPRECATED redirectString "Use redirectText instead" #-}
|
||||||
|
|
||||||
@ -489,7 +476,7 @@ setUltDest' = do
|
|||||||
Nothing -> return ()
|
Nothing -> return ()
|
||||||
Just r -> do
|
Just r -> do
|
||||||
tm <- getRouteToMaster
|
tm <- getRouteToMaster
|
||||||
gets' <- reqGetParams `liftM` handlerRequest `liftM` gask
|
gets' <- reqGetParams `liftM` handlerRequest `liftM` ask
|
||||||
render <- getUrlRenderParams
|
render <- getUrlRenderParams
|
||||||
setUltDestString $ render (tm r) gets'
|
setUltDestString $ render (tm r) gets'
|
||||||
|
|
||||||
@ -510,7 +497,7 @@ setUltDestReferer = do
|
|||||||
-- value from the session.
|
-- value from the session.
|
||||||
--
|
--
|
||||||
-- The ultimate destination is set with 'setUltDest'.
|
-- The ultimate destination is set with 'setUltDest'.
|
||||||
redirectUltDest :: Monad mo
|
redirectUltDest :: MonadIO mo
|
||||||
=> RedirectType
|
=> RedirectType
|
||||||
-> Route master -- ^ default destination if nothing in session
|
-> Route master -- ^ default destination if nothing in session
|
||||||
-> GGHandler sub master mo a
|
-> GGHandler sub master mo a
|
||||||
@ -554,52 +541,52 @@ getMessage = do
|
|||||||
--
|
--
|
||||||
-- For some backends, this is more efficient than reading in the file to
|
-- For some backends, this is more efficient than reading in the file to
|
||||||
-- memory, since they can optimize file sending via a system call to sendfile.
|
-- memory, since they can optimize file sending via a system call to sendfile.
|
||||||
sendFile :: Monad mo => ContentType -> FilePath -> GGHandler sub master mo a
|
sendFile :: MonadIO mo => ContentType -> FilePath -> GGHandler sub master mo a
|
||||||
sendFile ct fp = GHandler . throwError $ HCSendFile ct fp Nothing
|
sendFile ct fp = liftIO . throwIO $ HCSendFile ct fp Nothing
|
||||||
|
|
||||||
-- | Same as 'sendFile', but only sends part of a file.
|
-- | Same as 'sendFile', but only sends part of a file.
|
||||||
sendFilePart :: Monad mo
|
sendFilePart :: MonadIO mo
|
||||||
=> ContentType
|
=> ContentType
|
||||||
-> FilePath
|
-> FilePath
|
||||||
-> Integer -- ^ offset
|
-> Integer -- ^ offset
|
||||||
-> Integer -- ^ count
|
-> Integer -- ^ count
|
||||||
-> GGHandler sub master mo a
|
-> GGHandler sub master mo a
|
||||||
sendFilePart ct fp off count =
|
sendFilePart ct fp off count =
|
||||||
GHandler . throwError $ HCSendFile ct fp $ Just $ W.FilePart off count
|
liftIO . throwIO $ HCSendFile ct fp $ Just $ W.FilePart off count
|
||||||
|
|
||||||
-- | Bypass remaining handler code and output the given content with a 200
|
-- | Bypass remaining handler code and output the given content with a 200
|
||||||
-- status code.
|
-- status code.
|
||||||
sendResponse :: (Monad mo, HasReps c) => c -> GGHandler sub master mo a
|
sendResponse :: (MonadIO mo, HasReps c) => c -> GGHandler sub master mo a
|
||||||
sendResponse = GHandler . throwError . HCContent H.status200
|
sendResponse = liftIO . throwIO . HCContent H.status200
|
||||||
. chooseRep
|
. chooseRep
|
||||||
|
|
||||||
-- | Bypass remaining handler code and output the given content with the given
|
-- | Bypass remaining handler code and output the given content with the given
|
||||||
-- status code.
|
-- status code.
|
||||||
sendResponseStatus :: (Monad mo, HasReps c) => H.Status -> c -> GGHandler s m mo a
|
sendResponseStatus :: (MonadIO mo, HasReps c) => H.Status -> c -> GGHandler s m mo a
|
||||||
sendResponseStatus s = GHandler . throwError . HCContent s
|
sendResponseStatus s = liftIO . throwIO . HCContent s
|
||||||
. chooseRep
|
. chooseRep
|
||||||
|
|
||||||
-- | Send a 201 "Created" response with the given route as the Location
|
-- | Send a 201 "Created" response with the given route as the Location
|
||||||
-- response header.
|
-- response header.
|
||||||
sendResponseCreated :: Monad mo => Route m -> GGHandler s m mo a
|
sendResponseCreated :: MonadIO mo => Route m -> GGHandler s m mo a
|
||||||
sendResponseCreated url = do
|
sendResponseCreated url = do
|
||||||
r <- getUrlRender
|
r <- getUrlRender
|
||||||
GHandler $ throwError $ HCCreated $ r url
|
liftIO . throwIO $ HCCreated $ r url
|
||||||
|
|
||||||
-- | Send a 'W.Response'. Please note: this function is rarely
|
-- | Send a 'W.Response'. Please note: this function is rarely
|
||||||
-- necessary, and will /disregard/ any changes to response headers and session
|
-- necessary, and will /disregard/ any changes to response headers and session
|
||||||
-- that you have already specified. This function short-circuits. It should be
|
-- that you have already specified. This function short-circuits. It should be
|
||||||
-- considered only for very specific needs. If you are not sure if you need it,
|
-- considered only for very specific needs. If you are not sure if you need it,
|
||||||
-- you don't.
|
-- you don't.
|
||||||
sendWaiResponse :: Monad mo => W.Response -> GGHandler s m mo b
|
sendWaiResponse :: MonadIO mo => W.Response -> GGHandler s m mo b
|
||||||
sendWaiResponse = GHandler . throwError . HCWai
|
sendWaiResponse = liftIO . throwIO . HCWai
|
||||||
|
|
||||||
-- | Return a 404 not found page. Also denotes no handler available.
|
-- | Return a 404 not found page. Also denotes no handler available.
|
||||||
notFound :: Failure ErrorResponse m => m a
|
notFound :: Failure ErrorResponse m => m a
|
||||||
notFound = failure NotFound
|
notFound = failure NotFound
|
||||||
|
|
||||||
-- | Return a 405 method not supported page.
|
-- | Return a 405 method not supported page.
|
||||||
badMethod :: Monad mo => GGHandler s m mo a
|
badMethod :: MonadIO mo => GGHandler s m mo a
|
||||||
badMethod = do
|
badMethod = do
|
||||||
w <- waiRequest
|
w <- waiRequest
|
||||||
failure $ BadMethod $ W.requestMethod w
|
failure $ BadMethod $ W.requestMethod w
|
||||||
@ -609,7 +596,7 @@ permissionDenied :: Failure ErrorResponse m => Text -> m a
|
|||||||
permissionDenied = failure . PermissionDenied
|
permissionDenied = failure . PermissionDenied
|
||||||
|
|
||||||
-- | Return a 403 permission denied page.
|
-- | Return a 403 permission denied page.
|
||||||
permissionDeniedI :: (RenderMessage y msg, Monad mo) => msg -> GGHandler s y mo a
|
permissionDeniedI :: (RenderMessage y msg, MonadIO mo) => msg -> GGHandler s y mo a
|
||||||
permissionDeniedI msg = do
|
permissionDeniedI msg = do
|
||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
permissionDenied $ mr msg
|
permissionDenied $ mr msg
|
||||||
@ -619,7 +606,7 @@ invalidArgs :: Failure ErrorResponse m => [Text] -> m a
|
|||||||
invalidArgs = failure . InvalidArgs
|
invalidArgs = failure . InvalidArgs
|
||||||
|
|
||||||
-- | Return a 400 invalid arguments page.
|
-- | Return a 400 invalid arguments page.
|
||||||
invalidArgsI :: (RenderMessage y msg, Monad mo) => [msg] -> GGHandler s y mo a
|
invalidArgsI :: (RenderMessage y msg, MonadIO mo) => [msg] -> GGHandler s y mo a
|
||||||
invalidArgsI msg = do
|
invalidArgsI msg = do
|
||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
invalidArgs $ map mr msg
|
invalidArgs $ map mr msg
|
||||||
@ -679,18 +666,18 @@ setSession :: Monad mo
|
|||||||
=> Text -- ^ key
|
=> Text -- ^ key
|
||||||
-> Text -- ^ value
|
-> Text -- ^ value
|
||||||
-> GGHandler sub master mo ()
|
-> GGHandler sub master mo ()
|
||||||
setSession k = GHandler . lift . modify . modSession . Map.insert k
|
setSession k = modify . modSession . Map.insert k
|
||||||
|
|
||||||
-- | Unsets a session variable. See 'setSession'.
|
-- | Unsets a session variable. See 'setSession'.
|
||||||
deleteSession :: Monad mo => Text -> GGHandler sub master mo ()
|
deleteSession :: Monad mo => Text -> GGHandler sub master mo ()
|
||||||
deleteSession = GHandler . lift . modify . modSession . Map.delete
|
deleteSession = modify . modSession . Map.delete
|
||||||
|
|
||||||
modSession :: (SessionMap -> SessionMap) -> GHState -> GHState
|
modSession :: (SessionMap -> SessionMap) -> GHState -> GHState
|
||||||
modSession f x = x { ghsSession = f $ ghsSession x }
|
modSession f x = x { ghsSession = f $ ghsSession x }
|
||||||
|
|
||||||
-- | Internal use only, not to be confused with 'setHeader'.
|
-- | Internal use only, not to be confused with 'setHeader'.
|
||||||
addHeader :: Monad mo => Header -> GGHandler sub master mo ()
|
addHeader :: Monad mo => Header -> GGHandler sub master mo ()
|
||||||
addHeader = GHandler . lift . tell . Endo . (:)
|
addHeader = tell . Endo . (:)
|
||||||
|
|
||||||
getStatus :: ErrorResponse -> H.Status
|
getStatus :: ErrorResponse -> H.Status
|
||||||
getStatus NotFound = H.status404
|
getStatus NotFound = H.status404
|
||||||
@ -712,17 +699,17 @@ data RedirectType = RedirectPermanent
|
|||||||
|
|
||||||
localNoCurrent :: Monad mo => GGHandler s m mo a -> GGHandler s m mo a
|
localNoCurrent :: Monad mo => GGHandler s m mo a -> GGHandler s m mo a
|
||||||
localNoCurrent =
|
localNoCurrent =
|
||||||
GHandler . ErrorT . local (\hd -> hd { handlerRoute = Nothing }) . runErrorT . unGHandler
|
local (\hd -> hd { handlerRoute = Nothing })
|
||||||
|
|
||||||
-- | Lookup for session data.
|
-- | Lookup for session data.
|
||||||
lookupSession :: Monad mo => Text -> GGHandler s m mo (Maybe Text)
|
lookupSession :: Monad mo => Text -> GGHandler s m mo (Maybe Text)
|
||||||
lookupSession n = GHandler $ do
|
lookupSession n = do
|
||||||
m <- liftM ghsSession $ lift get
|
m <- liftM ghsSession get
|
||||||
return $ Map.lookup n m
|
return $ Map.lookup n m
|
||||||
|
|
||||||
-- | Get all session variables.
|
-- | Get all session variables.
|
||||||
getSession :: Monad mo => GGHandler s m mo SessionMap
|
getSession :: Monad mo => GGHandler s m mo SessionMap
|
||||||
getSession = liftM ghsSession $ GHandler $ lift get
|
getSession = liftM ghsSession get
|
||||||
|
|
||||||
handlerToYAR :: (HasReps a, HasReps b)
|
handlerToYAR :: (HasReps a, HasReps b)
|
||||||
=> m -- ^ master site foundation
|
=> m -- ^ master site foundation
|
||||||
@ -813,7 +800,7 @@ headerToPair _ _ (Header key value) = (key, value)
|
|||||||
|
|
||||||
-- | Get a unique identifier.
|
-- | Get a unique identifier.
|
||||||
newIdent :: Monad mo => GGHandler sub master mo String -- FIXME use Text
|
newIdent :: Monad mo => GGHandler sub master mo String -- FIXME use Text
|
||||||
newIdent = GHandler $ lift $ do
|
newIdent = do
|
||||||
x <- get
|
x <- get
|
||||||
let i' = ghsIdent x + 1
|
let i' = ghsIdent x + 1
|
||||||
put x { ghsIdent = i' }
|
put x { ghsIdent = i' }
|
||||||
@ -822,28 +809,8 @@ newIdent = GHandler $ lift $ do
|
|||||||
liftIOHandler :: MonadIO mo
|
liftIOHandler :: MonadIO mo
|
||||||
=> GGHandler sub master IO a
|
=> GGHandler sub master IO a
|
||||||
-> GGHandler sub master mo a
|
-> GGHandler sub master mo a
|
||||||
liftIOHandler m = GHandler $
|
liftIOHandler (RWST m) = RWST $ \r s ->
|
||||||
ErrorT $
|
liftIO (m r s)
|
||||||
RWST $ \r s ->
|
|
||||||
liftIO (runGGHandler m r s)
|
|
||||||
|
|
||||||
runGGHandler :: GGHandler sub master m a
|
|
||||||
-> HandlerData sub master
|
|
||||||
-> GHState
|
|
||||||
-> m (Either HandlerContents a, GHState, Endo [Header])
|
|
||||||
runGGHandler (GHandler (ErrorT m)) r s = runRWST m r s
|
|
||||||
|
|
||||||
instance MonadTransControl (GGHandler s m) where
|
|
||||||
liftControl f =
|
|
||||||
GHandler $
|
|
||||||
liftControl $ \runErr ->
|
|
||||||
liftControl $ \runRws ->
|
|
||||||
f ( liftM ( GHandler
|
|
||||||
. join . lift
|
|
||||||
)
|
|
||||||
. runRws . runErr
|
|
||||||
. unGHandler
|
|
||||||
)
|
|
||||||
|
|
||||||
-- | Redirect to a POST resource.
|
-- | Redirect to a POST resource.
|
||||||
--
|
--
|
||||||
@ -851,7 +818,7 @@ instance MonadTransControl (GGHandler s m) where
|
|||||||
-- POST form, and some Javascript to automatically submit the form. This can be
|
-- POST form, and some Javascript to automatically submit the form. This can be
|
||||||
-- useful when you need to post a plain link somewhere that needs to cause
|
-- useful when you need to post a plain link somewhere that needs to cause
|
||||||
-- changes on the server.
|
-- changes on the server.
|
||||||
redirectToPost :: Monad mo => Route master -> GGHandler sub master mo a
|
redirectToPost :: MonadIO mo => Route master -> GGHandler sub master mo a
|
||||||
redirectToPost dest = hamletToRepHtml
|
redirectToPost dest = hamletToRepHtml
|
||||||
#if GHC7
|
#if GHC7
|
||||||
[hamlet|
|
[hamlet|
|
||||||
@ -895,13 +862,13 @@ getMessageRender = do
|
|||||||
|
|
||||||
cacheLookup :: Monad mo => CacheKey a -> GGHandler sub master mo (Maybe a)
|
cacheLookup :: Monad mo => CacheKey a -> GGHandler sub master mo (Maybe a)
|
||||||
cacheLookup k = do
|
cacheLookup k = do
|
||||||
gs <- GHandler $ lift get
|
gs <- get
|
||||||
return $ Cache.lookup k $ ghsCache gs
|
return $ Cache.lookup k $ ghsCache gs
|
||||||
|
|
||||||
cacheInsert :: Monad mo => CacheKey a -> a -> GGHandler sub master mo ()
|
cacheInsert :: Monad mo => CacheKey a -> a -> GGHandler sub master mo ()
|
||||||
cacheInsert k v = GHandler $ lift $ modify $ \gs ->
|
cacheInsert k v = modify $ \gs ->
|
||||||
gs { ghsCache = Cache.insert k v $ ghsCache gs }
|
gs { ghsCache = Cache.insert k v $ ghsCache gs }
|
||||||
|
|
||||||
cacheDelete :: Monad mo => CacheKey a -> GGHandler sub master mo ()
|
cacheDelete :: Monad mo => CacheKey a -> GGHandler sub master mo ()
|
||||||
cacheDelete k = GHandler $ lift $ modify $ \gs ->
|
cacheDelete k = modify $ \gs ->
|
||||||
gs { ghsCache = Cache.delete k $ ghsCache gs }
|
gs { ghsCache = Cache.delete k $ ghsCache gs }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user