Safe Haskell | None |
---|---|
Language | Haskell98 |
- runSpock :: Port -> IO Middleware -> IO ()
- runSpockNoBanner :: Port -> IO Middleware -> IO ()
- spockAsApp :: IO Middleware -> IO Application
- type SpockAction conn sess st = SpockActionCtx () conn sess st
- type SpockActionCtx ctx conn sess st = ActionCtxT ctx (WebStateM conn sess st)
- type ActionT = ActionCtxT ()
- data ActionCtxT ctx m a
- request :: MonadIO m => ActionCtxT ctx m Request
- header :: MonadIO m => Text -> ActionCtxT ctx m (Maybe Text)
- rawHeader :: MonadIO m => HeaderName -> ActionCtxT ctx m (Maybe ByteString)
- cookie :: MonadIO m => Text -> ActionCtxT ctx m (Maybe Text)
- reqMethod :: MonadIO m => ActionCtxT ctx m StdMethod
- preferredFormat :: MonadIO m => ActionCtxT ctx m ClientPreferredFormat
- data ClientPreferredFormat
- body :: MonadIO m => ActionCtxT ctx m ByteString
- jsonBody :: (MonadIO m, FromJSON a) => ActionCtxT ctx m (Maybe a)
- jsonBody' :: (MonadIO m, FromJSON a) => ActionCtxT ctx m a
- files :: MonadIO m => ActionCtxT ctx m (HashMap Text UploadedFile)
- data UploadedFile = UploadedFile {
- uf_name :: !Text
- uf_contentType :: !Text
- uf_tempLocation :: !FilePath
- params :: MonadIO m => ActionCtxT ctx m [(Text, Text)]
- param :: (PathPiece p, MonadIO m) => Text -> ActionCtxT ctx m (Maybe p)
- param' :: (PathPiece p, MonadIO m) => Text -> ActionCtxT ctx m p
- getContext :: MonadIO m => ActionCtxT ctx m ctx
- runInContext :: MonadIO m => ctx' -> ActionCtxT ctx' m a -> ActionCtxT ctx m a
- setStatus :: MonadIO m => Status -> ActionCtxT ctx m ()
- setHeader :: MonadIO m => Text -> Text -> ActionCtxT ctx m ()
- redirect :: MonadIO m => Text -> ActionCtxT ctx m a
- jumpNext :: MonadIO m => ActionCtxT ctx m a
- data CookieSettings = CookieSettings {
- cs_EOL :: CookieEOL
- cs_path :: ByteString
- cs_domain :: Maybe ByteString
- cs_HTTPOnly :: Bool
- cs_secure :: Bool
- defaultCookieSettings :: CookieSettings
- data CookieEOL
- setCookie :: MonadIO m => Text -> Text -> CookieSettings -> ActionCtxT ctx m ()
- deleteCookie :: MonadIO m => Text -> ActionCtxT ctx m ()
- bytes :: MonadIO m => ByteString -> ActionCtxT ctx m a
- lazyBytes :: MonadIO m => ByteString -> ActionCtxT ctx m a
- text :: MonadIO m => Text -> ActionCtxT ctx m a
- html :: MonadIO m => Text -> ActionCtxT ctx m a
- file :: MonadIO m => Text -> FilePath -> ActionCtxT ctx m a
- json :: (ToJSON a, MonadIO m) => a -> ActionCtxT ctx m b
- stream :: MonadIO m => StreamingBody -> ActionCtxT ctx m a
- response :: MonadIO m => (Status -> ResponseHeaders -> Response) -> ActionCtxT ctx m a
- middlewarePass :: MonadIO m => ActionCtxT ctx m a
- modifyVault :: MonadIO m => (Vault -> Vault) -> ActionCtxT ctx m ()
- queryVault :: MonadIO m => Key a -> ActionCtxT ctx m (Maybe a)
- data SpockCfg conn sess st = SpockCfg {
- spc_initialState :: st
- spc_database :: PoolOrConn conn
- spc_sessionCfg :: SessionCfg sess
- spc_maxRequestSize :: Maybe Word64
- defaultSpockCfg :: sess -> PoolOrConn conn -> st -> SpockCfg conn sess st
- data PoolOrConn a where
- PCPool :: Pool a -> PoolOrConn a
- PCConn :: ConnBuilder a -> PoolOrConn a
- PCNoDatabase :: PoolOrConn ()
- data ConnBuilder a = ConnBuilder {
- cb_createConn :: IO a
- cb_destroyConn :: a -> IO ()
- cb_poolConfiguration :: PoolCfg
- data PoolCfg = PoolCfg {}
- class HasSpock m where
- type SpockConn m :: *
- type SpockState m :: *
- type SpockSession m :: *
- runQuery :: (SpockConn m -> IO a) -> m a
- getState :: m (SpockState m)
- requireBasicAuth :: MonadIO m => Text -> (Text -> Text -> ActionCtxT ctx m b) -> (b -> ActionCtxT ctx m a) -> ActionCtxT ctx m a
- withBasicAuthData :: MonadIO m => (Maybe (Text, Text) -> ActionCtxT ctx m a) -> ActionCtxT ctx m a
- defaultSessionCfg :: a -> SessionCfg a
- data SessionCfg a = SessionCfg {}
- defaultSessionHooks :: SessionHooks a
- data SessionHooks a = SessionHooks {
- sh_removed :: HashMap SessionId a -> IO ()
- data SessionPersistCfg a = SessionPersistCfg {}
- readShowSessionPersist :: (Read a, Show a) => FilePath -> SessionPersistCfg a
- type SessionId = Text
- sessionRegenerateId :: SpockActionCtx ctx conn sess st ()
- getSessionId :: SpockActionCtx ctx conn sess st SessionId
- readSession :: SpockActionCtx ctx conn sess st sess
- writeSession :: sess -> SpockActionCtx ctx conn sess st ()
- modifySession :: (sess -> sess) -> SpockActionCtx ctx conn sess st ()
- modifySession' :: (sess -> (sess, a)) -> SpockActionCtx ctx conn sess st a
- modifyReadSession :: (sess -> sess) -> SpockActionCtx ctx conn sess st sess
- mapAllSessions :: (sess -> STM sess) -> SpockActionCtx ctx conn sess st ()
- clearAllSessions :: SpockActionCtx ctx conn sess st ()
- getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st)
- runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a
- type WebStateM conn sess st = WebStateT conn sess st (ResourceT IO)
- data WebState conn sess st
Helpers for running Spock
runSpock :: Port -> IO Middleware -> IO () Source
Run a Spock application. Basically just a wrapper aroung run
.
runSpockNoBanner :: Port -> IO Middleware -> IO () Source
Like runSpock
, but does not display the banner "Spock is running on port XXX" on stdout.
spockAsApp :: IO Middleware -> IO Application Source
Convert a middleware to an application. All failing requests will result in a 404 page
Action types
type SpockAction conn sess st = SpockActionCtx () conn sess st Source
The SpockAction
is a specialisation of SpockActionCtx
with a '()' context.
type SpockActionCtx ctx conn sess st = ActionCtxT ctx (WebStateM conn sess st) Source
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 ActionT = ActionCtxT () Source
data ActionCtxT ctx m a Source
MonadTrans (ActionCtxT ctx) Source | |
Monad m => Monad (ActionCtxT ctx m) Source | |
Functor m => Functor (ActionCtxT ctx m) Source | |
Monad m => Applicative (ActionCtxT ctx m) Source | |
Monad m => Alternative (ActionCtxT ctx m) Source | |
MonadIO m => MonadIO (ActionCtxT ctx m) Source |
Handling requests
request :: MonadIO m => ActionCtxT ctx m Request Source
Get the original Wai Request object
rawHeader :: MonadIO m => HeaderName -> ActionCtxT ctx m (Maybe ByteString) Source
Read a header without converting it to text
cookie :: MonadIO m => Text -> ActionCtxT ctx m (Maybe Text) Source
Read a cookie. The cookie value will already be urldecoded.
reqMethod :: MonadIO m => ActionCtxT ctx m StdMethod Source
Returns the current request method, e.g. GET
preferredFormat :: MonadIO m => ActionCtxT ctx m ClientPreferredFormat Source
Tries to dected the preferred format of the response using the Accept header
body :: MonadIO m => ActionCtxT ctx m ByteString Source
Get the raw request body
jsonBody :: (MonadIO m, FromJSON a) => ActionCtxT ctx m (Maybe a) Source
Parse the request body as json
jsonBody' :: (MonadIO m, FromJSON a) => ActionCtxT ctx m a Source
Parse the request body as json and fails with 400 status code on error
files :: MonadIO m => ActionCtxT ctx m (HashMap Text UploadedFile) Source
Get uploaded files
data UploadedFile Source
UploadedFile | |
|
param :: (PathPiece p, MonadIO m) => Text -> ActionCtxT ctx m (Maybe p) Source
Read a request param. Spock looks in route captures first (in simple routing), then in POST variables and at last in GET variables
param' :: (PathPiece p, MonadIO m) => Text -> ActionCtxT ctx m p Source
Like param
, but outputs an error when a param is missing
Working with context
getContext :: MonadIO m => ActionCtxT ctx m ctx Source
Get the context of the current request
runInContext :: MonadIO m => ctx' -> ActionCtxT ctx' m a -> ActionCtxT ctx m a Source
Run an Action in a different context
Sending responses
setStatus :: MonadIO m => Status -> ActionCtxT ctx m () Source
Set a response status
setHeader :: MonadIO m => Text -> Text -> ActionCtxT ctx m () Source
Set a response header. If the response header
is allowed to occur multiple times (as in RFC 2616), it will
be appended. Otherwise the previous value is overwritten.
See setMultiHeader
.
redirect :: MonadIO m => Text -> ActionCtxT ctx m a Source
Redirect to a given url
jumpNext :: MonadIO m => ActionCtxT ctx m a Source
Abort the current action and jump the next one matching the route
data CookieSettings Source
Cookie settings
CookieSettings | |
|
defaultCookieSettings :: CookieSettings Source
Default cookie settings, equals
CookieSettings { cs_EOL = CookieValidForSession , cs_HTTPOnly = False , cs_secure = False , cs_domain = Nothing , cs_path = "/" }
Setting cookie expiration
CookieValidUntil UTCTime | a point in time in UTC until the cookie is valid |
CookieValidFor NominalDiffTime | a period (in seconds) for which the cookie is valid |
CookieValidForSession | the cookie expires with the browser session |
setCookie :: MonadIO m => Text -> Text -> CookieSettings -> ActionCtxT ctx m () Source
Set a cookie. The cookie value will be urlencoded.
deleteCookie :: MonadIO m => Text -> ActionCtxT ctx m () Source
Delete a cookie
bytes :: MonadIO m => ByteString -> ActionCtxT ctx m a Source
Send a ByteString
as response body. Provide your own Content-Type
lazyBytes :: MonadIO m => ByteString -> ActionCtxT ctx m a Source
Send a lazy ByteString
as response body. Provide your own Content-Type
text :: MonadIO m => Text -> ActionCtxT ctx m a Source
Send text as a response body. Content-Type will be "text/plain"
html :: MonadIO m => Text -> ActionCtxT ctx m a Source
Send a text as response body. Content-Type will be "text/html"
json :: (ToJSON a, MonadIO m) => a -> ActionCtxT ctx m b Source
Send json as response. Content-Type will be "application/json"
stream :: MonadIO m => StreamingBody -> ActionCtxT ctx m a Source
Use a StreamingBody
to generate a response.
response :: MonadIO m => (Status -> ResponseHeaders -> Response) -> ActionCtxT ctx m a Source
Use a custom Response
generator as response body.
Middleware helpers
middlewarePass :: MonadIO m => ActionCtxT ctx m a Source
If the Spock application is used as a middleware, you can use this to pass request handling to the underlying application. If Spock is not uses as a middleware, or there is no underlying application this will result in 404 error.
modifyVault :: MonadIO m => (Vault -> Vault) -> ActionCtxT ctx m () Source
Modify the vault (useful for sharing data between middleware and app)
queryVault :: MonadIO m => Key a -> ActionCtxT ctx m (Maybe a) Source
Query the vault
Configuration
data SpockCfg conn sess st Source
Spock configuration, use defaultSpockCfg
and change single values if needed
SpockCfg | |
|
defaultSpockCfg :: sess -> PoolOrConn conn -> st -> SpockCfg conn sess st Source
Spock configuration with reasonable defaults
Database
data PoolOrConn a where Source
You can feed Spock with either a connection pool, or instructions on how to build
a connection pool. See ConnBuilder
PCPool :: Pool a -> PoolOrConn a | |
PCConn :: ConnBuilder a -> PoolOrConn a | |
PCNoDatabase :: PoolOrConn () |
data ConnBuilder a Source
The ConnBuilder instructs Spock how to create or close a database connection.
ConnBuilder | |
|
If Spock should take care of connection pooling, you need to configure it depending on what you need.
Accessing Database and State
runQuery :: (SpockConn m -> IO a) -> m a Source
Give you access to a database connectin from the connection pool. The connection is released back to the pool once the function terminates.
getState :: m (SpockState m) Source
Read the application's state. If you wish to have mutable state, you could
use a TVar
from the STM packge.
Basic HTTP-Auth
requireBasicAuth :: MonadIO m => Text -> (Text -> Text -> ActionCtxT ctx m b) -> (b -> ActionCtxT ctx m a) -> ActionCtxT ctx m a Source
Convenience Basic authentification provide a title for the prompt and a function to validate user and password. Usage example:
get ("auth" <//> var <//> var) $ \user pass -> let checker user' pass' = unless (user == user' && pass == pass') $ do setStatus status401 text "err" in requireBasicAuth "Foo" checker $ \() -> text "ok"
withBasicAuthData :: MonadIO m => (Maybe (Text, Text) -> ActionCtxT ctx m a) -> ActionCtxT ctx m a Source
"Lower level" basic authentification handeling. Does not set any headers that will promt browser users, only looks for an Authorization header in the request and breaks it into username and passwort component if present
Sessions
defaultSessionCfg :: a -> SessionCfg a Source
Session configuration with reasonable defaults
data SessionCfg a Source
Configuration for the session manager
SessionCfg | |
|
defaultSessionHooks :: SessionHooks a Source
NOP session hooks
data SessionHooks a Source
Hook into the session manager to trigger custom behavior
SessionHooks | |
|
data SessionPersistCfg a Source
readShowSessionPersist :: (Read a, Show a) => FilePath -> SessionPersistCfg a Source
Simple session persisting configuration. DO NOT USE IN PRODUCTION
sessionRegenerateId :: SpockActionCtx ctx conn sess st () Source
Regenerate the users sessionId. This preserves all stored data. Call this prior to logging in a user to prevent session fixation attacks.
getSessionId :: SpockActionCtx ctx conn sess st SessionId Source
Get the current users sessionId. Note that this ID should only be shown to it's owner as otherwise sessions can be hijacked.
readSession :: SpockActionCtx ctx conn sess st sess Source
Read the stored session
writeSession :: sess -> SpockActionCtx ctx conn sess st () Source
Write to the current session. Note that all data is stored on the server. The user only reciedes a sessionId to be identified.
modifySession :: (sess -> sess) -> SpockActionCtx ctx conn sess st () Source
Modify the stored session
modifySession' :: (sess -> (sess, a)) -> SpockActionCtx ctx conn sess st a Source
Modify the stored session and return a value
modifyReadSession :: (sess -> sess) -> SpockActionCtx ctx conn sess st sess Source
Modify the stored session and return the new value after modification
mapAllSessions :: (sess -> STM sess) -> SpockActionCtx ctx conn sess st () Source
Apply a transformation to all sessions. Be careful with this, as this may cause many STM transaction retries.
clearAllSessions :: SpockActionCtx ctx conn sess st () Source
Globally delete all existing sessions. This is useful for example if you want to require all users to relogin
Internals for extending Spock
getSpockHeart :: MonadTrans t => t (WebStateM conn sess st) (WebState conn sess st) Source
Read the heart of Spock. This is useful if you want to construct your own monads that work with runQuery and getState using "runSpockIO"
runSpockIO :: WebState conn sess st -> WebStateM conn sess st a -> IO a Source
Run an action inside of Spocks core monad. This allows you to use runQuery and getState