{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} module Web.Apiary.Cookie ( -- * setter setCookie , deleteCookie -- * getter , getCookies -- * filter , cookie , cookie' -- * Reexport -- | SetCookie(..) , module Web.Cookie ) where import Control.Applicative((<$>)) import Data.Apiary.Routing.Dict(type ()) import Blaze.ByteString.Builder(toByteString) import Text.Blaze.Html(toHtml) import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as SC cond :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b cond p t f a = if p a then t a else f a {-# INLINE cond #-} -- | cookie filter. since 0.5.1.0. -- -- can use like 'query' function. -- -- example: -- -- @ -- cookie [key|foo|] (pFirst pInt) -- get first Int parameter from foo. -- cookie [key|bar|] (pOption pDouble) -- get first Double parameter from bar, allows no cookie. -- cookie [key|baz|] (pMany (pMaybe pString)) -- get zero or more baz cookies. allows cookie decrypt failure. -- cookie [key|baz|] (Proxy :: Proxy (LimitSome [int|100|] ByteString)) -- get raw cookies up to 100 entries. -- @ cookie :: (Strategy w, Monad actM, k proxy k -> w S.ByteString -> Filter exts actM m prms (SNext w k S.ByteString prms) cookie k p = function (DocPrecondition $ toHtml (symbolVal k) <> " cookie required") $ \l r -> strategy p k (map (Just . snd) . filter ((SC.pack (symbolVal k) ==) . fst) $ cookie' r) l cookie' :: Wai.Request -> [(S.ByteString, S.ByteString)] cookie' = concatMap Cookie.parseCookies . mapMaybe (cond (("cookie" ==) . fst) (Just . snd) (const Nothing)) . Wai.requestHeaders getCookies :: Monad m => ActionT exts prms m [(S.ByteString, S.ByteString)] getCookies = concatMap (Cookie.parseCookies . snd) . filter (("cookie" ==) . fst) <$> getHeaders -- | delete cookie. since 0.6.1.0. deleteCookie :: Monad m => S.ByteString -> ActionT exts prms m () deleteCookie k = setCookie Cookie.def { setCookieName = k , setCookieExpires = Just $ UTCTime (ModifiedJulianDay 0) 0 , setCookieMaxAge = Just 0 } -- | set raw cookie header. setCookie :: Monad m => SetCookie -> ActionT exts prms m () setCookie = addHeader "set-cookie" . toByteString . Cookie.renderSetCookie