{-# LANGUAGE FlexibleContexts, TypeOperators #-} module Network.Salvia.Handler.Rewrite ( hLocalRequest , hRewrite , hRewritePath , hRewriteHost , hRewriteExt , hWithDir , hWithoutDir ) where import Control.Applicative import Control.Category import Data.List import Data.Record.Label import Network.Protocol.Http import Network.Protocol.Uri import Network.Salvia.Interface hiding (host) import Prelude hiding ((.), id) {- | Run a handler in a local environment in which the `HTTP' `Request' has been modified. -} hLocalRequest :: HttpM Request m => (Http Request :-> b) -> (b -> b) -> m a -> m a hLocalRequest p f m = do u <- request (getM p) <* request (modM p f) m <* request (p =: u) {- | Run an handler in a modified context in which the request `Uri` has been changed by the specified modifier function. After the handler completes the `Uri` remains untouched. -} hRewrite :: HttpM Request m => (Uri -> Uri) -> m a -> m a hRewrite = hLocalRequest asUri {- | Run handler in a context with a modified host. -} hRewriteHost :: HttpM Request m => (String -> String) -> m a -> m a hRewriteHost = hLocalRequest (host . asUri) {- | Run handler in a context with a modified path. -} hRewritePath :: HttpM Request m => (FilePath -> FilePath) -> m a -> m a hRewritePath = hLocalRequest (path . asUri) {- | Run handler in a context with a modified file extension. -} hRewriteExt :: HttpM Request m => (Maybe String -> Maybe String) -> m a -> m a hRewriteExt = hLocalRequest (extension . path . asUri) {- | Run handler in a context with a modified path. The specified prefix will be prepended to the path. -} hWithDir :: HttpM Request m => String -> m a -> m a hWithDir d = hRewritePath (d++) {- | Run handler in a context with a modified path. The specified prefix will be stripped from the path. -} hWithoutDir :: HttpM Request m => String -> m a -> m a hWithoutDir d = hRewritePath $ \p -> if d `isPrefixOf` p then drop (length d) p else p