-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Another Haskell web framework for rapid development -- -- This toolbox provides everything you need to get a quick start into -- web hacking with haskell: -- -- -- -- A tutorial is available at spock.li @package Spock @version 0.12.0.0 module Web.Spock.Internal.SessionVault class (Eq (SessionKey s), Hashable (SessionKey s)) => IsSession s where type SessionKey s :: * where { type family SessionKey s :: *; } getSessionKey :: IsSession s => s -> SessionKey s newtype SessionVault s SessionVault :: Map (SessionKey s) s -> SessionVault s [unSessionVault] :: SessionVault s -> Map (SessionKey s) s -- | Create a new session vault newSessionVault :: STM (SessionVault s) -- | Load a session loadSession :: IsSession s => SessionKey s -> SessionVault s -> STM (Maybe s) -- | Store a session, overwriting any previous values storeSession :: IsSession s => s -> SessionVault s -> STM () -- | Removea session deleteSession :: IsSession s => SessionKey s -> SessionVault s -> STM () -- | Get all sessions as list toList :: SessionVault s -> STM [s] -- | Remove all sessions that do not match the predicate filterSessions :: IsSession s => (s -> Bool) -> SessionVault s -> STM () -- | Perform action on all sessions mapSessions :: IsSession s => (s -> STM s) -> SessionVault s -> STM () newStmSessionStore' :: IO (SessionStore (Session conn sess st) STM) newStmSessionStore :: IO (SessionStoreInstance (Session conn sess st)) instance Web.Spock.Internal.SessionVault.IsSession (Web.Spock.Internal.Types.Session conn sess st) module Web.Spock.Internal.SessionManager createSessionManager :: MonadIO m => SessionCfg conn sess st -> SessionIf m -> IO (SessionManager m conn sess st) withSessionManager :: MonadIO m => SessionCfg conn sess st -> SessionIf m -> (SessionManager m conn sess st -> IO a) -> IO a type SessionId = Text data Session conn sess st Session :: !SessionId -> !Text -> !UTCTime -> !sess -> Session conn sess st [sess_id] :: Session conn sess st -> !SessionId [sess_csrfToken] :: Session conn sess st -> !Text [sess_validUntil] :: Session conn sess st -> !UTCTime [sess_data] :: Session conn sess st -> !sess data SessionManager m conn sess st SessionManager :: m SessionId -> m Text -> m () -> m sess -> (sess -> m ()) -> (forall a. (sess -> (sess, a)) -> m a) -> ((forall n. Monad n => sess -> n sess) -> m ()) -> (MonadIO m => m ()) -> Middleware -> IO () -> SessionManager m conn sess st [sm_getSessionId] :: SessionManager m conn sess st -> m SessionId [sm_getCsrfToken] :: SessionManager m conn sess st -> m Text [sm_regenerateSessionId] :: SessionManager m conn sess st -> m () [sm_readSession] :: SessionManager m conn sess st -> m sess [sm_writeSession] :: SessionManager m conn sess st -> sess -> m () [sm_modifySession] :: SessionManager m conn sess st -> forall a. (sess -> (sess, a)) -> m a [sm_mapSessions] :: SessionManager m conn sess st -> (forall n. Monad n => sess -> n sess) -> m () [sm_clearAllSessions] :: SessionManager m conn sess st -> MonadIO m => m () [sm_middleware] :: SessionManager m conn sess st -> Middleware [sm_closeSessionManager] :: SessionManager m conn sess st -> IO () data SessionIf m SessionIf :: (forall a. Key a -> m (Maybe a)) -> ((Vault -> Vault) -> m ()) -> (MultiHeader -> ByteString -> m ()) -> IO (Key SessionId) -> SessionIf m [si_queryVault] :: SessionIf m -> forall a. Key a -> m (Maybe a) [si_modifyVault] :: SessionIf m -> (Vault -> Vault) -> m () [si_setRawMultiHeader] :: SessionIf m -> MultiHeader -> ByteString -> m () [si_vaultKey] :: SessionIf m -> IO (Key SessionId) module Web.Spock.SessionActions type SessionId = Text -- | Regenerate the users sessionId. This preserves all stored data. Call -- this prior to logging in a user to prevent session fixation attacks. sessionRegenerateId :: SpockActionCtx ctx conn sess st () -- | Get the current users sessionId. Note that this ID should only be -- shown to it's owner as otherwise sessions can be hijacked. getSessionId :: SpockActionCtx ctx conn sess st SessionId -- | Read the stored session readSession :: SpockActionCtx ctx conn sess st sess -- | Write to the current session. Note that all data is stored on the -- server. The user only reciedes a sessionId to be identified. writeSession :: forall sess ctx conn st. sess -> SpockActionCtx ctx conn sess st () -- | Modify the stored session modifySession :: (sess -> sess) -> SpockActionCtx ctx conn sess st () -- | Modify the stored session and return a value modifySession' :: (sess -> (sess, a)) -> SpockActionCtx ctx conn sess st a -- | Modify the stored session and return the new value after modification modifyReadSession :: (sess -> sess) -> SpockActionCtx ctx conn sess st sess -- | Apply a transformation to all sessions. Be careful with this, as this -- may cause many STM transaction retries. mapAllSessions :: (forall m. Monad m => sess -> m sess) -> SpockActionCtx ctx conn sess st () -- | Globally delete all existing sessions. This is useful for example if -- you want to require all users to relogin clearAllSessions :: SpockActionCtx ctx conn sess st () module Web.Spock.Config -- | Spock configuration, use defaultSpockCfg and change single -- values if needed data SpockCfg conn sess st SpockCfg :: st -> PoolOrConn conn -> SessionCfg conn sess st -> Maybe Word64 -> (Status -> ActionCtxT () IO ()) -> Bool -> Text -> Text -> SpockCfg conn sess st -- | initial application global state [spc_initialState] :: SpockCfg conn sess st -> st -- | See PoolOrConn [spc_database] :: SpockCfg conn sess st -> PoolOrConn conn -- | See SessionCfg [spc_sessionCfg] :: SpockCfg conn sess st -> SessionCfg conn sess st -- | Maximum request size in bytes. Nothing means no limit. Defaults -- to 5 MB in defaultSpockCfg. [spc_maxRequestSize] :: SpockCfg conn sess st -> Maybe Word64 -- | Custom error handlers for implicit errors such as not matching routes -- or exceptions during a request handler run. [spc_errorHandler] :: SpockCfg conn sess st -> Status -> ActionCtxT () IO () -- | When set to true, all non GET request will require either an -- HTTP-Header spc_csrfHeaderName or a POST-Parameter -- spc_csrfPostName to be set to the value aquired by -- getCsrfToken [spc_csrfProtection] :: SpockCfg conn sess st -> Bool -- | see spc_csrfHeaderName [spc_csrfHeaderName] :: SpockCfg conn sess st -> Text -- | see spc_csrfPostName [spc_csrfPostName] :: SpockCfg conn sess st -> Text -- | Spock configuration with reasonable defaults such as a basic error -- page and 5MB request body limit. IMPORTANT: CSRF Protection is turned -- off by default for now to not break any existing Spock applications. -- Consider turning it on manually as it will become the default in the -- future. defaultSpockCfg :: sess -> PoolOrConn conn -> st -> IO (SpockCfg conn sess st) -- | You can feed Spock with either a connection pool, or instructions on -- how to build a connection pool. See ConnBuilder data PoolOrConn a [PCPool] :: Pool a -> PoolOrConn a [PCConn] :: ConnBuilder a -> PoolOrConn a [PCNoDatabase] :: PoolOrConn () -- | The ConnBuilder instructs Spock how to create or close a database -- connection. data ConnBuilder a ConnBuilder :: IO a -> (a -> IO ()) -> PoolCfg -> ConnBuilder a [cb_createConn] :: ConnBuilder a -> IO a [cb_destroyConn] :: ConnBuilder a -> a -> IO () [cb_poolConfiguration] :: ConnBuilder a -> PoolCfg -- | If Spock should take care of connection pooling, you need to configure -- it depending on what you need. data PoolCfg PoolCfg :: Int -> Int -> NominalDiffTime -> PoolCfg [pc_stripes] :: PoolCfg -> Int [pc_resPerStripe] :: PoolCfg -> Int [pc_keepOpenTime] :: PoolCfg -> NominalDiffTime -- | Session configuration with reasonable defaults and an stm based -- session store defaultSessionCfg :: a -> IO (SessionCfg conn a st) -- | Configuration for the session manager data SessionCfg conn a st SessionCfg :: Text -> NominalDiffTime -> Int -> Bool -> a -> SessionStoreInstance (Session conn a st) -> NominalDiffTime -> SessionHooks a -> SessionCfg conn a st -- | name of the client side cookie [sc_cookieName] :: SessionCfg conn a st -> Text -- | how long shoud a client session live [sc_sessionTTL] :: SessionCfg conn a st -> NominalDiffTime -- | entropy of the session id sent to the client [sc_sessionIdEntropy] :: SessionCfg conn a st -> Int -- | if this is true, every page reload will renew the session time to live -- counter [sc_sessionExpandTTL] :: SessionCfg conn a st -> Bool -- | initial session for visitors [sc_emptySession] :: SessionCfg conn a st -> a -- | storage interface for sessions [sc_store] :: SessionCfg conn a st -> SessionStoreInstance (Session conn a st) -- | how often should the session manager check for dangeling dead sessions [sc_housekeepingInterval] :: SessionCfg conn a st -> NominalDiffTime -- | hooks into the session manager [sc_hooks] :: SessionCfg conn a st -> SessionHooks a -- | NOP session hooks defaultSessionHooks :: SessionHooks a -- | Hook into the session manager to trigger custom behavior data SessionHooks a SessionHooks :: (HashMap SessionId a -> IO ()) -> SessionHooks a [sh_removed] :: SessionHooks a -> HashMap SessionId a -> IO () data SessionStore sess tx SessionStore :: (forall a. tx a -> IO a) -> (SessionId -> tx (Maybe sess)) -> (SessionId -> tx ()) -> (sess -> tx ()) -> tx [sess] -> ((sess -> Bool) -> tx ()) -> ((sess -> tx sess) -> tx ()) -> SessionStore sess tx [ss_runTx] :: SessionStore sess tx -> forall a. tx a -> IO a [ss_loadSession] :: SessionStore sess tx -> SessionId -> tx (Maybe sess) [ss_deleteSession] :: SessionStore sess tx -> SessionId -> tx () [ss_storeSession] :: SessionStore sess tx -> sess -> tx () [ss_toList] :: SessionStore sess tx -> tx [sess] [ss_filterSessions] :: SessionStore sess tx -> (sess -> Bool) -> tx () [ss_mapSessions] :: SessionStore sess tx -> (sess -> tx sess) -> tx () data SessionStoreInstance sess [SessionStoreInstance] :: forall sess tx. (Monad tx, Functor tx, Applicative tx) => SessionStore sess tx -> SessionStoreInstance sess newStmSessionStore :: IO (SessionStoreInstance (Session conn sess st)) module Web.Spock -- | Run a Spock application. Basically just a wrapper around run. runSpock :: Port -> IO Middleware -> IO () -- | Like runSpock, but does not display the banner "Spock is -- running on port XXX" on stdout. runSpockNoBanner :: Port -> IO Middleware -> IO () -- | Convert a middleware to an application. All failing requests will -- result in a 404 page spockAsApp :: IO Middleware -> IO Application -- | Create a spock application using a given db storageLayer and an -- initial state. Spock works with database libraries that already -- implement connection pooling and with those that don't come with it -- out of the box. For more see the PoolOrConn type. Use -- runSpock to run the app or spockAsApp to create a -- Wai.Application spock :: forall conn sess st. SpockCfg conn sess st -> SpockM conn sess st () -> IO Middleware type SpockM conn sess st = SpockCtxM () conn sess st type SpockCtxM ctx conn sess st = SpockCtxT ctx (WebStateM conn sess st) data Path (as :: [*]) (pathState :: PathState) :: [*] -> PathState -> * -- | The root of a path piece. Use to define a handler for "/" root :: Path ([] *) Open type Var a = Path ((:) * a ([] *)) Open -- | A route parameter var :: (Typeable * a, FromHttpApiData a) => Path ((:) * a ([] *)) Open -- | A static route piece static :: String -> Path ([] *) Open -- | Combine two path components () :: Path as Open -> Path bs ps -> Path (Append as bs) ps -- | Matches the rest of the route. Should be the last part of the path. wildcard :: Path ((:) * Text ([] *)) Closed -- | Render a route applying path pieces renderRoute :: AllHave ToHttpApiData as => Path as Open -> HVectElim as Text -- | Define a subcomponent. Usage example: -- --
--   subcomponent "site" $
--     do get "home" homeHandler
--        get ("misc" <//> var) $ -- ...
--   subcomponent "admin" $
--     do get "home" adminHomeHandler
--   
-- -- The request /site/home will be routed to homeHandler and the request -- /admin/home will be routed to adminHomeHandler subcomponent :: (RouteM t, Monad m) => Path ([] *) Open -> t ctx m () -> t ctx m () -- | Specify an action that will be run before all subroutes. It can modify -- the requests current context prehook :: (RouteM t, MonadIO m) => ActionCtxT ctx m ctx' -> t ctx' m () -> t ctx m () type RouteSpec xs ps ctx conn sess st = Path xs ps -> HVectElim xs (SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st () -- | Specify an action that will be run when the HTTP verb GET and -- the given route match get :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb POST and -- the given route match post :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb 'GET'/'POST' and -- the given route match getpost :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb HEAD and -- the given route match head :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb PUT and -- the given route match put :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb DELETE -- and the given route match delete :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when the HTTP verb PATCH and -- the given route match patch :: HasRep xs => RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when a standard HTTP verb and the -- given route match hookRoute :: HasRep xs => StdMethod -> RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when a custom HTTP verb and the -- given route match hookRouteCustom :: HasRep xs => Text -> RouteSpec xs ps ctx conn sess st -- | Specify an action that will be run when a standard HTTP verb matches -- but no defined route matches. The full path is passed as an argument hookAny :: StdMethod -> ([Text] -> SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st () -- | Specify an action that will be run when a custom HTTP verb matches but -- no defined route matches. The full path is passed as an argument hookAnyCustom :: Text -> ([Text] -> SpockActionCtx ctx conn sess st ()) -> SpockCtxM ctx conn sess st () -- | HTTP standard method (as defined by RFC 2616, and PATCH which is -- defined by RFC 5789). data StdMethod :: * GET :: StdMethod POST :: StdMethod HEAD :: StdMethod PUT :: StdMethod DELETE :: StdMethod TRACE :: StdMethod CONNECT :: StdMethod OPTIONS :: StdMethod PATCH :: StdMethod -- | Hook wai middleware into Spock middleware :: (RouteM t, Monad m) => Middleware -> t ctx m () -- | The SpockAction is a specialisation of SpockActionCtx -- with a '()' context. type SpockAction conn sess st = SpockActionCtx () conn sess st -- | The SpockActionCtx is the monad of all route-actions. You have -- access to the context of the request and database, session and state -- of your application. type SpockActionCtx ctx conn sess st = ActionCtxT ctx (WebStateM conn sess st) class HasSpock m where type SpockConn m :: * type SpockState m :: * type SpockSession m :: * where { type family SpockConn m :: *; type family SpockState m :: *; type family SpockSession m :: *; } -- | Give you access to a database connectin from the connection pool. The -- connection is released back to the pool once the function terminates. runQuery :: HasSpock m => (SpockConn m -> IO a) -> m a -- | Read the application's state. If you wish to have mutable state, you -- could use a TVar from the STM packge. getState :: HasSpock m => m (SpockState m) -- | Get the session manager getSessMgr :: HasSpock m => m (SpockSessionManager (SpockConn m) (SpockSession m) (SpockState m)) -- | Get the Spock configuration getSpockCfg :: HasSpock m => m (SpockCfg (SpockConn m) (SpockSession m) (SpockState m)) data SessionManager m conn sess st -- | Get the CSRF token for the current user. This token must be sent on -- all non GET requests via a post parameter or HTTP-Header if -- spc_csrfProtection is turned on. See configuration -- SpockCfg documentation for more information getCsrfToken :: SpockActionCtx ctx conn sess st Text -- | Get the CSRF token sent by the client. You should not need to call -- this manually if spc_csrfProtection is turned on. getClientCsrfToken :: SpockActionCtx ctx conn sess st (Maybe Text) -- | Check that the client sent a valid CSRF token. You should not need to -- call this manually in non GET requests if spc_csrfProtection is -- turned on. csrfCheck :: SpockActionCtx ctx conn sess st () type WebStateM conn sess st = WebStateT conn sess st (ResourceT IO) data WebStateT conn sess st m a data WebState conn sess st -- | Read the heart of Spock. This is useful if you want to construct your -- own monads that work with runQuery and getState using -- runSpockIO getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st) -- | Run an action inside of Spocks core monad. This allows you to use -- runQuery and getState runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a -- | Read the connection pool of Spock. This is useful if you want to -- construct your own monads that work with runQuery and -- getState using runSpockIO getSpockPool :: MonadTrans t => t (WebStateM conn sess st) (Pool conn)