{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Yesod.Core.Handler
(
HandlerT
, HandlerFor
, getYesod
, getsYesod
, getUrlRender
, getUrlRenderParams
, getPostParams
, getCurrentRoute
, getRequest
, waiRequest
, runRequestBody
, rawRequestBody
, RequestBodyContents
, YesodRequest (..)
, FileInfo
, fileName
, fileContentType
, fileSource
, fileSourceByteString
, fileMove
, languages
, lookupGetParam
, lookupPostParam
, lookupCookie
, lookupFile
, lookupHeader
, lookupBasicAuth
, lookupBearerAuth
, lookupGetParams
, lookupPostParams
, lookupCookies
, lookupFiles
, lookupHeaders
, respond
, respondSource
, sendChunk
, sendFlush
, sendChunkBS
, sendChunkLBS
, sendChunkText
, sendChunkLazyText
, sendChunkHtml
, RedirectUrl (..)
, redirect
, redirectWith
, redirectToPost
, Fragment(..)
, notFound
, badMethod
, notAuthenticated
, permissionDenied
, permissionDeniedI
, invalidArgs
, invalidArgsI
, sendFile
, sendFilePart
, sendResponse
, sendResponseStatus
, sendStatusJSON
, sendResponseCreated
, sendResponseNoContent
, sendWaiResponse
, sendWaiApplication
, sendRawResponse
, sendRawResponseNoConduit
, notModified
, selectRep
, provideRep
, provideRepType
, ProvidedRep
, setCookie
, getExpires
, deleteCookie
, addHeader
, setHeader
, replaceOrAddHeader
, setLanguage
, addContentDispositionFileName
, cacheSeconds
, neverExpires
, alreadyExpired
, expiresAt
, setEtag
, setWeakEtag
, SessionMap
, lookupSession
, lookupSessionBS
, getSession
, setSession
, setSessionBS
, deleteSession
, clearSession
, setUltDest
, setUltDestCurrent
, setUltDestReferer
, redirectUltDest
, clearUltDest
, addMessage
, addMessageI
, getMessages
, setMessage
, setMessageI
, getMessage
, SubHandlerFor
, getSubYesod
, getRouteToParent
, getSubCurrentRoute
, hamletToRepHtml
, giveUrlRenderer
, withUrlRenderer
, newIdent
, handlerToIO
, forkHandler
, getMessageRender
, cached
, cacheGet
, cacheSet
, cachedBy
, cacheByGet
, cacheBySet
, setCsrfCookie
, setCsrfCookieWithCookie
, defaultCsrfCookieName
, checkCsrfHeaderNamed
, hasValidCsrfHeaderNamed
, defaultCsrfHeaderName
, hasValidCsrfParamNamed
, checkCsrfParamNamed
, defaultCsrfParamName
, checkCsrfHeaderOrParam
) where
import Data.Time (UTCTime, addUTCTime,
getCurrentTime)
import Yesod.Core.Internal.Request (langKey, mkFileInfoFile,
mkFileInfoLBS, mkFileInfoSource)
import Control.Applicative ((<|>))
import qualified Data.CaseInsensitive as CI
import Control.Exception (evaluate, SomeException, throwIO)
import Control.Exception (handle)
import Control.Monad (void, liftM, unless)
import qualified Control.Monad.Trans.Writer as Writer
import UnliftIO (MonadIO, liftIO, MonadUnliftIO, withRunInIO)
import qualified Network.HTTP.Types as H
import qualified Network.Wai as W
import Network.Wai.Middleware.HttpAuth
( extractBasicAuth, extractBearerAuth )
import Control.Monad.Trans.Class (lift)
import Data.Aeson (ToJSON(..))
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8With, encodeUtf8, decodeUtf8)
import Data.Text.Encoding.Error (lenientDecode)
import qualified Data.Text.Lazy as TL
import Text.Blaze.Html.Renderer.Utf8 (renderHtml)
import Text.Hamlet (Html, HtmlUrl, hamlet)
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import qualified Data.Map as Map
import qualified Data.HashMap.Strict as HM
import Data.ByteArray (constEq)
import Control.Arrow ((***))
import qualified Data.ByteString.Char8 as S8
import Data.Monoid (Endo (..))
import Data.Text (Text)
import qualified Network.Wai.Parse as NWP
import Text.Shakespeare.I18N (RenderMessage (..))
import Web.Cookie (SetCookie (..), defaultSetCookie)
import Yesod.Core.Content (ToTypedContent (..), simpleContentType, contentTypeTypes, HasContentType (..), ToContent (..), ToFlushBuilder (..))
import Yesod.Core.Internal.Util (formatRFC1123)
import Text.Blaze.Html (preEscapedToHtml, toHtml)
import qualified Data.IORef as I
import Data.Maybe (listToMaybe, mapMaybe)
import Data.Typeable (Typeable)
import Data.Kind (Type)
import Web.PathPieces (PathPiece(..))
import Yesod.Core.Class.Handler
import Yesod.Core.Types
import Yesod.Routes.Class (Route)
import Data.ByteString.Builder (Builder)
import Data.CaseInsensitive (CI, original)
import qualified Data.Conduit.List as CL
import Control.Monad.Trans.Resource (MonadResource, InternalState, runResourceT, withInternalState, getInternalState, liftResourceT, resourceForkIO)
import qualified System.PosixCompat.Files as PC
import Conduit ((.|), runConduit, sinkLazy)
import Data.Conduit (ConduitT, transPipe, Flush (Flush), yield, Void)
import qualified Yesod.Core.TypeCache as Cache
import qualified Data.Word8 as W8
import qualified Data.Foldable as Fold
import Control.Monad.Logger (MonadLogger, logWarnS)
type HandlerT site (m :: Type -> Type) = HandlerFor site
{-# DEPRECATED HandlerT "Use HandlerFor directly" #-}
get :: MonadHandler m => m GHState
get :: forall (m :: * -> *). MonadHandler m => m GHState
get = forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
I.readIORef forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. HandlerData child site -> IORef GHState
handlerState
put :: MonadHandler m => GHState -> m ()
put :: forall (m :: * -> *). MonadHandler m => GHState -> m ()
put GHState
x = forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. IORef a -> a -> IO ()
I.writeIORef GHState
x forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. HandlerData child site -> IORef GHState
handlerState
modify :: MonadHandler m => (GHState -> GHState) -> m ()
modify :: forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify GHState -> GHState
f = forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. IORef a -> (a -> a) -> IO ()
I.modifyIORef GHState -> GHState
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. HandlerData child site -> IORef GHState
handlerState
tell :: MonadHandler m => Endo [Header] -> m ()
tell :: forall (m :: * -> *). MonadHandler m => Endo [Header] -> m ()
tell Endo [Header]
hs = forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \GHState
g -> GHState
g { ghsHeaders :: Endo [Header]
ghsHeaders = GHState -> Endo [Header]
ghsHeaders GHState
g forall a. Monoid a => a -> a -> a
`mappend` Endo [Header]
hs }
handlerError :: MonadHandler m => HandlerContents -> m a
handlerError :: forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a. Exception e => e -> IO a
throwIO
hcError :: MonadHandler m => ErrorResponse -> m a
hcError :: forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErrorResponse -> HandlerContents
HCError
getRequest :: MonadHandler m => m YesodRequest
getRequest :: forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest = forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. HandlerData child site -> YesodRequest
handlerRequest
runRequestBody :: MonadHandler m => m RequestBodyContents
runRequestBody :: forall (m :: * -> *). MonadHandler m => m RequestBodyContents
runRequestBody = do
HandlerData
{ handlerEnv :: forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv = RunHandlerEnv {Maybe (Route (HandlerSite m))
Text
HandlerSite m
Loc -> Text -> LogLevel -> LogStr -> IO ()
RequestBodyLength -> FileUpload
Route (HandlerSite m) -> Route (HandlerSite m)
Route (HandlerSite m) -> [(Text, Text)] -> Text
ErrorResponse -> YesodApp
forall a (m :: * -> *).
MonadUnliftIO m =>
m a -> (SomeException -> m a) -> m a
rheCatchHandlerExceptions :: forall child site.
RunHandlerEnv child site
-> forall a (m :: * -> *).
MonadUnliftIO m =>
m a -> (SomeException -> m a) -> m a
rheMaxExpires :: forall child site. RunHandlerEnv child site -> Text
rheOnError :: forall child site.
RunHandlerEnv child site -> ErrorResponse -> YesodApp
rheLog :: forall child site.
RunHandlerEnv child site
-> Loc -> Text -> LogLevel -> LogStr -> IO ()
rheUpload :: forall child site.
RunHandlerEnv child site -> RequestBodyLength -> FileUpload
rheChild :: forall child site. RunHandlerEnv child site -> child
rheSite :: forall child site. RunHandlerEnv child site -> site
rheRouteToMaster :: forall child site.
RunHandlerEnv child site -> Route child -> Route site
rheRoute :: forall child site. RunHandlerEnv child site -> Maybe (Route child)
rheRender :: forall child site.
RunHandlerEnv child site -> Route site -> [(Text, Text)] -> Text
rheCatchHandlerExceptions :: forall a (m :: * -> *).
MonadUnliftIO m =>
m a -> (SomeException -> m a) -> m a
rheMaxExpires :: Text
rheOnError :: ErrorResponse -> YesodApp
rheLog :: Loc -> Text -> LogLevel -> LogStr -> IO ()
rheUpload :: RequestBodyLength -> FileUpload
rheChild :: HandlerSite m
rheSite :: HandlerSite m
rheRouteToMaster :: Route (HandlerSite m) -> Route (HandlerSite m)
rheRoute :: Maybe (Route (HandlerSite m))
rheRender :: Route (HandlerSite m) -> [(Text, Text)] -> Text
..}
, handlerRequest :: forall child site. HandlerData child site -> YesodRequest
handlerRequest = YesodRequest
req
} <- forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall (m :: * -> *) a. Monad m => a -> m a
return
let len :: RequestBodyLength
len = Request -> RequestBodyLength
W.requestBodyLength forall a b. (a -> b) -> a -> b
$ YesodRequest -> Request
reqWaiRequest YesodRequest
req
upload :: FileUpload
upload = RequestBodyLength -> FileUpload
rheUpload RequestBodyLength
len
GHState
x <- forall (m :: * -> *). MonadHandler m => m GHState
get
case GHState -> Maybe RequestBodyContents
ghsRBC GHState
x of
Just RequestBodyContents
rbc -> forall (m :: * -> *) a. Monad m => a -> m a
return RequestBodyContents
rbc
Maybe RequestBodyContents
Nothing -> do
Request
rr <- forall (m :: * -> *). MonadHandler m => m Request
waiRequest
InternalState
internalState <- forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
liftResourceT forall (m :: * -> *). Monad m => ResourceT m InternalState
getInternalState
RequestBodyContents
rbc <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ FileUpload -> Request -> InternalState -> IO RequestBodyContents
rbHelper FileUpload
upload Request
rr InternalState
internalState
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put GHState
x { ghsRBC :: Maybe RequestBodyContents
ghsRBC = forall a. a -> Maybe a
Just RequestBodyContents
rbc }
forall (m :: * -> *) a. Monad m => a -> m a
return RequestBodyContents
rbc
rbHelper :: FileUpload -> W.Request -> InternalState -> IO RequestBodyContents
rbHelper :: FileUpload -> Request -> InternalState -> IO RequestBodyContents
rbHelper FileUpload
upload Request
req InternalState
internalState =
case FileUpload
upload of
FileUploadMemory BackEnd ByteString
s -> forall x.
BackEnd x
-> (Text -> Text -> x -> FileInfo)
-> Request
-> IO RequestBodyContents
rbHelper' BackEnd ByteString
s Text -> Text -> ByteString -> FileInfo
mkFileInfoLBS Request
req
FileUploadDisk InternalState -> BackEnd FilePath
s -> forall x.
BackEnd x
-> (Text -> Text -> x -> FileInfo)
-> Request
-> IO RequestBodyContents
rbHelper' (InternalState -> BackEnd FilePath
s InternalState
internalState) Text -> Text -> FilePath -> FileInfo
mkFileInfoFile Request
req
FileUploadSource BackEnd (ConduitT () ByteString (ResourceT IO) ())
s -> forall x.
BackEnd x
-> (Text -> Text -> x -> FileInfo)
-> Request
-> IO RequestBodyContents
rbHelper' BackEnd (ConduitT () ByteString (ResourceT IO) ())
s Text
-> Text -> ConduitT () ByteString (ResourceT IO) () -> FileInfo
mkFileInfoSource Request
req
rbHelper' :: NWP.BackEnd x
-> (Text -> Text -> x -> FileInfo)
-> W.Request
-> IO ([(Text, Text)], [(Text, FileInfo)])
rbHelper' :: forall x.
BackEnd x
-> (Text -> Text -> x -> FileInfo)
-> Request
-> IO RequestBodyContents
rbHelper' BackEnd x
backend Text -> Text -> x -> FileInfo
mkFI Request
req =
(forall a b. (a -> b) -> [a] -> [b]
map Param -> (Text, Text)
fix1 forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe File x -> Maybe (Text, FileInfo)
fix2) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall y. BackEnd y -> Request -> IO ([Param], [File y])
NWP.parseRequestBody BackEnd x
backend Request
req
where
fix1 :: Param -> (Text, Text)
fix1 = ByteString -> Text
go forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** ByteString -> Text
go
fix2 :: File x -> Maybe (Text, FileInfo)
fix2 (ByteString
x, NWP.FileInfo ByteString
a' ByteString
b x
c)
| ByteString -> Bool
S.null ByteString
a = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just (ByteString -> Text
go ByteString
x, Text -> Text -> x -> FileInfo
mkFI (ByteString -> Text
go ByteString
a) (ByteString -> Text
go ByteString
b) x
c)
where
a :: ByteString
a
| ByteString -> Int
S.length ByteString
a' forall a. Ord a => a -> a -> Bool
< Int
2 = ByteString
a'
| ByteString -> Char
S8.head ByteString
a' forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
&& ByteString -> Char
S8.last ByteString
a' forall a. Eq a => a -> a -> Bool
== Char
'"' = HasCallStack => ByteString -> ByteString
S.tail forall a b. (a -> b) -> a -> b
$ HasCallStack => ByteString -> ByteString
S.init ByteString
a'
| ByteString -> Char
S8.head ByteString
a' forall a. Eq a => a -> a -> Bool
== Char
'\'' Bool -> Bool -> Bool
&& ByteString -> Char
S8.last ByteString
a' forall a. Eq a => a -> a -> Bool
== Char
'\'' = HasCallStack => ByteString -> ByteString
S.tail forall a b. (a -> b) -> a -> b
$ HasCallStack => ByteString -> ByteString
S.init ByteString
a'
| Bool
otherwise = ByteString
a'
go :: ByteString -> Text
go = OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode
askHandlerEnv :: MonadHandler m => m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv :: forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv = forall (m :: * -> *) a.
MonadHandler m =>
HandlerFor (HandlerSite m) a -> m a
liftHandler forall a b. (a -> b) -> a -> b
$ forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv
getYesod :: MonadHandler m => m (HandlerSite m)
getYesod :: forall (m :: * -> *). MonadHandler m => m (HandlerSite m)
getYesod = forall child site. RunHandlerEnv child site -> site
rheSite forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
getsYesod :: MonadHandler m => (HandlerSite m -> a) -> m a
getsYesod :: forall (m :: * -> *) a.
MonadHandler m =>
(HandlerSite m -> a) -> m a
getsYesod HandlerSite m -> a
f = (HandlerSite m -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. RunHandlerEnv child site -> site
rheSite) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
getUrlRender :: MonadHandler m => m (Route (HandlerSite m) -> Text)
getUrlRender :: forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> Text)
getUrlRender = do
Route (HandlerSite m) -> [(Text, Text)] -> Text
x <- forall child site.
RunHandlerEnv child site -> Route site -> [(Text, Text)] -> Text
rheRender forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip Route (HandlerSite m) -> [(Text, Text)] -> Text
x []
getUrlRenderParams
:: MonadHandler m
=> m (Route (HandlerSite m) -> [(Text, Text)] -> Text)
getUrlRenderParams :: forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> [(Text, Text)] -> Text)
getUrlRenderParams = forall child site.
RunHandlerEnv child site -> Route site -> [(Text, Text)] -> Text
rheRender forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
getPostParams
:: MonadHandler m
=> m [(Text, Text)]
getPostParams :: forall (m :: * -> *). MonadHandler m => m [(Text, Text)]
getPostParams = do
RequestBodyContents
reqBodyContent <- forall (m :: * -> *). MonadHandler m => m RequestBodyContents
runRequestBody
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> a
fst RequestBodyContents
reqBodyContent
getCurrentRoute :: MonadHandler m => m (Maybe (Route (HandlerSite m)))
getCurrentRoute :: forall (m :: * -> *).
MonadHandler m =>
m (Maybe (Route (HandlerSite m)))
getCurrentRoute = forall child site. RunHandlerEnv child site -> Maybe (Route child)
rheRoute forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
handlerToIO :: MonadIO m => HandlerFor site (HandlerFor site a -> m a)
handlerToIO :: forall (m :: * -> *) site a.
MonadIO m =>
HandlerFor site (HandlerFor site a -> m a)
handlerToIO =
forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ \HandlerData site site
oldHandlerData -> do
let newReq :: YesodRequest
newReq = YesodRequest
oldReq { reqWaiRequest :: Request
reqWaiRequest = Request
newWaiReq }
where
oldReq :: YesodRequest
oldReq = forall child site. HandlerData child site -> YesodRequest
handlerRequest HandlerData site site
oldHandlerData
oldWaiReq :: Request
oldWaiReq = YesodRequest -> Request
reqWaiRequest YesodRequest
oldReq
newWaiReq :: Request
newWaiReq = Request
oldWaiReq { requestBody :: IO ByteString
W.requestBody = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
, requestBodyLength :: RequestBodyLength
W.requestBodyLength = Word64 -> RequestBodyLength
W.KnownLength Word64
0
}
oldEnv :: RunHandlerEnv site site
oldEnv = forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv HandlerData site site
oldHandlerData
GHState
newState <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
GHState
oldState <- forall a. IORef a -> IO a
I.readIORef (forall child site. HandlerData child site -> IORef GHState
handlerState HandlerData site site
oldHandlerData)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ GHState
oldState { ghsRBC :: Maybe RequestBodyContents
ghsRBC = forall a. Maybe a
Nothing
, ghsIdent :: Int
ghsIdent = Int
1
, ghsCache :: TypeMap
ghsCache = forall a. Monoid a => a
mempty
, ghsCacheBy :: KeyedTypeMap
ghsCacheBy = forall a. Monoid a => a
mempty
, ghsHeaders :: Endo [Header]
ghsHeaders = forall a. Monoid a => a
mempty }
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO a
evaluate (YesodRequest
newReq seq :: forall a b. a -> b -> b
`seq` RunHandlerEnv site site
oldEnv seq :: forall a b. a -> b -> b
`seq` GHState
newState seq :: forall a b. a -> b -> b
`seq` ())
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \(HandlerFor HandlerData site site -> IO a
f) ->
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. (InternalState -> m a) -> ResourceT m a
withInternalState forall a b. (a -> b) -> a -> b
$ \InternalState
resState -> do
IORef GHState
newStateIORef <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a. a -> IO (IORef a)
I.newIORef GHState
newState)
let newHandlerData :: HandlerData site site
newHandlerData =
HandlerData
{ handlerRequest :: YesodRequest
handlerRequest = YesodRequest
newReq
, handlerEnv :: RunHandlerEnv site site
handlerEnv = RunHandlerEnv site site
oldEnv
, handlerState :: IORef GHState
handlerState = IORef GHState
newStateIORef
, handlerResource :: InternalState
handlerResource = InternalState
resState
}
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (HandlerData site site -> IO a
f HandlerData site site
newHandlerData)
forkHandler :: (SomeException -> HandlerFor site ())
-> HandlerFor site ()
-> HandlerFor site ()
forkHandler :: forall site.
(SomeException -> HandlerFor site ())
-> HandlerFor site () -> HandlerFor site ()
forkHandler SomeException -> HandlerFor site ()
onErr HandlerFor site ()
handler = do
HandlerFor site () -> IO ()
yesRunner <- forall (m :: * -> *) site a.
MonadIO m =>
HandlerFor site (HandlerFor site a -> m a)
handlerToIO
forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
liftResourceT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
MonadUnliftIO m =>
ResourceT m () -> ResourceT m ThreadId
resourceForkIO forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle (HandlerFor site () -> IO ()
yesRunner forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> HandlerFor site ()
onErr) (HandlerFor site () -> IO ()
yesRunner HandlerFor site ()
handler)
redirect :: (MonadHandler m, RedirectUrl (HandlerSite m) url)
=> url -> m a
redirect :: forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m a
redirect url
url = do
Request
req <- forall (m :: * -> *). MonadHandler m => m Request
waiRequest
let status :: Status
status =
if Request -> HttpVersion
W.httpVersion Request
req forall a. Eq a => a -> a -> Bool
== HttpVersion
H.http11
then Status
H.status303
else Status
H.status302
forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
Status -> url -> m a
redirectWith Status
status url
url
redirectWith :: (MonadHandler m, RedirectUrl (HandlerSite m) url)
=> H.Status
-> url
-> m a
redirectWith :: forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
Status -> url -> m a
redirectWith Status
status url
url = do
Text
urlText <- forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl url
url
forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall a b. (a -> b) -> a -> b
$ Status -> Text -> HandlerContents
HCRedirect Status
status Text
urlText
ultDestKey :: Text
ultDestKey :: Text
ultDestKey = Text
"_ULT"
setUltDest :: (MonadHandler m, RedirectUrl (HandlerSite m) url)
=> url
-> m ()
setUltDest :: forall (m :: * -> *) url.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m ()
setUltDest url
url = do
Text
urlText <- forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl url
url
forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setSession Text
ultDestKey Text
urlText
setUltDestCurrent :: MonadHandler m => m ()
setUltDestCurrent :: forall (m :: * -> *). MonadHandler m => m ()
setUltDestCurrent = do
Maybe (Route (HandlerSite m))
route <- forall (m :: * -> *).
MonadHandler m =>
m (Maybe (Route (HandlerSite m)))
getCurrentRoute
case Maybe (Route (HandlerSite m))
route of
Maybe (Route (HandlerSite m))
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just Route (HandlerSite m)
r -> do
[(Text, Text)]
gets' <- YesodRequest -> [(Text, Text)]
reqGetParams forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
forall (m :: * -> *) url.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m ()
setUltDest (Route (HandlerSite m)
r, [(Text, Text)]
gets')
setUltDestReferer :: MonadHandler m => m ()
setUltDestReferer :: forall (m :: * -> *). MonadHandler m => m ()
setUltDestReferer = do
Maybe Text
mdest <- forall (m :: * -> *). MonadHandler m => Text -> m (Maybe Text)
lookupSession Text
ultDestKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(forall (m :: * -> *). MonadHandler m => m Request
waiRequest forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return ()) ByteString -> m ()
setUltDestBS forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup CI ByteString
"referer" forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> RequestHeaders
W.requestHeaders)
(forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ())
Maybe Text
mdest
where
setUltDestBS :: ByteString -> m ()
setUltDestBS = forall (m :: * -> *) url.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m ()
setUltDest forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> FilePath
S8.unpack
redirectUltDest :: (RedirectUrl (HandlerSite m) url, MonadHandler m)
=> url
-> m a
redirectUltDest :: forall (m :: * -> *) url a.
(RedirectUrl (HandlerSite m) url, MonadHandler m) =>
url -> m a
redirectUltDest url
defaultDestination = do
Maybe Text
mdest <- forall (m :: * -> *). MonadHandler m => Text -> m (Maybe Text)
lookupSession Text
ultDestKey
forall (m :: * -> *). MonadHandler m => Text -> m ()
deleteSession Text
ultDestKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m a
redirect url
defaultDestination) forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m a
redirect Maybe Text
mdest
clearUltDest :: MonadHandler m => m ()
clearUltDest :: forall (m :: * -> *). MonadHandler m => m ()
clearUltDest = forall (m :: * -> *). MonadHandler m => Text -> m ()
deleteSession Text
ultDestKey
msgKey :: Text
msgKey :: Text
msgKey = Text
"_MSG"
addMessage :: MonadHandler m
=> Text
-> Html
-> m ()
addMessage :: forall (m :: * -> *). MonadHandler m => Text -> Html -> m ()
addMessage Text
status Html
msg = do
Maybe ByteString
val <- forall (m :: * -> *).
MonadHandler m =>
Text -> m (Maybe ByteString)
lookupSessionBS Text
msgKey
forall (m :: * -> *). MonadHandler m => Text -> ByteString -> m ()
setSessionBS Text
msgKey forall a b. (a -> b) -> a -> b
$ Maybe ByteString -> ByteString
addMsg Maybe ByteString
val
where
addMsg :: Maybe ByteString -> ByteString
addMsg = forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
msg' (ByteString -> ByteString -> ByteString
S.append ByteString
msg' forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ByteString -> ByteString
S.cons Word8
W8._nul)
msg' :: ByteString
msg' = ByteString -> ByteString -> ByteString
S.append
(Text -> ByteString
encodeUtf8 Text
status)
(Word8
W8._nul Word8 -> ByteString -> ByteString
`S.cons` ByteString -> ByteString
L.toStrict (Html -> ByteString
renderHtml Html
msg))
addMessageI :: (MonadHandler m, RenderMessage (HandlerSite m) msg)
=> Text -> msg -> m ()
addMessageI :: forall (m :: * -> *) msg.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
Text -> msg -> m ()
addMessageI Text
status msg
msg = do
msg -> Text
mr <- forall (m :: * -> *) message.
(MonadHandler m, RenderMessage (HandlerSite m) message) =>
m (message -> Text)
getMessageRender
forall (m :: * -> *). MonadHandler m => Text -> Html -> m ()
addMessage Text
status forall a b. (a -> b) -> a -> b
$ forall a. ToMarkup a => a -> Html
toHtml forall a b. (a -> b) -> a -> b
$ msg -> Text
mr msg
msg
getMessages :: MonadHandler m => m [(Text, Html)]
getMessages :: forall (m :: * -> *). MonadHandler m => m [(Text, Html)]
getMessages = do
Maybe ByteString
bs <- forall (m :: * -> *).
MonadHandler m =>
Text -> m (Maybe ByteString)
lookupSessionBS Text
msgKey
let ms :: [(Text, Html)]
ms = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ByteString -> [(Text, Html)]
enlist Maybe ByteString
bs
forall (m :: * -> *). MonadHandler m => Text -> m ()
deleteSession Text
msgKey
forall (m :: * -> *) a. Monad m => a -> m a
return [(Text, Html)]
ms
where
enlist :: ByteString -> [(Text, Html)]
enlist = [ByteString] -> [(Text, Html)]
pairup forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ByteString -> [ByteString]
S.split Word8
W8._nul
pairup :: [ByteString] -> [(Text, Html)]
pairup [] = []
pairup [ByteString
_] = []
pairup (ByteString
s:ByteString
v:[ByteString]
xs) = (ByteString -> Text
decode ByteString
s, forall a. ToMarkup a => a -> Html
preEscapedToHtml (ByteString -> Text
decode ByteString
v)) forall a. a -> [a] -> [a]
: [ByteString] -> [(Text, Html)]
pairup [ByteString]
xs
decode :: ByteString -> Text
decode = OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode
setMessage :: MonadHandler m => Html -> m ()
setMessage :: forall (m :: * -> *). MonadHandler m => Html -> m ()
setMessage = forall (m :: * -> *). MonadHandler m => Text -> Html -> m ()
addMessage Text
""
setMessageI :: (MonadHandler m, RenderMessage (HandlerSite m) msg)
=> msg -> m ()
setMessageI :: forall (m :: * -> *) msg.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
msg -> m ()
setMessageI = forall (m :: * -> *) msg.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
Text -> msg -> m ()
addMessageI Text
""
getMessage :: MonadHandler m => m (Maybe Html)
getMessage :: forall (m :: * -> *). MonadHandler m => m (Maybe Html)
getMessage = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe a
listToMaybe) forall (m :: * -> *). MonadHandler m => m [(Text, Html)]
getMessages
sendFile :: MonadHandler m => ContentType -> FilePath -> m a
sendFile :: forall (m :: * -> *) a.
MonadHandler m =>
ByteString -> FilePath -> m a
sendFile ByteString
ct FilePath
fp = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall a b. (a -> b) -> a -> b
$ ByteString -> FilePath -> Maybe FilePart -> HandlerContents
HCSendFile ByteString
ct FilePath
fp forall a. Maybe a
Nothing
sendFilePart :: MonadHandler m
=> ContentType
-> FilePath
-> Integer
-> Integer
-> m a
sendFilePart :: forall (m :: * -> *) a.
MonadHandler m =>
ByteString -> FilePath -> Integer -> Integer -> m a
sendFilePart ByteString
ct FilePath
fp Integer
off Integer
count = do
FileStatus
fs <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ FilePath -> IO FileStatus
PC.getFileStatus FilePath
fp
forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall a b. (a -> b) -> a -> b
$ ByteString -> FilePath -> Maybe FilePart -> HandlerContents
HCSendFile ByteString
ct FilePath
fp forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just W.FilePart
{ filePartOffset :: Integer
W.filePartOffset = Integer
off
, filePartByteCount :: Integer
W.filePartByteCount = Integer
count
, filePartFileSize :: Integer
W.filePartFileSize = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ FileStatus -> FileOffset
PC.fileSize FileStatus
fs
}
sendResponse :: (MonadHandler m, ToTypedContent c) => c -> m a
sendResponse :: forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
c -> m a
sendResponse = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall b c a. (b -> c) -> (a -> b) -> a -> c
. Status -> TypedContent -> HandlerContents
HCContent Status
H.status200 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToTypedContent a => a -> TypedContent
toTypedContent
sendResponseStatus :: (MonadHandler m, ToTypedContent c) => H.Status -> c -> m a
sendResponseStatus :: forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
Status -> c -> m a
sendResponseStatus Status
s = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall b c a. (b -> c) -> (a -> b) -> a -> c
. Status -> TypedContent -> HandlerContents
HCContent Status
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToTypedContent a => a -> TypedContent
toTypedContent
sendStatusJSON :: (MonadHandler m, ToJSON c) => H.Status -> c -> m a
sendStatusJSON :: forall (m :: * -> *) c a.
(MonadHandler m, ToJSON c) =>
Status -> c -> m a
sendStatusJSON Status
s c
v = forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
Status -> c -> m a
sendResponseStatus Status
s (forall a. ToJSON a => a -> Encoding
toEncoding c
v)
sendResponseCreated :: MonadHandler m => Route (HandlerSite m) -> m a
sendResponseCreated :: forall (m :: * -> *) a.
MonadHandler m =>
Route (HandlerSite m) -> m a
sendResponseCreated Route (HandlerSite m)
url = do
Route (HandlerSite m) -> Text
r <- forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> Text)
getUrlRender
forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall a b. (a -> b) -> a -> b
$ Text -> HandlerContents
HCCreated forall a b. (a -> b) -> a -> b
$ Route (HandlerSite m) -> Text
r Route (HandlerSite m)
url
sendResponseNoContent :: MonadHandler m => m a
sendResponseNoContent :: forall (m :: * -> *) a. MonadHandler m => m a
sendResponseNoContent = forall (m :: * -> *) b. MonadHandler m => Response -> m b
sendWaiResponse forall a b. (a -> b) -> a -> b
$ Status -> RequestHeaders -> Builder -> Response
W.responseBuilder Status
H.status204 [] forall a. Monoid a => a
mempty
sendWaiResponse :: MonadHandler m => W.Response -> m b
sendWaiResponse :: forall (m :: * -> *) b. MonadHandler m => Response -> m b
sendWaiResponse = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response -> HandlerContents
HCWai
sendWaiApplication :: MonadHandler m => W.Application -> m b
sendWaiApplication :: forall (m :: * -> *) b. MonadHandler m => Application -> m b
sendWaiApplication = forall (m :: * -> *) a. MonadHandler m => HandlerContents -> m a
handlerError forall b c a. (b -> c) -> (a -> b) -> a -> c
. Application -> HandlerContents
HCWaiApp
sendRawResponseNoConduit
:: (MonadHandler m, MonadUnliftIO m)
=> (IO S8.ByteString -> (S8.ByteString -> IO ()) -> m ())
-> m a
sendRawResponseNoConduit :: forall (m :: * -> *) a.
(MonadHandler m, MonadUnliftIO m) =>
(IO ByteString -> (ByteString -> IO ()) -> m ()) -> m a
sendRawResponseNoConduit IO ByteString -> (ByteString -> IO ()) -> m ()
raw = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
runInIO ->
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => e -> IO a
throwIO forall a b. (a -> b) -> a -> b
$ Response -> HandlerContents
HCWai forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip (IO ByteString -> (ByteString -> IO ()) -> IO ())
-> Response -> Response
W.responseRaw Response
fallback
forall a b. (a -> b) -> a -> b
$ \IO ByteString
src ByteString -> IO ()
sink -> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
runInIO (IO ByteString -> (ByteString -> IO ()) -> m ()
raw IO ByteString
src ByteString -> IO ()
sink)
where
fallback :: Response
fallback = Status -> RequestHeaders -> ByteString -> Response
W.responseLBS Status
H.status500 [(CI ByteString
"Content-Type", ByteString
"text/plain")]
ByteString
"sendRawResponse: backend does not support raw responses"
sendRawResponse
:: (MonadHandler m, MonadUnliftIO m)
=> (ConduitT () S8.ByteString IO () -> ConduitT S8.ByteString Void IO () -> m ())
-> m a
sendRawResponse :: forall (m :: * -> *) a.
(MonadHandler m, MonadUnliftIO m) =>
(ConduitT () ByteString IO ()
-> ConduitT ByteString Void IO () -> m ())
-> m a
sendRawResponse ConduitT () ByteString IO ()
-> ConduitT ByteString Void IO () -> m ()
raw = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
runInIO ->
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => e -> IO a
throwIO forall a b. (a -> b) -> a -> b
$ Response -> HandlerContents
HCWai forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> b -> a -> c
flip (IO ByteString -> (ByteString -> IO ()) -> IO ())
-> Response -> Response
W.responseRaw Response
fallback
forall a b. (a -> b) -> a -> b
$ \IO ByteString
src ByteString -> IO ()
sink -> forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
runInIO forall a b. (a -> b) -> a -> b
$ ConduitT () ByteString IO ()
-> ConduitT ByteString Void IO () -> m ()
raw (forall {m :: * -> *} {i}.
MonadIO m =>
IO ByteString -> ConduitT i ByteString m ()
src' IO ByteString
src) (forall (m :: * -> *) a o.
Monad m =>
(a -> m ()) -> ConduitT a o m ()
CL.mapM_ ByteString -> IO ()
sink)
where
fallback :: Response
fallback = Status -> RequestHeaders -> ByteString -> Response
W.responseLBS Status
H.status500 [(CI ByteString
"Content-Type", ByteString
"text/plain")]
ByteString
"sendRawResponse: backend does not support raw responses"
src' :: IO ByteString -> ConduitT i ByteString m ()
src' IO ByteString
src = do
ByteString
bs <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO ByteString
src
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteString -> Bool
S.null ByteString
bs) forall a b. (a -> b) -> a -> b
$ do
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
bs
IO ByteString -> ConduitT i ByteString m ()
src' IO ByteString
src
notModified :: MonadHandler m => m a
notModified :: forall (m :: * -> *) a. MonadHandler m => m a
notModified = forall (m :: * -> *) b. MonadHandler m => Response -> m b
sendWaiResponse forall a b. (a -> b) -> a -> b
$ Status -> RequestHeaders -> Builder -> Response
W.responseBuilder Status
H.status304 [] forall a. Monoid a => a
mempty
notFound :: MonadHandler m => m a
notFound :: forall (m :: * -> *) a. MonadHandler m => m a
notFound = forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError ErrorResponse
NotFound
badMethod :: MonadHandler m => m a
badMethod :: forall (m :: * -> *) a. MonadHandler m => m a
badMethod = do
Request
w <- forall (m :: * -> *). MonadHandler m => m Request
waiRequest
forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError forall a b. (a -> b) -> a -> b
$ ByteString -> ErrorResponse
BadMethod forall a b. (a -> b) -> a -> b
$ Request -> ByteString
W.requestMethod Request
w
notAuthenticated :: MonadHandler m => m a
notAuthenticated :: forall (m :: * -> *) a. MonadHandler m => m a
notAuthenticated = forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError ErrorResponse
NotAuthenticated
permissionDenied :: MonadHandler m => Text -> m a
permissionDenied :: forall (m :: * -> *) a. MonadHandler m => Text -> m a
permissionDenied = forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ErrorResponse
PermissionDenied
permissionDeniedI :: (RenderMessage (HandlerSite m) msg, MonadHandler m)
=> msg
-> m a
permissionDeniedI :: forall (m :: * -> *) msg a.
(RenderMessage (HandlerSite m) msg, MonadHandler m) =>
msg -> m a
permissionDeniedI msg
msg = do
msg -> Text
mr <- forall (m :: * -> *) message.
(MonadHandler m, RenderMessage (HandlerSite m) message) =>
m (message -> Text)
getMessageRender
forall (m :: * -> *) a. MonadHandler m => Text -> m a
permissionDenied forall a b. (a -> b) -> a -> b
$ msg -> Text
mr msg
msg
invalidArgs :: MonadHandler m => [Text] -> m a
invalidArgs :: forall (m :: * -> *) a. MonadHandler m => [Text] -> m a
invalidArgs = forall (m :: * -> *) a. MonadHandler m => ErrorResponse -> m a
hcError forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> ErrorResponse
InvalidArgs
invalidArgsI :: (MonadHandler m, RenderMessage (HandlerSite m) msg) => [msg] -> m a
invalidArgsI :: forall (m :: * -> *) msg a.
(MonadHandler m, RenderMessage (HandlerSite m) msg) =>
[msg] -> m a
invalidArgsI [msg]
msg = do
msg -> Text
mr <- forall (m :: * -> *) message.
(MonadHandler m, RenderMessage (HandlerSite m) message) =>
m (message -> Text)
getMessageRender
forall (m :: * -> *) a. MonadHandler m => [Text] -> m a
invalidArgs forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map msg -> Text
mr [msg]
msg
setCookie :: MonadHandler m => SetCookie -> m ()
setCookie :: forall (m :: * -> *). MonadHandler m => SetCookie -> m ()
setCookie SetCookie
sc = do
forall (m :: * -> *). MonadHandler m => Header -> m ()
addHeaderInternal (ByteString -> ByteString -> Header
DeleteCookie ByteString
name ByteString
path)
forall (m :: * -> *). MonadHandler m => Header -> m ()
addHeaderInternal (SetCookie -> Header
AddCookie SetCookie
sc)
where name :: ByteString
name = SetCookie -> ByteString
setCookieName SetCookie
sc
path :: ByteString
path = forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
"/" forall a. a -> a
id (SetCookie -> Maybe ByteString
setCookiePath SetCookie
sc)
getExpires :: MonadIO m
=> Int
-> m UTCTime
getExpires :: forall (m :: * -> *). MonadIO m => Int -> m UTCTime
getExpires Int
m = do
UTCTime
now <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO UTCTime
getCurrentTime
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
m forall a. Num a => a -> a -> a
* Int
60) NominalDiffTime -> UTCTime -> UTCTime
`addUTCTime` UTCTime
now
deleteCookie :: MonadHandler m
=> Text
-> Text
-> m ()
deleteCookie :: forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
deleteCookie Text
a = forall (m :: * -> *). MonadHandler m => Header -> m ()
addHeaderInternal forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString -> Header
DeleteCookie (Text -> ByteString
encodeUtf8 Text
a) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8
setLanguage :: MonadHandler m => Text -> m ()
setLanguage :: forall (m :: * -> *). MonadHandler m => Text -> m ()
setLanguage = forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setSession forall a. IsString a => a
langKey
addContentDispositionFileName :: MonadHandler m => T.Text -> m ()
addContentDispositionFileName :: forall (m :: * -> *). MonadHandler m => Text -> m ()
addContentDispositionFileName Text
fileName
= forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
addHeader Text
"Content-Disposition" forall a b. (a -> b) -> a -> b
$ Text -> Text
rfc6266Utf8FileName Text
fileName
rfc6266Utf8FileName :: T.Text -> T.Text
rfc6266Utf8FileName :: Text -> Text
rfc6266Utf8FileName Text
fileName = Text
"attachment; filename*=UTF-8''" forall a. Monoid a => a -> a -> a
`mappend` ByteString -> Text
decodeUtf8 (Bool -> ByteString -> ByteString
H.urlEncode Bool
True (Text -> ByteString
encodeUtf8 Text
fileName))
addHeader :: MonadHandler m => Text -> Text -> m ()
Text
a = forall (m :: * -> *). MonadHandler m => Header -> m ()
addHeaderInternal forall b c a. (b -> c) -> (a -> b) -> a -> c
. CI ByteString -> ByteString -> Header
Header (forall s. FoldCase s => s -> CI s
CI.mk forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 Text
a) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8
setHeader :: MonadHandler m => Text -> Text -> m ()
= forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
addHeader
{-# DEPRECATED setHeader "Please use addHeader instead" #-}
replaceOrAddHeader :: MonadHandler m => Text -> Text -> m ()
Text
a Text
b =
forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \GHState
g -> GHState
g {ghsHeaders :: Endo [Header]
ghsHeaders = Endo [Header] -> Endo [Header]
replaceHeader (GHState -> Endo [Header]
ghsHeaders GHState
g)}
where
repHeader :: Header
repHeader = CI ByteString -> ByteString -> Header
Header (forall s. FoldCase s => s -> CI s
CI.mk forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 Text
a) (Text -> ByteString
encodeUtf8 Text
b)
sameHeaderName :: Header -> Header -> Bool
sameHeaderName :: Header -> Header -> Bool
sameHeaderName (Header CI ByteString
n1 ByteString
_) (Header CI ByteString
n2 ByteString
_) = CI ByteString
n1 forall a. Eq a => a -> a -> Bool
== CI ByteString
n2
sameHeaderName Header
_ Header
_ = Bool
False
replaceIndividualHeader :: [Header] -> [Header]
replaceIndividualHeader :: [Header] -> [Header]
replaceIndividualHeader [] = [Header
repHeader]
replaceIndividualHeader [Header]
xs = [Header] -> [Header] -> [Header]
aux [Header]
xs []
where
aux :: [Header] -> [Header] -> [Header]
aux [] [Header]
acc = [Header]
acc forall a. [a] -> [a] -> [a]
++ [Header
repHeader]
aux (Header
x:[Header]
xs') [Header]
acc =
if Header -> Header -> Bool
sameHeaderName Header
repHeader Header
x
then [Header]
acc forall a. [a] -> [a] -> [a]
++
[Header
repHeader] forall a. [a] -> [a] -> [a]
++
(forall a. (a -> Bool) -> [a] -> [a]
filter (\Header
header -> Bool -> Bool
not (Header -> Header -> Bool
sameHeaderName Header
header Header
repHeader)) [Header]
xs')
else [Header] -> [Header] -> [Header]
aux [Header]
xs' ([Header]
acc forall a. [a] -> [a] -> [a]
++ [Header
x])
replaceHeader :: Endo [Header] -> Endo [Header]
replaceHeader :: Endo [Header] -> Endo [Header]
replaceHeader Endo [Header]
endo =
let [Header]
allHeaders :: [Header] = forall a. Endo a -> a -> a
appEndo Endo [Header]
endo []
in forall a. (a -> a) -> Endo a
Endo (\[Header]
rest -> [Header] -> [Header]
replaceIndividualHeader [Header]
allHeaders forall a. [a] -> [a] -> [a]
++ [Header]
rest)
cacheSeconds :: MonadHandler m => Int -> m ()
cacheSeconds :: forall (m :: * -> *). MonadHandler m => Int -> m ()
cacheSeconds Int
i = forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setHeader Text
"Cache-Control" forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat
[ Text
"max-age="
, FilePath -> Text
T.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> FilePath
show Int
i
, Text
", public"
]
neverExpires :: MonadHandler m => m ()
neverExpires :: forall (m :: * -> *). MonadHandler m => m ()
neverExpires = do
forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setHeader Text
"Expires" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. RunHandlerEnv child site -> Text
rheMaxExpires forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
forall (m :: * -> *). MonadHandler m => Int -> m ()
cacheSeconds Int
oneYear
where
oneYear :: Int
oneYear :: Int
oneYear = Int
60 forall a. Num a => a -> a -> a
* Int
60 forall a. Num a => a -> a -> a
* Int
24 forall a. Num a => a -> a -> a
* Int
365
alreadyExpired :: MonadHandler m => m ()
alreadyExpired :: forall (m :: * -> *). MonadHandler m => m ()
alreadyExpired = forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setHeader Text
"Expires" Text
"Thu, 01 Jan 1970 05:05:05 GMT"
expiresAt :: MonadHandler m => UTCTime -> m ()
expiresAt :: forall (m :: * -> *). MonadHandler m => UTCTime -> m ()
expiresAt = forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setHeader Text
"Expires" forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> Text
formatRFC1123
data Etag
= WeakEtag !S.ByteString
| StrongEtag !S.ByteString
| InvalidEtag !S.ByteString
deriving (Int -> Etag -> ShowS
[Etag] -> ShowS
Etag -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Etag] -> ShowS
$cshowList :: [Etag] -> ShowS
show :: Etag -> FilePath
$cshow :: Etag -> FilePath
showsPrec :: Int -> Etag -> ShowS
$cshowsPrec :: Int -> Etag -> ShowS
Show, Etag -> Etag -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Etag -> Etag -> Bool
$c/= :: Etag -> Etag -> Bool
== :: Etag -> Etag -> Bool
$c== :: Etag -> Etag -> Bool
Eq)
setEtag :: MonadHandler m => Text -> m ()
setEtag :: forall (m :: * -> *). MonadHandler m => Text -> m ()
setEtag Text
etag = do
Maybe ByteString
mmatch <- forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Maybe ByteString)
lookupHeader CI ByteString
"if-none-match"
let matches :: [Etag]
matches = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ByteString -> [Etag]
parseMatch Maybe ByteString
mmatch
baseTag :: ByteString
baseTag = Text -> ByteString
encodeUtf8 Text
etag
strongTag :: Etag
strongTag = ByteString -> Etag
StrongEtag ByteString
baseTag
badTag :: Etag
badTag = ByteString -> Etag
InvalidEtag ByteString
baseTag
if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\Etag
tag -> Etag
tag forall a. Eq a => a -> a -> Bool
== Etag
strongTag Bool -> Bool -> Bool
|| Etag
tag forall a. Eq a => a -> a -> Bool
== Etag
badTag) [Etag]
matches
then forall (m :: * -> *) a. MonadHandler m => m a
notModified
else forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
addHeader Text
"etag" forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat [Text
"\"", Text
etag, Text
"\""]
parseMatch :: S.ByteString -> [Etag]
parseMatch :: ByteString -> [Etag]
parseMatch =
forall a b. (a -> b) -> [a] -> [b]
map ByteString -> Etag
clean forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ByteString -> [ByteString]
S.split Word8
W8._comma
where
clean :: ByteString -> Etag
clean = ByteString -> Etag
classify forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Bool) -> ByteString -> Param
S.spanEnd Word8 -> Bool
W8.isSpace forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Bool) -> ByteString -> ByteString
S.dropWhile Word8 -> Bool
W8.isSpace
classify :: ByteString -> Etag
classify ByteString
bs
| ByteString -> Int
S.length ByteString
bs forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& HasCallStack => ByteString -> Word8
S.head ByteString
bs forall a. Eq a => a -> a -> Bool
== Word8
W8._quotedbl Bool -> Bool -> Bool
&& HasCallStack => ByteString -> Word8
S.last ByteString
bs forall a. Eq a => a -> a -> Bool
== Word8
W8._quotedbl
= ByteString -> Etag
StrongEtag forall a b. (a -> b) -> a -> b
$ HasCallStack => ByteString -> ByteString
S.init forall a b. (a -> b) -> a -> b
$ HasCallStack => ByteString -> ByteString
S.tail ByteString
bs
| ByteString -> Int
S.length ByteString
bs forall a. Ord a => a -> a -> Bool
>= Int
4 Bool -> Bool -> Bool
&&
HasCallStack => ByteString -> Word8
S.head ByteString
bs forall a. Eq a => a -> a -> Bool
== Word8
W8._W Bool -> Bool -> Bool
&&
HasCallStack => ByteString -> Int -> Word8
S.index ByteString
bs Int
1 forall a. Eq a => a -> a -> Bool
== Word8
W8._slash Bool -> Bool -> Bool
&&
HasCallStack => ByteString -> Int -> Word8
S.index ByteString
bs Int
2 forall a. Eq a => a -> a -> Bool
== Word8
W8._quotedbl Bool -> Bool -> Bool
&&
HasCallStack => ByteString -> Word8
S.last ByteString
bs forall a. Eq a => a -> a -> Bool
== Word8
W8._quotedbl
= ByteString -> Etag
WeakEtag forall a b. (a -> b) -> a -> b
$ HasCallStack => ByteString -> ByteString
S.init forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
S.drop Int
3 ByteString
bs
| Bool
otherwise = ByteString -> Etag
InvalidEtag ByteString
bs
setWeakEtag :: MonadHandler m => Text -> m ()
setWeakEtag :: forall (m :: * -> *). MonadHandler m => Text -> m ()
setWeakEtag Text
etag = do
Maybe ByteString
mmatch <- forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Maybe ByteString)
lookupHeader CI ByteString
"if-none-match"
let matches :: [Etag]
matches = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] ByteString -> [Etag]
parseMatch Maybe ByteString
mmatch
if ByteString -> Etag
WeakEtag (Text -> ByteString
encodeUtf8 Text
etag) forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Etag]
matches
then forall (m :: * -> *) a. MonadHandler m => m a
notModified
else forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
addHeader Text
"etag" forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat [Text
"W/\"", Text
etag, Text
"\""]
setSession :: MonadHandler m
=> Text
-> Text
-> m ()
setSession :: forall (m :: * -> *). MonadHandler m => Text -> Text -> m ()
setSession Text
k = forall (m :: * -> *). MonadHandler m => Text -> ByteString -> m ()
setSessionBS Text
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8
setSessionBS :: MonadHandler m
=> Text
-> S.ByteString
-> m ()
setSessionBS :: forall (m :: * -> *). MonadHandler m => Text -> ByteString -> m ()
setSessionBS Text
k = forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SessionMap -> SessionMap) -> GHState -> GHState
modSession forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Text
k
deleteSession :: MonadHandler m => Text -> m ()
deleteSession :: forall (m :: * -> *). MonadHandler m => Text -> m ()
deleteSession = forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SessionMap -> SessionMap) -> GHState -> GHState
modSession forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => k -> Map k a -> Map k a
Map.delete
clearSession :: MonadHandler m => m ()
clearSession :: forall (m :: * -> *). MonadHandler m => m ()
clearSession = forall (m :: * -> *).
MonadHandler m =>
(GHState -> GHState) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \GHState
x -> GHState
x { ghsSession :: SessionMap
ghsSession = forall k a. Map k a
Map.empty }
modSession :: (SessionMap -> SessionMap) -> GHState -> GHState
modSession :: (SessionMap -> SessionMap) -> GHState -> GHState
modSession SessionMap -> SessionMap
f GHState
x = GHState
x { ghsSession :: SessionMap
ghsSession = SessionMap -> SessionMap
f forall a b. (a -> b) -> a -> b
$ GHState -> SessionMap
ghsSession GHState
x }
addHeaderInternal :: MonadHandler m => Header -> m ()
= forall (m :: * -> *). MonadHandler m => Endo [Header] -> m ()
tell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a) -> Endo a
Endo forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)
class RedirectUrl master a where
toTextUrl :: (MonadHandler m, HandlerSite m ~ master) => a -> m Text
instance RedirectUrl master Text where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
Text -> m Text
toTextUrl = forall (m :: * -> *) a. Monad m => a -> m a
return
instance RedirectUrl master String where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
FilePath -> m Text
toTextUrl = forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Text
T.pack
instance RedirectUrl master (Route master) where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
Route master -> m Text
toTextUrl Route master
url = do
Route master -> Text
r <- forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> Text)
getUrlRender
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Route master -> Text
r Route master
url
instance (key ~ Text, val ~ Text) => RedirectUrl master (Route master, [(key, val)]) where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
(Route master, [(key, val)]) -> m Text
toTextUrl (Route master
url, [(key, val)]
params) = do
Route master -> [(key, val)] -> Text
r <- forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> [(Text, Text)] -> Text)
getUrlRenderParams
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Route master -> [(key, val)] -> Text
r Route master
url [(key, val)]
params
instance (key ~ Text, val ~ Text) => RedirectUrl master (Route master, Map.Map key val) where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
(Route master, Map key val) -> m Text
toTextUrl (Route master
url, Map key val
params) = forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl (Route master
url, forall k a. Map k a -> [(k, a)]
Map.toList Map key val
params)
data Fragment a b = a :#: b deriving Int -> Fragment a b -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Fragment a b -> ShowS
forall a b. (Show a, Show b) => [Fragment a b] -> ShowS
forall a b. (Show a, Show b) => Fragment a b -> FilePath
showList :: [Fragment a b] -> ShowS
$cshowList :: forall a b. (Show a, Show b) => [Fragment a b] -> ShowS
show :: Fragment a b -> FilePath
$cshow :: forall a b. (Show a, Show b) => Fragment a b -> FilePath
showsPrec :: Int -> Fragment a b -> ShowS
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Fragment a b -> ShowS
Show
instance (RedirectUrl master a, PathPiece b) => RedirectUrl master (Fragment a b) where
toTextUrl :: forall (m :: * -> *).
(MonadHandler m, HandlerSite m ~ master) =>
Fragment a b -> m Text
toTextUrl (a
a :#: b
b) = (\Text
ua -> [Text] -> Text
T.concat [Text
ua, Text
"#", forall s. PathPiece s => s -> Text
toPathPiece b
b]) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl a
a
lookupSession :: MonadHandler m => Text -> m (Maybe Text)
lookupSession :: forall (m :: * -> *). MonadHandler m => Text -> m (Maybe Text)
lookupSession = (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) (OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
MonadHandler m =>
Text -> m (Maybe ByteString)
lookupSessionBS
lookupSessionBS :: MonadHandler m => Text -> m (Maybe S.ByteString)
lookupSessionBS :: forall (m :: * -> *).
MonadHandler m =>
Text -> m (Maybe ByteString)
lookupSessionBS Text
n = do
SessionMap
m <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GHState -> SessionMap
ghsSession forall (m :: * -> *). MonadHandler m => m GHState
get
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
n SessionMap
m
getSession :: MonadHandler m => m SessionMap
getSession :: forall (m :: * -> *). MonadHandler m => m SessionMap
getSession = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GHState -> SessionMap
ghsSession forall (m :: * -> *). MonadHandler m => m GHState
get
newIdent :: MonadHandler m => m Text
newIdent :: forall (m :: * -> *). MonadHandler m => m Text
newIdent = do
GHState
x <- forall (m :: * -> *). MonadHandler m => m GHState
get
let i' :: Int
i' = GHState -> Int
ghsIdent GHState
x forall a. Num a => a -> a -> a
+ Int
1
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put GHState
x { ghsIdent :: Int
ghsIdent = Int
i' }
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ FilePath -> Text
T.pack forall a b. (a -> b) -> a -> b
$ FilePath
"hident" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> FilePath
show Int
i'
redirectToPost :: (MonadHandler m, RedirectUrl (HandlerSite m) url)
=> url
-> m a
redirectToPost :: forall (m :: * -> *) url a.
(MonadHandler m, RedirectUrl (HandlerSite m) url) =>
url -> m a
redirectToPost url
url = do
Text
urlText <- forall master a (m :: * -> *).
(RedirectUrl master a, MonadHandler m, HandlerSite m ~ master) =>
a -> m Text
toTextUrl url
url
YesodRequest
req <- forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
forall (m :: * -> *) output.
MonadHandler m =>
((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
withUrlRenderer [hamlet|
$newline never
$doctype 5
<html>
<head>
<title>Redirecting...
<body>
<form id="form" method="post" action=#{urlText}>
$maybe token <- reqToken req
<input type=hidden name=#{defaultCsrfParamName} value=#{token}>
<noscript>
<p>Javascript has been disabled; please click on the button below to be redirected.
<input type="submit" value="Continue">
<script>
window.onload = function() { document.getElementById('form').submit(); };
|] forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
c -> m a
sendResponse
hamletToRepHtml :: MonadHandler m => HtmlUrl (Route (HandlerSite m)) -> m Html
hamletToRepHtml :: forall (m :: * -> *).
MonadHandler m =>
HtmlUrl (Route (HandlerSite m)) -> m Html
hamletToRepHtml = forall (m :: * -> *) output.
MonadHandler m =>
((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
withUrlRenderer
{-# DEPRECATED hamletToRepHtml "Use withUrlRenderer instead" #-}
giveUrlRenderer :: MonadHandler m
=> ((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
giveUrlRenderer :: forall (m :: * -> *) output.
MonadHandler m =>
((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
giveUrlRenderer = forall (m :: * -> *) output.
MonadHandler m =>
((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
withUrlRenderer
{-# DEPRECATED giveUrlRenderer "Use withUrlRenderer instead" #-}
withUrlRenderer :: MonadHandler m
=> ((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
withUrlRenderer :: forall (m :: * -> *) output.
MonadHandler m =>
((Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output)
-> m output
withUrlRenderer (Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output
f = do
Route (HandlerSite m) -> [(Text, Text)] -> Text
render <- forall (m :: * -> *).
MonadHandler m =>
m (Route (HandlerSite m) -> [(Text, Text)] -> Text)
getUrlRenderParams
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Route (HandlerSite m) -> [(Text, Text)] -> Text) -> output
f Route (HandlerSite m) -> [(Text, Text)] -> Text
render
waiRequest :: MonadHandler m => m W.Request
waiRequest :: forall (m :: * -> *). MonadHandler m => m Request
waiRequest = YesodRequest -> Request
reqWaiRequest forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
getMessageRender :: (MonadHandler m, RenderMessage (HandlerSite m) message)
=> m (message -> Text)
getMessageRender :: forall (m :: * -> *) message.
(MonadHandler m, RenderMessage (HandlerSite m) message) =>
m (message -> Text)
getMessageRender = do
RunHandlerEnv (HandlerSite m) (HandlerSite m)
env <- forall (m :: * -> *).
MonadHandler m =>
m (RunHandlerEnv (HandlerSite m) (HandlerSite m))
askHandlerEnv
[Text]
l <- forall (m :: * -> *). MonadHandler m => m [Text]
languages
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall master message.
RenderMessage master message =>
master -> [Text] -> message -> Text
renderMessage (forall child site. RunHandlerEnv child site -> site
rheSite RunHandlerEnv (HandlerSite m) (HandlerSite m)
env) [Text]
l
cached :: (MonadHandler m, Typeable a)
=> m a
-> m a
cached :: forall (m :: * -> *) a. (MonadHandler m, Typeable a) => m a -> m a
cached m a
action = do
TypeMap
cache <- GHState -> TypeMap
ghsCache forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m GHState
get
Either (TypeMap, a) a
eres <- forall (m :: * -> *) a.
(Monad m, Typeable a) =>
TypeMap -> m a -> m (Either (TypeMap, a) a)
Cache.cached TypeMap
cache m a
action
case Either (TypeMap, a) a
eres of
Right a
res -> forall (m :: * -> *) a. Monad m => a -> m a
return a
res
Left (TypeMap
newCache, a
res) -> do
GHState
gs <- forall (m :: * -> *). MonadHandler m => m GHState
get
let merged :: TypeMap
merged = TypeMap
newCache forall k v.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k v -> HashMap k v
`HM.union` GHState -> TypeMap
ghsCache GHState
gs
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put forall a b. (a -> b) -> a -> b
$ GHState
gs { ghsCache :: TypeMap
ghsCache = TypeMap
merged }
forall (m :: * -> *) a. Monad m => a -> m a
return a
res
cacheGet :: (MonadHandler m, Typeable a)
=> m (Maybe a)
cacheGet :: forall (m :: * -> *) a. (MonadHandler m, Typeable a) => m (Maybe a)
cacheGet = do
TypeMap
cache <- GHState -> TypeMap
ghsCache forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m GHState
get
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeMap -> Maybe a
Cache.cacheGet TypeMap
cache
cacheSet :: (MonadHandler m, Typeable a)
=> a
-> m ()
cacheSet :: forall (m :: * -> *) a. (MonadHandler m, Typeable a) => a -> m ()
cacheSet a
value = do
GHState
gs <- forall (m :: * -> *). MonadHandler m => m GHState
get
let cache :: TypeMap
cache = GHState -> TypeMap
ghsCache GHState
gs
newCache :: TypeMap
newCache = forall a. Typeable a => a -> TypeMap -> TypeMap
Cache.cacheSet a
value TypeMap
cache
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put forall a b. (a -> b) -> a -> b
$ GHState
gs { ghsCache :: TypeMap
ghsCache = TypeMap
newCache }
cachedBy :: (MonadHandler m, Typeable a) => S.ByteString -> m a -> m a
cachedBy :: forall (m :: * -> *) a.
(MonadHandler m, Typeable a) =>
ByteString -> m a -> m a
cachedBy ByteString
k m a
action = do
KeyedTypeMap
cache <- GHState -> KeyedTypeMap
ghsCacheBy forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m GHState
get
Either (KeyedTypeMap, a) a
eres <- forall (m :: * -> *) a.
(Monad m, Typeable a) =>
KeyedTypeMap -> ByteString -> m a -> m (Either (KeyedTypeMap, a) a)
Cache.cachedBy KeyedTypeMap
cache ByteString
k m a
action
case Either (KeyedTypeMap, a) a
eres of
Right a
res -> forall (m :: * -> *) a. Monad m => a -> m a
return a
res
Left (KeyedTypeMap
newCache, a
res) -> do
GHState
gs <- forall (m :: * -> *). MonadHandler m => m GHState
get
let merged :: KeyedTypeMap
merged = KeyedTypeMap
newCache forall k v.
(Eq k, Hashable k) =>
HashMap k v -> HashMap k v -> HashMap k v
`HM.union` GHState -> KeyedTypeMap
ghsCacheBy GHState
gs
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put forall a b. (a -> b) -> a -> b
$ GHState
gs { ghsCacheBy :: KeyedTypeMap
ghsCacheBy = KeyedTypeMap
merged }
forall (m :: * -> *) a. Monad m => a -> m a
return a
res
cacheByGet :: (MonadHandler m, Typeable a)
=> S.ByteString
-> m (Maybe a)
cacheByGet :: forall (m :: * -> *) a.
(MonadHandler m, Typeable a) =>
ByteString -> m (Maybe a)
cacheByGet ByteString
key = do
KeyedTypeMap
cache <- GHState -> KeyedTypeMap
ghsCacheBy forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m GHState
get
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => ByteString -> KeyedTypeMap -> Maybe a
Cache.cacheByGet ByteString
key KeyedTypeMap
cache
cacheBySet :: (MonadHandler m, Typeable a)
=> S.ByteString
-> a
-> m ()
cacheBySet :: forall (m :: * -> *) a.
(MonadHandler m, Typeable a) =>
ByteString -> a -> m ()
cacheBySet ByteString
key a
value = do
GHState
gs <- forall (m :: * -> *). MonadHandler m => m GHState
get
let cache :: KeyedTypeMap
cache = GHState -> KeyedTypeMap
ghsCacheBy GHState
gs
newCache :: KeyedTypeMap
newCache = forall a.
Typeable a =>
ByteString -> a -> KeyedTypeMap -> KeyedTypeMap
Cache.cacheBySet ByteString
key a
value KeyedTypeMap
cache
forall (m :: * -> *). MonadHandler m => GHState -> m ()
put forall a b. (a -> b) -> a -> b
$ GHState
gs { ghsCacheBy :: KeyedTypeMap
ghsCacheBy = KeyedTypeMap
newCache }
languages :: MonadHandler m => m [Text]
languages :: forall (m :: * -> *). MonadHandler m => m [Text]
languages = YesodRequest -> [Text]
reqLangs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
lookup' :: Eq a => a -> [(a, b)] -> [b]
lookup' :: forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' a
a = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
filter (\(a, b)
x -> a
a forall a. Eq a => a -> a -> Bool
== forall a b. (a, b) -> a
fst (a, b)
x)
lookupHeader :: MonadHandler m => CI S8.ByteString -> m (Maybe S8.ByteString)
= forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m [ByteString]
lookupHeaders
lookupHeaders :: MonadHandler m => CI S8.ByteString -> m [S8.ByteString]
CI ByteString
key = do
Request
req <- forall (m :: * -> *). MonadHandler m => m Request
waiRequest
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' CI ByteString
key forall a b. (a -> b) -> a -> b
$ Request -> RequestHeaders
W.requestHeaders Request
req
lookupBasicAuth :: (MonadHandler m) => m (Maybe (Text, Text))
lookupBasicAuth :: forall (m :: * -> *). MonadHandler m => m (Maybe (Text, Text))
lookupBasicAuth = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> Maybe (Text, Text)
getBA) (forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Maybe ByteString)
lookupHeader CI ByteString
"Authorization")
where
getBA :: ByteString -> Maybe (Text, Text)
getBA ByteString
bs = (OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe Param
extractBasicAuth ByteString
bs
lookupBearerAuth :: (MonadHandler m) => m (Maybe Text)
lookupBearerAuth :: forall (m :: * -> *). MonadHandler m => m (Maybe Text)
lookupBearerAuth = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> Maybe Text
getBR)
(forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Maybe ByteString)
lookupHeader CI ByteString
"Authorization")
where
getBR :: ByteString -> Maybe Text
getBR ByteString
bs = OnDecodeError -> ByteString -> Text
decodeUtf8With OnDecodeError
lenientDecode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe ByteString
extractBearerAuth ByteString
bs
lookupGetParams :: MonadHandler m => Text -> m [Text]
lookupGetParams :: forall (m :: * -> *). MonadHandler m => Text -> m [Text]
lookupGetParams Text
pn = do
YesodRequest
rr <- forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' Text
pn forall a b. (a -> b) -> a -> b
$ YesodRequest -> [(Text, Text)]
reqGetParams YesodRequest
rr
lookupGetParam :: MonadHandler m => Text -> m (Maybe Text)
lookupGetParam :: forall (m :: * -> *). MonadHandler m => Text -> m (Maybe Text)
lookupGetParam = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadHandler m => Text -> m [Text]
lookupGetParams
lookupPostParams :: (MonadResource m, MonadHandler m) => Text -> m [Text]
lookupPostParams :: forall (m :: * -> *).
(MonadResource m, MonadHandler m) =>
Text -> m [Text]
lookupPostParams Text
pn = do
([(Text, Text)]
pp, [(Text, FileInfo)]
_) <- forall (m :: * -> *). MonadHandler m => m RequestBodyContents
runRequestBody
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' Text
pn [(Text, Text)]
pp
lookupPostParam :: (MonadResource m, MonadHandler m)
=> Text
-> m (Maybe Text)
lookupPostParam :: forall (m :: * -> *).
(MonadResource m, MonadHandler m) =>
Text -> m (Maybe Text)
lookupPostParam = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
(MonadResource m, MonadHandler m) =>
Text -> m [Text]
lookupPostParams
lookupFile :: MonadHandler m
=> Text
-> m (Maybe FileInfo)
lookupFile :: forall (m :: * -> *). MonadHandler m => Text -> m (Maybe FileInfo)
lookupFile = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadHandler m => Text -> m [FileInfo]
lookupFiles
lookupFiles :: MonadHandler m
=> Text
-> m [FileInfo]
lookupFiles :: forall (m :: * -> *). MonadHandler m => Text -> m [FileInfo]
lookupFiles Text
pn = do
([(Text, Text)]
_, [(Text, FileInfo)]
files) <- forall (m :: * -> *). MonadHandler m => m RequestBodyContents
runRequestBody
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' Text
pn [(Text, FileInfo)]
files
lookupCookie :: MonadHandler m => Text -> m (Maybe Text)
lookupCookie :: forall (m :: * -> *). MonadHandler m => Text -> m (Maybe Text)
lookupCookie = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [a] -> Maybe a
listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadHandler m => Text -> m [Text]
lookupCookies
lookupCookies :: MonadHandler m => Text -> m [Text]
lookupCookies :: forall (m :: * -> *). MonadHandler m => Text -> m [Text]
lookupCookies Text
pn = do
YesodRequest
rr <- forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. Eq a => a -> [(a, b)] -> [b]
lookup' Text
pn forall a b. (a -> b) -> a -> b
$ YesodRequest -> [(Text, Text)]
reqCookies YesodRequest
rr
selectRep :: MonadHandler m
=> Writer.Writer (Endo [ProvidedRep m]) ()
-> m TypedContent
selectRep :: forall (m :: * -> *).
MonadHandler m =>
Writer (Endo [ProvidedRep m]) () -> m TypedContent
selectRep Writer (Endo [ProvidedRep m]) ()
w = do
[ByteString]
cts <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap YesodRequest -> [ByteString]
reqAccept forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
case forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ByteString -> Maybe (ProvidedRep m)
tryAccept [ByteString]
cts of
[] ->
case [ProvidedRep m]
reps of
[] -> forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
Status -> c -> m a
sendResponseStatus Status
H.status500 (Text
"No reps provided to selectRep" :: Text)
ProvidedRep m
rep:[ProvidedRep m]
_ -> forall {f :: * -> *}. Functor f => ProvidedRep f -> f TypedContent
returnRep ProvidedRep m
rep
ProvidedRep m
rep:[ProvidedRep m]
_ -> forall {f :: * -> *}. Functor f => ProvidedRep f -> f TypedContent
returnRep ProvidedRep m
rep
where
returnRep :: ProvidedRep f -> f TypedContent
returnRep (ProvidedRep ByteString
ct f Content
mcontent) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ByteString -> Content -> TypedContent
TypedContent ByteString
ct) f Content
mcontent
reps :: [ProvidedRep m]
reps = forall a. Endo a -> a -> a
appEndo (forall w a. Writer w a -> w
Writer.execWriter Writer (Endo [ProvidedRep m]) ()
w) []
repMap :: Map ByteString (ProvidedRep m)
repMap = forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\v :: ProvidedRep m
v@(ProvidedRep ByteString
k m Content
_) -> forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
[ (ByteString
k, ProvidedRep m
v)
, (ByteString -> ByteString
noSpace ByteString
k, ProvidedRep m
v)
, (ByteString -> ByteString
simpleContentType ByteString
k, ProvidedRep m
v)
]) [ProvidedRep m]
reps
mainTypeMap :: Map ByteString (ProvidedRep m)
mainTypeMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map
(\v :: ProvidedRep m
v@(ProvidedRep ByteString
ct m Content
_) -> (forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ ByteString -> Param
contentTypeTypes ByteString
ct, ProvidedRep m
v)) [ProvidedRep m]
reps
tryAccept :: ByteString -> Maybe (ProvidedRep m)
tryAccept ByteString
ct =
if ByteString
subType forall a. Eq a => a -> a -> Bool
== ByteString
"*"
then if ByteString
mainType forall a. Eq a => a -> a -> Bool
== ByteString
"*"
then forall a. [a] -> Maybe a
listToMaybe [ProvidedRep m]
reps
else forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ByteString
mainType Map ByteString (ProvidedRep m)
mainTypeMap
else ByteString -> Maybe (ProvidedRep m)
lookupAccept ByteString
ct
where
(ByteString
mainType, ByteString
subType) = ByteString -> Param
contentTypeTypes ByteString
ct
lookupAccept :: ByteString -> Maybe (ProvidedRep m)
lookupAccept ByteString
ct = forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ByteString
ct Map ByteString (ProvidedRep m)
repMap forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (ByteString -> ByteString
noSpace ByteString
ct) Map ByteString (ProvidedRep m)
repMap forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (ByteString -> ByteString
simpleContentType ByteString
ct) Map ByteString (ProvidedRep m)
repMap
noSpace :: ByteString -> ByteString
noSpace = (Char -> Bool) -> ByteString -> ByteString
S8.filter (forall a. Eq a => a -> a -> Bool
/= Char
' ')
data ProvidedRep m = ProvidedRep !ContentType !(m Content)
provideRep :: (Monad m, HasContentType a)
=> m a
-> Writer.Writer (Endo [ProvidedRep m]) ()
provideRep :: forall (m :: * -> *) a.
(Monad m, HasContentType a) =>
m a -> Writer (Endo [ProvidedRep m]) ()
provideRep m a
handler = forall (m :: * -> *) a.
(Monad m, ToContent a) =>
ByteString -> m a -> Writer (Endo [ProvidedRep m]) ()
provideRepType (forall a (m :: * -> *).
(HasContentType a, Monad m) =>
m a -> ByteString
getContentType m a
handler) m a
handler
provideRepType :: (Monad m, ToContent a)
=> ContentType
-> m a
-> Writer.Writer (Endo [ProvidedRep m]) ()
provideRepType :: forall (m :: * -> *) a.
(Monad m, ToContent a) =>
ByteString -> m a -> Writer (Endo [ProvidedRep m]) ()
provideRepType ByteString
ct m a
handler =
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
Writer.tell forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> Endo a
Endo (forall (m :: * -> *). ByteString -> m Content -> ProvidedRep m
ProvidedRep ByteString
ct (forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. ToContent a => a -> Content
toContent m a
handler)forall a. a -> [a] -> [a]
:)
rawRequestBody :: MonadHandler m => ConduitT i S.ByteString m ()
rawRequestBody :: forall (m :: * -> *) i.
MonadHandler m =>
ConduitT i ByteString m ()
rawRequestBody = do
Request
req <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall (m :: * -> *). MonadHandler m => m Request
waiRequest
let loop :: ConduitT i ByteString m ()
loop = do
ByteString
bs <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Request -> IO ByteString
W.requestBody Request
req
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteString -> Bool
S.null ByteString
bs) forall a b. (a -> b) -> a -> b
$ do
forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
bs
ConduitT i ByteString m ()
loop
ConduitT i ByteString m ()
loop
fileSource :: MonadResource m => FileInfo -> ConduitT () S.ByteString m ()
fileSource :: forall (m :: * -> *).
MonadResource m =>
FileInfo -> ConduitT () ByteString m ()
fileSource = forall (m :: * -> *) (n :: * -> *) i o r.
Monad m =>
(forall a. m a -> n a) -> ConduitT i o m r -> ConduitT i o n r
transPipe forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
liftResourceT forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileInfo -> ConduitT () ByteString (ResourceT IO) ()
fileSourceRaw
fileSourceByteString :: MonadResource m => FileInfo -> m S.ByteString
fileSourceByteString :: forall (m :: * -> *). MonadResource m => FileInfo -> m ByteString
fileSourceByteString FileInfo
fileInfo = forall (m :: * -> *) r. Monad m => ConduitT () Void m r -> m r
runConduit (ByteString -> ByteString
L.toStrict forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall (m :: * -> *).
MonadResource m =>
FileInfo -> ConduitT () ByteString m ()
fileSource FileInfo
fileInfo forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
.| forall (m :: * -> *) lazy strict o.
(Monad m, LazySequence lazy strict) =>
ConduitT strict o m lazy
sinkLazy))
respond :: (Monad m, ToContent a) => ContentType -> a -> m TypedContent
respond :: forall (m :: * -> *) a.
(Monad m, ToContent a) =>
ByteString -> a -> m TypedContent
respond ByteString
ct = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Content -> TypedContent
TypedContent ByteString
ct forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToContent a => a -> Content
toContent
respondSource :: ContentType
-> ConduitT () (Flush Builder) (HandlerFor site) ()
-> HandlerFor site TypedContent
respondSource :: forall site.
ByteString
-> ConduitT () (Flush Builder) (HandlerFor site) ()
-> HandlerFor site TypedContent
respondSource ByteString
ctype ConduitT () (Flush Builder) (HandlerFor site) ()
src = forall site a. (HandlerData site site -> IO a) -> HandlerFor site a
HandlerFor forall a b. (a -> b) -> a -> b
$ \HandlerData site site
hd ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Content -> TypedContent
TypedContent ByteString
ctype forall a b. (a -> b) -> a -> b
$ ConduitT () (Flush Builder) (ResourceT IO) () -> Content
ContentSource
forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) (n :: * -> *) i o r.
Monad m =>
(forall a. m a -> n a) -> ConduitT i o m r -> ConduitT i o n r
transPipe (forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall site a. HandlerFor site a -> HandlerData site site -> IO a
unHandlerFor HandlerData site site
hd) ConduitT () (Flush Builder) (HandlerFor site) ()
src
sendChunk :: Monad m => ToFlushBuilder a => a -> ConduitT i (Flush Builder) m ()
sendChunk :: forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk = forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToFlushBuilder a => a -> Flush Builder
toFlushBuilder
sendFlush :: Monad m => ConduitT i (Flush Builder) m ()
sendFlush :: forall (m :: * -> *) i. Monad m => ConduitT i (Flush Builder) m ()
sendFlush = forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield forall a. Flush a
Flush
sendChunkBS :: Monad m => S.ByteString -> ConduitT i (Flush Builder) m ()
sendChunkBS :: forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i (Flush Builder) m ()
sendChunkBS = forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk
sendChunkLBS :: Monad m => L.ByteString -> ConduitT i (Flush Builder) m ()
sendChunkLBS :: forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i (Flush Builder) m ()
sendChunkLBS = forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk
sendChunkText :: Monad m => T.Text -> ConduitT i (Flush Builder) m ()
sendChunkText :: forall (m :: * -> *) i.
Monad m =>
Text -> ConduitT i (Flush Builder) m ()
sendChunkText = forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk
sendChunkLazyText :: Monad m => TL.Text -> ConduitT i (Flush Builder) m ()
sendChunkLazyText :: forall (m :: * -> *) i.
Monad m =>
Text -> ConduitT i (Flush Builder) m ()
sendChunkLazyText = forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk
sendChunkHtml :: Monad m => Html -> ConduitT i (Flush Builder) m ()
sendChunkHtml :: forall (m :: * -> *) i.
Monad m =>
Html -> ConduitT i (Flush Builder) m ()
sendChunkHtml = forall (m :: * -> *) a i.
(Monad m, ToFlushBuilder a) =>
a -> ConduitT i (Flush Builder) m ()
sendChunk
defaultCsrfCookieName :: S8.ByteString
defaultCsrfCookieName :: ByteString
defaultCsrfCookieName = ByteString
"XSRF-TOKEN"
setCsrfCookie :: MonadHandler m => m ()
setCsrfCookie :: forall (m :: * -> *). MonadHandler m => m ()
setCsrfCookie = forall (m :: * -> *). MonadHandler m => SetCookie -> m ()
setCsrfCookieWithCookie SetCookie
defaultSetCookie
{ setCookieName :: ByteString
setCookieName = ByteString
defaultCsrfCookieName
, setCookiePath :: Maybe ByteString
setCookiePath = forall a. a -> Maybe a
Just ByteString
"/"
}
setCsrfCookieWithCookie :: MonadHandler m => SetCookie -> m ()
setCsrfCookieWithCookie :: forall (m :: * -> *). MonadHandler m => SetCookie -> m ()
setCsrfCookieWithCookie SetCookie
cookie = do
Maybe Text
mCsrfToken <- YesodRequest -> Maybe Text
reqToken forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
Fold.forM_ Maybe Text
mCsrfToken (\Text
token -> forall (m :: * -> *). MonadHandler m => SetCookie -> m ()
setCookie forall a b. (a -> b) -> a -> b
$ SetCookie
cookie { setCookieValue :: ByteString
setCookieValue = Text -> ByteString
encodeUtf8 Text
token })
defaultCsrfHeaderName :: CI S8.ByteString
= CI ByteString
"X-XSRF-TOKEN"
checkCsrfHeaderNamed :: MonadHandler m => CI S8.ByteString -> m ()
CI ByteString
headerName = do
(Bool
valid, Maybe Text
mHeader) <- forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Bool, Maybe Text)
hasValidCsrfHeaderNamed' CI ByteString
headerName
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
valid (forall (m :: * -> *) a. MonadHandler m => Text -> m a
permissionDenied forall a b. (a -> b) -> a -> b
$ [CSRFExpectation] -> Text
csrfErrorMessage [Text -> Maybe Text -> CSRFExpectation
CSRFHeader (ByteString -> Text
decodeUtf8 forall a b. (a -> b) -> a -> b
$ forall s. CI s -> s
original CI ByteString
headerName) Maybe Text
mHeader])
hasValidCsrfHeaderNamed :: MonadHandler m => CI S8.ByteString -> m Bool
CI ByteString
headerName = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Bool, Maybe Text)
hasValidCsrfHeaderNamed' CI ByteString
headerName
hasValidCsrfHeaderNamed' :: MonadHandler m => CI S8.ByteString -> m (Bool, Maybe Text)
CI ByteString
headerName = do
Maybe Text
mCsrfToken <- YesodRequest -> Maybe Text
reqToken forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
Maybe ByteString
mXsrfHeader <- forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Maybe ByteString)
lookupHeader CI ByteString
headerName
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Maybe Text -> Maybe ByteString -> Bool
validCsrf Maybe Text
mCsrfToken Maybe ByteString
mXsrfHeader, ByteString -> Text
decodeUtf8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
mXsrfHeader)
defaultCsrfParamName :: Text
defaultCsrfParamName :: Text
defaultCsrfParamName = Text
"_token"
checkCsrfParamNamed :: MonadHandler m => Text -> m ()
checkCsrfParamNamed :: forall (m :: * -> *). MonadHandler m => Text -> m ()
checkCsrfParamNamed Text
paramName = do
(Bool
valid, Maybe Text
mParam) <- forall (m :: * -> *).
MonadHandler m =>
Text -> m (Bool, Maybe Text)
hasValidCsrfParamNamed' Text
paramName
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
valid (forall (m :: * -> *) a. MonadHandler m => Text -> m a
permissionDenied forall a b. (a -> b) -> a -> b
$ [CSRFExpectation] -> Text
csrfErrorMessage [Text -> Maybe Text -> CSRFExpectation
CSRFParam Text
paramName Maybe Text
mParam])
hasValidCsrfParamNamed :: MonadHandler m => Text -> m Bool
hasValidCsrfParamNamed :: forall (m :: * -> *). MonadHandler m => Text -> m Bool
hasValidCsrfParamNamed Text
paramName = forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadHandler m =>
Text -> m (Bool, Maybe Text)
hasValidCsrfParamNamed' Text
paramName
hasValidCsrfParamNamed' :: MonadHandler m => Text -> m (Bool, Maybe Text)
hasValidCsrfParamNamed' :: forall (m :: * -> *).
MonadHandler m =>
Text -> m (Bool, Maybe Text)
hasValidCsrfParamNamed' Text
paramName = do
Maybe Text
mCsrfToken <- YesodRequest -> Maybe Text
reqToken forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
Maybe Text
mCsrfParam <- forall (m :: * -> *).
(MonadResource m, MonadHandler m) =>
Text -> m (Maybe Text)
lookupPostParam Text
paramName
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Maybe Text -> Maybe ByteString -> Bool
validCsrf Maybe Text
mCsrfToken (Text -> ByteString
encodeUtf8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
mCsrfParam), Maybe Text
mCsrfParam)
checkCsrfHeaderOrParam :: (MonadHandler m, MonadLogger m)
=> CI S8.ByteString
-> Text
-> m ()
CI ByteString
headerName Text
paramName = do
(Bool
validHeader, Maybe Text
mHeader) <- forall (m :: * -> *).
MonadHandler m =>
CI ByteString -> m (Bool, Maybe Text)
hasValidCsrfHeaderNamed' CI ByteString
headerName
(Bool
validParam, Maybe Text
mParam) <- forall (m :: * -> *).
MonadHandler m =>
Text -> m (Bool, Maybe Text)
hasValidCsrfParamNamed' Text
paramName
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Bool
validHeader Bool -> Bool -> Bool
|| Bool
validParam) forall a b. (a -> b) -> a -> b
$ do
let errorMessage :: Text
errorMessage = [CSRFExpectation] -> Text
csrfErrorMessage forall a b. (a -> b) -> a -> b
$ [Text -> Maybe Text -> CSRFExpectation
CSRFHeader (ByteString -> Text
decodeUtf8 forall a b. (a -> b) -> a -> b
$ forall s. CI s -> s
original CI ByteString
headerName) Maybe Text
mHeader, Text -> Maybe Text -> CSRFExpectation
CSRFParam Text
paramName Maybe Text
mParam]
$Text -> Text -> m ()
logWarnS Text
"yesod-core" Text
errorMessage
forall (m :: * -> *) a. MonadHandler m => Text -> m a
permissionDenied Text
errorMessage
validCsrf :: Maybe Text -> Maybe S.ByteString -> Bool
validCsrf :: Maybe Text -> Maybe ByteString -> Bool
validCsrf (Just Text
token) (Just ByteString
param) = Text -> ByteString
encodeUtf8 Text
token forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
`constEq` ByteString
param
validCsrf Maybe Text
Nothing Maybe ByteString
_param = Bool
True
validCsrf (Just Text
_token) Maybe ByteString
Nothing = Bool
False
data CSRFExpectation = Text (Maybe Text)
| CSRFParam Text (Maybe Text)
csrfErrorMessage :: [CSRFExpectation]
-> Text
csrfErrorMessage :: [CSRFExpectation] -> Text
csrfErrorMessage [CSRFExpectation]
expectedLocations = Text -> [Text] -> Text
T.intercalate Text
"\n"
[ Text
"A valid CSRF token wasn't present. Because the request could have been forged, it's been rejected altogether."
, Text
"If you're a developer of this site, these tips will help you debug the issue:"
, Text
"- Read the Yesod.Core.Handler docs of the yesod-core package for details on CSRF protection."
, Text
"- Check that your HTTP client is persisting cookies between requests, like a browser does."
, Text
"- By default, the CSRF token is sent to the client in a cookie named " forall a. Monoid a => a -> a -> a
`mappend` (ByteString -> Text
decodeUtf8 ByteString
defaultCsrfCookieName) forall a. Monoid a => a -> a -> a
`mappend` Text
"."
, Text
"- The server is looking for the token in the following locations:\n" forall a. Monoid a => a -> a -> a
`mappend` Text -> [Text] -> Text
T.intercalate Text
"\n" (forall a b. (a -> b) -> [a] -> [b]
map CSRFExpectation -> Text
csrfLocation [CSRFExpectation]
expectedLocations)
]
where csrfLocation :: CSRFExpectation -> Text
csrfLocation CSRFExpectation
expected = case CSRFExpectation
expected of
CSRFHeader Text
k Maybe Text
v -> Text -> [Text] -> Text
T.intercalate Text
" " [Text
" - An HTTP header named", Text
k, (Maybe Text -> Text
formatValue Maybe Text
v)]
CSRFParam Text
k Maybe Text
v -> Text -> [Text] -> Text
T.intercalate Text
" " [Text
" - A POST parameter named", Text
k, (Maybe Text -> Text
formatValue Maybe Text
v)]
formatValue :: Maybe Text -> Text
formatValue :: Maybe Text -> Text
formatValue Maybe Text
maybeText = case Maybe Text
maybeText of
Maybe Text
Nothing -> Text
"(which is not currently set)"
Just Text
t -> [Text] -> Text
T.concat [Text
"(which has the current, incorrect value: '", Text
t, Text
"')"]
getSubYesod :: MonadHandler m => m (SubHandlerSite m)
getSubYesod :: forall (m :: * -> *). MonadHandler m => m (SubHandlerSite m)
getSubYesod = forall (m :: * -> *) a.
MonadHandler m =>
SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a
liftSubHandler forall a b. (a -> b) -> a -> b
$ forall sub master a.
(HandlerData sub master -> IO a) -> SubHandlerFor sub master a
SubHandlerFor forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. RunHandlerEnv child site -> child
rheChild forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv
getRouteToParent :: MonadHandler m => m (Route (SubHandlerSite m) -> Route (HandlerSite m))
getRouteToParent :: forall (m :: * -> *).
MonadHandler m =>
m (Route (SubHandlerSite m) -> Route (HandlerSite m))
getRouteToParent = forall (m :: * -> *) a.
MonadHandler m =>
SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a
liftSubHandler forall a b. (a -> b) -> a -> b
$ forall sub master a.
(HandlerData sub master -> IO a) -> SubHandlerFor sub master a
SubHandlerFor forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site.
RunHandlerEnv child site -> Route child -> Route site
rheRouteToMaster forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv
getSubCurrentRoute :: MonadHandler m => m (Maybe (Route (SubHandlerSite m)))
getSubCurrentRoute :: forall (m :: * -> *).
MonadHandler m =>
m (Maybe (Route (SubHandlerSite m)))
getSubCurrentRoute = forall (m :: * -> *) a.
MonadHandler m =>
SubHandlerFor (SubHandlerSite m) (HandlerSite m) a -> m a
liftSubHandler forall a b. (a -> b) -> a -> b
$ forall sub master a.
(HandlerData sub master -> IO a) -> SubHandlerFor sub master a
SubHandlerFor forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site. RunHandlerEnv child site -> Maybe (Route child)
rheRoute forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall child site.
HandlerData child site -> RunHandlerEnv child site
handlerEnv