{-# LANGUAGE FlexibleContexts #-}-- | This module provides four classes and some related functions-- which provide 'ServerPartT' with much of its web-centric behavior.---- 1. 'ServerMonad' provides access to the HTTP 'Request'---- 2. 'FilterMonad' provides the ability to apply filters and transformations to a 'Response'---- 3. 'WebMonad' provides a way to escape a computation early and return a 'Response'---- 4. 'HasRqData' which provides access to the decoded QUERY_STRING and request body/form datamoduleHappstack.Server.Monads(-- * ServerPartTServerPartT,ServerPart-- * Happstack class,Happstack-- * ServerMonad,ServerMonad(..),mapServerPartT,mapServerPartT',UnWebT,filterFun-- * FilterMonad,FilterMonad(..),ignoreFilters,addHeaderM,getHeaderM,setHeaderM,neverExpires-- * WebMonad,WebMonad(..),escape,escape'-- * MonadPlus helpers,require,requireM)whereimportControl.Applicative(Alternative,Applicative)importControl.Monad(MonadPlus(mzero))importControl.Monad.Trans(MonadIO(..),MonadTrans(lift))importControl.Monad.Reader(ReaderT)importControl.Monad.Writer(WriterT)importControl.Monad.State(StateT)importControl.Monad.RWS(RWST)importqualifiedData.ByteString.Char8asBimportData.Monoid(Monoid)importHappstack.Server.Internal.MonadsimportHappstack.Server.Types(Response,addHeader,getHeader,setHeader)importHappstack.Server.RqData(HasRqData)-- | A class alias for all the classes a standard server monad (such as 'ServerPartT') is expected to have instances for. This allows you to keep your type signatures shorter and easier to understand.class(ServerMonadm,WebMonadResponsem,FilterMonadResponsem,MonadIOm,MonadPlusm,HasRqDatam,Monadm,Functorm,Applicativem,Alternativem)=>Happstackminstance(Functorm,Monadm,MonadPlusm,MonadIOm)=>Happstack(ServerPartTm)instance(Happstackm)=>Happstack(StateTsm)instance(Happstackm)=>Happstack(ReaderTrm)instance(Happstackm,Monoidw)=>Happstack(WriterTwm)instance(Happstackm,Monoidw)=>Happstack(RWSTrwsm)-- | Get a header out of the request.getHeaderM::(ServerMonadm)=>String->m(MaybeB.ByteString)getHeaderMa=askRq>>=return.(getHeadera)-- | Add headers into the response. This method does not overwrite-- any existing header of the same name, hence the name 'addHeaderM'.-- If you want to replace a header use 'setHeaderM'.addHeaderM::(FilterMonadResponsem)=>String->String->m()addHeaderMav=composeFilter$\res->addHeaderavres-- | Set a header into the response. This will replace an existing-- header of the same name. Use 'addHeaderM' if you want to add more-- than one header of the same name.setHeaderM::(FilterMonadResponsem)=>String->String->m()setHeaderMav=composeFilter$\res->setHeaderavres-- | Set a far-future Expires header. Useful for static resources. If the-- browser has the resource cached, no extra request is spent.neverExpires::(FilterMonadResponsem)=>m()neverExpires=setHeaderM"Expires""Mon, 31 Dec 2035 12:00:00 GMT"-- | Run an 'IO' action and, if it returns 'Just', pass it to the-- second argument.require::(MonadIOm,MonadPlusm)=>IO(Maybea)->(a->mr)->mrrequirefnhandle=dombVal<-liftIOfncasembValofNothing->mzeroJusta->handlea-- | A variant of require that can run in any monad, not just 'IO'.requireM::(MonadTranst,Monadm,MonadPlus(tm))=>m(Maybea)->(a->tmr)->tmrrequireMfnhandle=dombVal<-liftfncasembValofNothing->mzeroJusta->handlea