{-# LANGUAGE OverloadedStrings, RankNTypes #-} module Web.Scotty.Action ( addHeader , body , file , files , html , json , jsonData , next , param , params , raise , raw , readEither , redirect , reqHeader , request , rescue , setHeader , source , status , text , Param , Parsable(..) -- private to Scotty , runAction ) where import Blaze.ByteString.Builder (Builder, fromLazyByteString) import Control.Monad.Error import Control.Monad.Reader import qualified Control.Monad.State as MS import qualified Data.Aeson as A import qualified Data.ByteString.Char8 as B import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.CaseInsensitive as CI import Data.Conduit (Flush, Source) import Data.Default (def) import Data.Monoid (mconcat) import qualified Data.Text as ST import qualified Data.Text.Lazy as T import Data.Text.Lazy.Encoding (encodeUtf8) import Network.HTTP.Types import Network.Wai import Web.Scotty.Types import Web.Scotty.Util -- Nothing indicates route failed (due to Next) and pattern matching should continue. -- Just indicates a successful response. runAction :: (ScottyError e, Monad m) => ErrorHandler e m -> ActionEnv -> ActionT e m () -> m (Maybe Response) runAction h env action = do (e,r) <- flip MS.runStateT def $ flip runReaderT env $ runErrorT $ runAM $ action `catchError` (defH h) return $ either (const Nothing) (const $ Just $ mkResponse r) e -- | Default error handler for all actions. defH :: (ScottyError e, Monad m) => ErrorHandler e m -> ActionError e -> ActionT e m () defH _ (Redirect url) = do status status302 setHeader "Location" url defH Nothing (ActionError e) = do status status500 html $ mconcat ["