{-# LANGUAGE OverloadedStrings, RankNTypes #-} module Web.Scotty.Action ( addHeader , body , file , files , header , headers , html , json , jsonData , next , param , params , raise , raw , readEither , redirect , request , rescue , setHeader , status , stream , source -- Deprecated , 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 import qualified Data.Conduit.List as CL 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 ["