{-# language OverloadedStrings #-} {-# language FlexibleContexts #-} {-# language ConstraintKinds #-} {-# language ViewPatterns #-} module RubiX.RubixRequest ( getPath , getPathInfo , getMethod , getQueryString , getQueries , getQueriesMulti , getQuery , getQueryMulti , getHeader , getHeaderMulti , getHeaders , getBody , checkSecure , waiRequest , matchPaths ) where import Control.Monad.Reader import Data.Maybe import Data.Bifunctor import qualified Data.Text as DT import qualified Data.Map as DM import qualified Data.CaseInsensitive as DCI import Text.Regex.PCRE import qualified Network.Wai as NW import RubiX.Utils import RubiX.Types type ReqReader b = MonadReader ReqContext b fromReq :: ReqReader b => (NW.Request -> a) -> b a fromReq getter = asks (getter . request) -- Gets the headers of the request getHeader :: ReqReader b => DT.Text -> b (Maybe DT.Text) getHeader key = listToMaybe <$> getHeaderMulti key -- Gets the headers of the request getHeaderMulti :: ReqReader b => DT.Text -> b [DT.Text] getHeaderMulti key = fromMaybe [] . DM.lookup (DCI.mk key) <$> getHeaders -- Gets the headers of the request getHeaders :: ReqReader b => b HeaderMap getHeaders = convertHeaders <$> fromReq NW.requestHeaders -- Gets path and returns the full path of the current request getPath :: ReqReader b => b DT.Text getPath = fromByteString <$> fromReq NW.rawPathInfo -- Gets the HTTP method of the current request getMethod :: ReqReader b => b DT.Text getMethod = fromByteString <$> fromReq NW.requestMethod -- Gets query string and returns the full path of the current request getQueryString :: ReqReader b => b DT.Text getQueryString = fromByteString <$> fromReq NW.rawQueryString -- Gets full body of the request getBody :: ReqReader b => b DT.Text getBody = asks requestBody -- Calls through to 'Wai.isSecure' checkSecure :: ReqReader b => b Bool checkSecure = fromReq NW.isSecure -- Returns the path's individual '/' separated chunks. getPathInfo :: ReqReader b => b [DT.Text] getPathInfo = fromReq NW.pathInfo -- Exposes the underlying 'Wai.Request'. waiRequest :: ReqReader b => b NW.Request waiRequest = asks request -- Gets all key/values from the query string getQueriesMulti :: ReqReader b => b MultiQueryMap getQueriesMulti = convertQueries <$> fromReq NW.queryString -- Get the last set value for each query getQueries :: ReqReader b => b QueryMap getQueries = simpleQuery <$> fromReq NW.queryString -- Gets all values provided for a given query key getQueryMulti :: ReqReader b => DT.Text -> b [DT.Text] getQueryMulti key = fromMaybe [] . DM.lookup key <$> getQueriesMulti -- Get the value for a given query getQuery :: ReqReader b => DT.Text -> b (Maybe DT.Text) getQuery key = DM.lookup key <$> getQueries -- | Determine whether a route matches a pattern matchPaths :: ReqReader b => Pattern -> b Bool matchPaths pattern = checkMatch pattern <$> getPath where checkMatch :: Pattern -> Route -> Bool checkMatch (DT.unpack -> pat) (DT.unpack -> rt) = rt =~ ("^" ++ pat ++ "$")