packages feed

Spock 0.7.3.0 → 0.7.4.0

raw patch · 10 files changed

+95/−125 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Web.Spock.Safe: spockApp :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Application
- Web.Spock.Safe: spockMiddleware :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
- Web.Spock.Simple: spockApp :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Application
- Web.Spock.Simple: spockMiddleware :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
+ Web.Spock.Shared: runSpock :: Port -> IO Middleware -> IO ()
+ Web.Spock.Shared: spockAsApp :: IO Middleware -> IO Application
- Web.Spock.Safe: spock :: Int -> SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO ()
+ Web.Spock.Safe: spock :: SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO Middleware
- Web.Spock.Safe: spockT :: MonadIO m => Port -> (forall a. m a -> IO a) -> SpockT m () -> IO ()
+ Web.Spock.Safe: spockT :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Middleware
- Web.Spock.Simple: spock :: Int -> SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO ()
+ Web.Spock.Simple: spock :: SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO Middleware
- Web.Spock.Simple: spockT :: MonadIO m => Port -> (forall a. m a -> IO a) -> SpockT m () -> IO ()
+ Web.Spock.Simple: spockT :: MonadIO m => (forall a. m a -> IO a) -> SpockT m () -> IO Middleware

Files

Spock.cabal view
@@ -1,5 +1,5 @@ name:                Spock-version:             0.7.3.0+version:             0.7.4.0 synopsis:            Another Haskell web framework for rapid development description:         This toolbox provides everything you need to get a quick start into web hacking with haskell: fast routing, middleware, json, blaze, sessions, cookies, database helper, csrf-protection Homepage:            https://github.com/agrafix/Spock@@ -25,7 +25,6 @@                        Web.Spock.Internal.Util,                        Web.Spock.Internal.Core,                        Web.Spock.Internal.CoreAction,-                       Web.Spock.Internal.Wrapper,                        Web.Spock.Internal.Wire   build-depends:       aeson >= 0.6.2.1 && <0.9,                        base >= 4 && < 5,
src/Web/Spock/Internal/Core.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE TypeFamilies #-} module Web.Spock.Internal.Core     ( SpockAllT+    , spockAll     , spockAllT     , middleware     , hookRoute@@ -13,22 +14,58 @@     ) where +import Web.Spock.Internal.SessionManager+import Web.Spock.Internal.Types import Web.Spock.Internal.Wire  import Control.Monad.Error+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Resource+import Data.Pool import Prelude hiding (head) import Web.Routing.AbstractRouter-import qualified Network.Wai.Handler.Warp as Warp+import qualified Network.Wai as Wai +-- | Run a spock application using the warp server, 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.+spockAll :: forall r conn sess st.+            ( AbstractRouter r+            , RouteAppliedAction r ~ ActionT (WebStateM conn sess st) ()+            )+         => r+         -> SessionCfg sess+         -> PoolOrConn conn+         -> st+         -> SpockAllM r conn sess st ()+         -> IO Wai.Middleware+spockAll regIf sessionCfg poolOrConn initialState defs =+    do sessionMgr <- createSessionManager sessionCfg+       connectionPool <-+           case poolOrConn of+             PCPool p ->+                 return p+             PCConn cb ->+                 let pc = cb_poolConfiguration cb+                 in createPool (cb_createConn cb) (cb_destroyConn cb)+                        (pc_stripes pc) (pc_keepOpenTime pc)+                        (pc_resPerStripe pc)+       let internalState =+               WebState+               { web_dbConn = connectionPool+               , web_sessionMgr = sessionMgr+               , web_state = initialState+               }+       spockAllT regIf (\m -> runResourceT $ runReaderT (runWebStateM m) internalState) $+               do defs+                  middleware (sm_middleware sessionMgr)+ -- | Run a raw spock server on a defined port. If you don't need -- a custom base monad you can just supply 'id' as lift function. spockAllT :: (MonadIO m, AbstractRouter r, RouteAppliedAction r ~ ActionT m ())        => r-       -> Warp.Port        -> (forall a. m a -> IO a)        -> SpockAllT r m ()-       -> IO ()-spockAllT registryIf port liftSpock routeDefs =-    do spockApp <- buildApp registryIf liftSpock routeDefs-       putStrLn $ "Spock is up and running on port " ++ show port-       Warp.run port spockApp+       -> IO Wai.Middleware+spockAllT registryIf liftSpock routeDefs =+    buildMiddleware registryIf liftSpock routeDefs
src/Web/Spock/Internal/Types.hs view
@@ -6,8 +6,8 @@ {-# LANGUAGE ExistentialQuantification #-} module Web.Spock.Internal.Types where -import Web.Spock.Internal.Core import Web.Spock.Internal.CoreAction+import Web.Spock.Internal.Wire  import Control.Applicative import Control.Concurrent.STM
src/Web/Spock/Internal/Wire.hs view
@@ -135,14 +135,10 @@ type SpockAllT r m a =     RegistryT r Wai.Middleware StdMethod m a -buildApp :: forall m r. (MonadIO m, AbstractRouter r, RouteAppliedAction r ~ ActionT m ())-         => r-         -> (forall a. m a -> IO a)-         -> SpockAllT r m ()-         -> IO Wai.Application-buildApp registryIf registryLift spockActions =-    do mw <- buildMiddleware registryIf registryLift spockActions-       return (mw fallbackApp)+middlewareToApp :: Wai.Middleware+                -> Wai.Application+middlewareToApp mw =+    mw fallbackApp     where       fallbackApp :: Wai.Application       fallbackApp _ respond =@@ -152,7 +148,7 @@          => r          -> (forall a. m a -> IO a)          -> SpockAllT r m ()-         -> IO (Wai.Application -> Wai.Application)+         -> IO Wai.Middleware buildMiddleware registryIf registryLift spockActions =     do (_, getMatchingRoutes, middlewares) <-            registryLift $ runRegistry registryIf spockActions
− src/Web/Spock/Internal/Wrapper.hs
@@ -1,50 +0,0 @@-{-# LANGUAGE DoAndIfThenElse #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE KindSignatures #-}-{-# LANGUAGE TypeFamilies #-}-module Web.Spock.Internal.Wrapper where--import Web.Spock.Internal.Core-import Web.Spock.Internal.Wire-import Web.Spock.Internal.SessionManager-import Web.Spock.Internal.Types--import Control.Monad.Trans.Reader-import Control.Monad.Trans.Resource-import Data.Pool-import Web.Routing.AbstractRouter---- | Run a spock application using the warp server, 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.-spockAll :: forall r conn sess st.-            ( AbstractRouter r-            , RouteAppliedAction r ~ ActionT (WebStateM conn sess st) ()-            )-         => r-         -> Int-         -> SessionCfg sess-         -> PoolOrConn conn-         -> st-         -> SpockAllM r conn sess st ()-         -> IO ()-spockAll regIf port sessionCfg poolOrConn initialState defs =-    do sessionMgr <- createSessionManager sessionCfg-       connectionPool <--           case poolOrConn of-             PCPool p ->-                 return p-             PCConn cb ->-                 let pc = cb_poolConfiguration cb-                 in createPool (cb_createConn cb) (cb_destroyConn cb)-                        (pc_stripes pc) (pc_keepOpenTime pc)-                        (pc_resPerStripe pc)-       let internalState =-               WebState-               { web_dbConn = connectionPool-               , web_sessionMgr = sessionMgr-               , web_state = initialState-               }-       spockAllT regIf port (\m -> runResourceT $ runReaderT (runWebStateM m) internalState) $-               do defs-                  middleware (sm_middleware sessionMgr)
src/Web/Spock/Safe.hs view
@@ -11,7 +11,6 @@     ( -- * Spock's core       spock, SpockM, SpockAction     , spockT, SpockT, ActionT-    , spockApp      -- * Defining routes     , Path, root, var, static, (</>)      -- * Rendering routes@@ -22,8 +21,6 @@     , Http.StdMethod (..)       -- * Adding Wai.Middleware     , middleware-      -- * Using Spock as middleware-    , spockMiddleware       -- * Safe actions     , SafeAction (..)     , safeActionPath@@ -35,8 +32,6 @@ import Web.Spock.Shared import Web.Spock.Internal.CoreAction import Web.Spock.Internal.Types-import Web.Spock.Internal.Wrapper-import qualified Web.Spock.Internal.Wire as W import qualified Web.Spock.Internal.Core as C  import Control.Applicative@@ -49,7 +44,6 @@ import qualified Data.Text as T import qualified Network.HTTP.Types as Http import qualified Network.Wai as Wai-import qualified Network.Wai.Handler.Warp as Warp  type SpockM conn sess st a = SpockT (WebStateM conn sess st) a @@ -60,35 +54,26 @@ instance MonadTrans SpockT where     lift = SpockT . lift --- | Run a spock application using the warp server, a given db storageLayer and an initial state.+-- | 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.-spock :: Int -> SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO ()-spock port sessCfg poolOrConn initSt spockAppl =-    spockAll SafeRouter port sessCfg poolOrConn initSt (runSpockT spockAppl')+-- Use @runSpock@ to run the app or @spockAsApp@ to create a @Wai.Application@+spock :: SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO Wai.Middleware+spock sessCfg poolOrConn initSt spockAppl =+    C.spockAll SafeRouter sessCfg poolOrConn initSt (runSpockT spockAppl')     where       spockAppl' =           do hookSafeActions              spockAppl --- | Run a raw spock application with custom underlying monad+-- | Create a raw spock application with custom underlying monad+-- Use @runSpock@ to run the app or @spockAsApp@ to create a @Wai.Application@ spockT :: (MonadIO m)-       => Warp.Port-       -> (forall a. m a -> IO a)+       => (forall a. m a -> IO a)        -> SpockT m ()-       -> IO ()-spockT port liftFun (SpockT app) =-    C.spockAllT SafeRouter port liftFun app---- | Convert a Spock-App to a wai-application-spockApp :: (MonadIO m) => (forall a. m a -> IO a) -> SpockT m () -> IO Wai.Application-spockApp liftFun (SpockT app) =-    W.buildApp SafeRouter liftFun app---- | Convert a Spock-App to a wai-middleware-spockMiddleware :: (MonadIO m) => (forall a. m a -> IO a) -> SpockT m () -> IO Wai.Middleware-spockMiddleware liftFun (SpockT app) =-    W.buildMiddleware SafeRouter liftFun app+       -> IO Wai.Middleware+spockT liftFun (SpockT app) =+    C.spockAllT SafeRouter liftFun app  -- | Specify an action that will be run when the HTTP verb 'GET' and the given route match get :: MonadIO m => Path xs -> HVectElim xs (ActionT m ()) -> SpockT m ()
src/Web/Spock/Shared.hs view
@@ -8,8 +8,10 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE DataKinds #-} module Web.Spock.Shared-    (-- * Handeling requests-      request, header, cookie, body, jsonBody, jsonBody', files, UploadedFile (..)+    (-- * Helpers for running Spock+      runSpock, spockAsApp+     -- * Handeling requests+    , request, header, cookie, body, jsonBody, jsonBody', files, UploadedFile (..)     , params, param, param'      -- * Sending responses     , setStatus, setHeader, redirect, jumpNext, setCookie, setCookie', bytes, lazyBytes@@ -37,6 +39,22 @@ import Web.Spock.Internal.SessionManager import Web.Spock.Internal.Types import Web.Spock.Internal.CoreAction+import Control.Monad+import qualified Web.Spock.Internal.Wire as W+import qualified Network.Wai as Wai+import qualified Network.Wai.Handler.Warp as Warp++-- | Run a Spock application. Basically just a wrapper aroung @Warp.run@.+runSpock :: Warp.Port -> IO Wai.Middleware -> IO ()+runSpock port mw =+    do putStrLn ("Spock is running on port " ++ show port)+       app <- spockAsApp mw+       Warp.run port app++-- | Convert a middleware to an application. All failing requests will+-- result in a 404 page+spockAsApp :: IO Wai.Middleware -> IO Wai.Application+spockAsApp = liftM W.middlewareToApp  -- | Get the current users sessionId. Note that this ID should only be -- shown to it's owner as otherwise sessions can be hijacked.
src/Web/Spock/Simple.hs view
@@ -10,7 +10,6 @@     ( -- * Spock's core       spock, SpockM, SpockAction     , spockT, SpockT, ActionT-    , spockApp      -- * Defining routes     , SpockRoute, (<#>)      -- * Hooking routes@@ -19,8 +18,6 @@     , Http.StdMethod (..)      -- * Adding Wai.Middleware     , middleware-      -- * Using Spock as middleware-    , spockMiddleware       -- * Safe actions     , SafeAction (..)     , safeActionPath@@ -31,8 +28,6 @@ import Web.Spock.Shared import Web.Spock.Internal.CoreAction import Web.Spock.Internal.Types-import Web.Spock.Internal.Wrapper-import qualified Web.Spock.Internal.Wire as W import qualified Web.Spock.Internal.Core as C  import Control.Applicative@@ -45,7 +40,6 @@ import qualified Data.Text as T import qualified Network.HTTP.Types as Http import qualified Network.Wai as Wai-import qualified Network.Wai.Handler.Warp as Warp  type SpockM conn sess st a = SpockT (WebStateM conn sess st) a @@ -60,35 +54,26 @@     = SpockRoute { _unSpockRoute :: T.Text }     deriving (Eq, Ord, Show, Read, IsString) --- | Run a spock application using the warp server, a given db storageLayer and an initial state.+-- | 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.-spock :: Int -> SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO ()-spock port sessCfg poolOrConn initSt spockAppl =-    spockAll TextRouter port sessCfg poolOrConn initSt (runSpockT spockAppl')+-- Use @runSpock@ to run the app or @spockAsApp@ to create a @Wai.Application@+spock :: SessionCfg sess -> PoolOrConn conn -> st -> SpockM conn sess st () -> IO Wai.Middleware+spock sessCfg poolOrConn initSt spockAppl =+    C.spockAll TextRouter sessCfg poolOrConn initSt (runSpockT spockAppl')     where       spockAppl' =           do hookSafeActions              spockAppl --- | Run a raw spock application with custom underlying monad+-- | Create a raw spock application with custom underlying monad+-- Use @runSpock@ to run the app or @spockAsApp@ to create a @Wai.Application@ spockT :: (MonadIO m)-       => Warp.Port-       -> (forall a. m a -> IO a)+       => (forall a. m a -> IO a)        -> SpockT m ()-       -> IO ()-spockT port liftFun (SpockT app) =-    C.spockAllT TextRouter port liftFun app---- | Convert a Spock-App to a wai-application-spockApp :: (MonadIO m) => (forall a. m a -> IO a) -> SpockT m () -> IO Wai.Application-spockApp liftFun (SpockT app) =-    W.buildApp TextRouter liftFun app---- | Convert a Spock-App to a wai-middleware-spockMiddleware :: (MonadIO m) => (forall a. m a -> IO a) -> SpockT m () -> IO Wai.Middleware-spockMiddleware liftFun (SpockT app) =-    W.buildMiddleware TextRouter liftFun app+       -> IO Wai.Middleware+spockT liftFun (SpockT app) =+    C.spockAllT TextRouter liftFun app  -- | Combine two route components safely -- "/foo" <#> "/bar" ===> "/foo/bar"
test/Web/Spock/SafeSpec.hs view
@@ -28,4 +28,4 @@        hookAny GET $ text . T.intercalate "/"  spec :: Spec-spec = describe "SafeRouting" $ frameworkSpec (spockApp id app)+spec = describe "SafeRouting" $ frameworkSpec (spockAsApp $ spockT id app)
test/Web/Spock/SimpleSpec.hs view
@@ -29,4 +29,4 @@        hookAny GET $ text . T.intercalate "/"  spec :: Spec-spec = describe "SimpleRouting" $ frameworkSpec (spockApp id app)+spec = describe "SimpleRouting" $ frameworkSpec (spockAsApp $ spockT id app)