module Control.Monad.Apiary.Filter (
method, stdMethod
, Control.Monad.Apiary.Filter.httpVersion
, http09, http10, http11
, root
, capture
, Capture.path
, Capture.endPath
, Capture.fetch
, QueryKey(..), (??)
, query
, (=:), (=!:), (=?:), (?:), (=*:), (=+:)
, hasQuery
, hasHeader
, eqHeader
, headers
, header
, header'
, ssl
, module Network.HTTP.Types
, module Control.Monad.Apiary.Filter.Internal.Strategy
) where
import Control.Monad
import Control.Monad.Trans
import Network.Wai as Wai
import qualified Network.HTTP.Types as HT
import Network.HTTP.Types (StdMethod(..))
import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as SC
import Data.Monoid
import Data.Proxy
import Data.String
import Data.Reflection
import Text.Blaze.Html
import Data.Apiary.SList
import Data.Apiary.Param
import Data.Apiary.Document
import Control.Monad.Apiary.Action.Internal
import Control.Monad.Apiary.Filter.Internal
import qualified Control.Monad.Apiary.Filter.Internal.Strategy as Strategy
import Control.Monad.Apiary.Filter.Internal.Strategy (pFirst, pOne, pOption, pCheck, pMany, pSome)
import qualified Control.Monad.Apiary.Filter.Internal.Capture as Capture
import Control.Monad.Apiary.Filter.Internal.Capture.TH
import Control.Monad.Apiary.Internal
method :: Monad n => HT.Method -> ApiaryT c n m a -> ApiaryT c n m a
method m = function_ (DocMethod m) ((m ==) . requestMethod)
stdMethod :: Monad n => StdMethod -> ApiaryT c n m a -> ApiaryT c n m a
stdMethod = method . HT.renderStdMethod
ssl :: Monad n => ApiaryT c n m a -> ApiaryT c n m a
ssl = function_ (DocPrecondition "SSL required") isSecure
httpVersion :: Monad n => HT.HttpVersion -> Html -> ApiaryT c n m b -> ApiaryT c n m b
httpVersion v h = function_ (DocPrecondition h) $ (v ==) . Wai.httpVersion
http09 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http09 = Control.Monad.Apiary.Filter.httpVersion HT.http09 "HTTP/0.9 only"
http10 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http10 = Control.Monad.Apiary.Filter.httpVersion HT.http10 "HTTP/1.0 only"
http11 :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
http11 = Control.Monad.Apiary.Filter.httpVersion HT.http11 "HTTP/1.1 only"
root :: Monad n => ApiaryT c n m b -> ApiaryT c n m b
root m = do
rs <- rootPattern `liftM` apiaryConfig
function_ DocRoot (\r -> rawPathInfo r `elem` rs) m
data QueryKey = QueryKey
{ queryKey :: S.ByteString
, queryDesc :: Maybe Html
}
instance IsString QueryKey where
fromString s = case break (== ':') s of
(k, []) -> QueryKey (SC.pack k) Nothing
(k, d) -> QueryKey (SC.pack k) (Just . toHtml $ tail d)
(??) :: QueryKey -> Html -> QueryKey
QueryKey k _ ?? d = QueryKey k (Just d)
query :: forall a as w n m b proxy.
(ReqParam a, Strategy.Strategy w, MonadIO n)
=> QueryKey
-> proxy (w a)
-> ApiaryT (Strategy.SNext w as a) n m b
-> ApiaryT as n m b
query QueryKey{..} p =
focus doc $ \l -> do
r <- getRequest
(q,f) <- getRequestBody
maybe mzero return $
Strategy.readStrategy id ((queryKey ==) . fst) p
(reqParams (Proxy :: Proxy a) r q f) l
where
doc = case queryDesc of
Nothing -> id
Just h -> DocQuery queryKey (Strategy.strategyRep (Proxy :: Proxy w)) (reqParamRep (Proxy :: Proxy a)) h
(=:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as a) n m b -> ApiaryT as n m b
k =: t = query k (pFirst t)
(=!:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as a) n m b -> ApiaryT as n m b
k =!: t = query k (pOne t)
(=?:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as (Maybe a)) n m b -> ApiaryT as n m b
k =?: t = query k (pOption t)
(?:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT as n m b -> ApiaryT as n m b
k ?: t = query k (pCheck t)
(=*:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as [a]) n m b -> ApiaryT as n m b
k =*: t = query k (pMany t)
(=+:) :: (MonadIO n, ReqParam a) => QueryKey -> proxy a
-> ApiaryT (Snoc as [a]) n m b -> ApiaryT as n m b
k =+: t = query k (pSome t)
hasQuery :: (MonadIO n) => QueryKey -> ApiaryT c n m a -> ApiaryT c n m a
hasQuery q = query q (Proxy :: Proxy (Strategy.Check ()))
hasHeader :: Monad n => HT.HeaderName -> ApiaryT as n m b -> ApiaryT as n m b
hasHeader n = header' pCheck ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
eqHeader :: Monad n
=> HT.HeaderName
-> S.ByteString
-> ApiaryT as n m b
-> ApiaryT as n m b
eqHeader k v = header' pCheck (\(k',v') -> k == k' && v == v') . Just $
mconcat [toHtml $ show k, " header == ", toHtml $ show v]
header :: Monad n => HT.HeaderName
-> ApiaryT (Snoc as S.ByteString) n m b -> ApiaryT as n m b
header n = header' pFirst ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
headers :: Monad n => HT.HeaderName
-> ApiaryT (Snoc as [S.ByteString]) n m b -> ApiaryT as n m b
headers n = header' limit100 ((n ==) . fst) . Just $
toHtml (show n) <> " header requred"
where
limit100 :: Proxy x -> Proxy (Strategy.LimitSome $(int 100) x)
limit100 _ = Proxy
header' :: (Strategy.Strategy w, Monad n)
=> (forall x. Proxy x -> Proxy (w x))
-> (HT.Header -> Bool)
-> Maybe Html
-> ApiaryT (Strategy.SNext w as S.ByteString) n m b
-> ApiaryT as n m b
header' pf kf d = function pc $ \l r ->
Strategy.readStrategy Just kf (pf pByteString) (requestHeaders r) l
where
pc = maybe id DocPrecondition d