-- | -- Module: WebWire.Tools -- Copyright: (c) 2011 Ertugrul Soeylemez -- License: BSD3 -- Maintainer: Ertugrul Soeylemez -- -- Various webwire tools. module WebWire.Tools ( -- * Requests getQueryParam, -- * Responses -- ** Headers addHeader, -- ** Cookies getCookie, setCookie, setCookieSimple, -- ** Failure notFound ) where import qualified Data.Map as M import Blaze.ByteString.Builder import Control.Arrow import Control.Exception import Control.Monad.Trans.State import Data.ByteString as B import Data.CaseInsensitive import Data.Time.Clock import FRP.NetWire import Network.HTTP.Types import Web.Cookie import WebWire.Types -- | Add an additional header to the response. addHeader :: WebWire site (CI Ascii, Ascii) () addHeader = proc h -> execute -< modify $ \cfg -> let h' = wcSetHeaders cfg in cfg { wcSetHeaders = h : h' } -- | Retrieves the given cookie from the request. Inhibits, if the -- cookie doesn't exist. getCookie :: WebWire site ByteString ByteString getCookie = proc name -> do cookies <- execute -< gets wcCookies case M.lookup name cookies of Just value -> identity -< value Nothing -> notFound -< () -- | Retrieve the given query parameter. Inhibits with 404, if the -- parameter does not exist. getQueryParam :: WebWire site ByteString ByteString getQueryParam = proc name -> do params <- execute -< gets wcQueryParams case M.lookup name params of Nothing -> notFound -< () Just value -> identity -< value -- | Inhibits with a 404 error. notFound :: WebWire site a b notFound = constant (toException (WebException statusNotFound)) >>> inhibit -- | Sets the given cookie. setCookie :: WebWire site SetCookie () setCookie = proc cookie -> execute -< modify $ \cfg -> let cs' = wcSetCookies cfg cStr = toByteString (renderSetCookie cookie) in cfg { wcSetCookies = M.insert (setCookieName cookie) cStr cs' } -- | Sets the given cookie for the root path of the current domain with -- the given validity duration. If no duration is given, it becomes a -- session cookie. setCookieSimple :: WebWire site (ByteString, ByteString, Maybe NominalDiffTime) () setCookieSimple = proc (name, value, mTime) -> do let cookie = SetCookie { setCookieName = name, setCookieValue = value, setCookiePath = Just "/", setCookieExpires = Nothing, setCookieDomain = Nothing, setCookieHttpOnly = False } case mTime of Nothing -> setCookie -< cookie Just dt -> do now <- execute -< liftIO getCurrentTime setCookie -< cookie { setCookieExpires = Just (addUTCTime dt now) }