module IHP.Controller.Redirect
( redirectTo
, redirectToPath
, redirectToUrl
, redirectBack
, redirectBackWithFallback
) where
import IHP.Prelude
import qualified Network.Wai.Util
import Network.URI (parseURI)
import IHP.Controller.RequestContext
import IHP.RouterSupport (HasPath (pathTo))
import IHP.FrameworkConfig
import Network.HTTP.Types.Status
import IHP.Controller.Context
import IHP.ControllerSupport
redirectTo :: (?context :: ControllerContext, HasPath action) => action -> IO ()
redirectTo :: forall action.
(?context::ControllerContext, HasPath action) =>
action -> IO ()
redirectTo action
action = (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToPath (action -> Text
forall controller. HasPath controller => controller -> Text
pathTo action
action)
{-# INLINABLE redirectTo #-}
redirectToPath :: (?context :: ControllerContext) => Text -> IO ()
redirectToPath :: (?context::ControllerContext) => Text -> IO ()
redirectToPath Text
path = (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToUrl (?context::ControllerContext
ControllerContext
?context.frameworkConfig.baseUrl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
path)
{-# INLINABLE redirectToPath #-}
redirectToUrl :: (?context :: ControllerContext) => Text -> IO ()
redirectToUrl :: (?context::ControllerContext) => Text -> IO ()
redirectToUrl Text
url = do
let RequestContext { Respond
respond :: Respond
respond :: RequestContext -> Respond
respond } = ?context::ControllerContext
ControllerContext
?context.requestContext
let !parsedUrl :: URI
parsedUrl = URI -> Maybe URI -> URI
forall a. a -> Maybe a -> a
fromMaybe
(Text -> URI
forall a. Text -> a
error (Text
"redirectToPath: Unable to parse url: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
forall a. Show a => a -> Text
show Text
url))
(String -> Maybe URI
parseURI (Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs Text
url))
let !redirectResponse :: Response
redirectResponse = Response -> Maybe Response -> Response
forall a. a -> Maybe a -> a
fromMaybe
(Text -> Response
forall a. Text -> a
error Text
"redirectToPath: Unable to construct redirect response")
(Status -> ResponseHeaders -> URI -> Maybe Response
Network.Wai.Util.redirect Status
status302 [] URI
parsedUrl)
(?context::ControllerContext) => Response -> IO ()
Response -> IO ()
respondAndExit Response
redirectResponse
{-# INLINABLE redirectToUrl #-}
redirectBack :: (?context :: ControllerContext) => IO ()
redirectBack :: (?context::ControllerContext) => IO ()
redirectBack = (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectBackWithFallback Text
"/"
{-# INLINABLE redirectBack #-}
redirectBackWithFallback :: (?context :: ControllerContext) => Text -> IO ()
redirectBackWithFallback :: (?context::ControllerContext) => Text -> IO ()
redirectBackWithFallback Text
fallbackPathOrUrl = do
case (?context::ControllerContext) => ByteString -> Maybe ByteString
ByteString -> Maybe ByteString
getHeader ByteString
"Referer" of
Just ByteString
referer -> case String -> Maybe URI
parseURI (ByteString -> String
forall a b. ConvertibleStrings a b => a -> b
cs ByteString
referer) of
Just URI
uri -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToUrl (URI -> Text
forall a. Show a => a -> Text
tshow URI
uri)
Maybe URI
Nothing -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToPath (ByteString -> Text
forall a b. ConvertibleStrings a b => a -> b
cs ByteString
referer)
Maybe ByteString
Nothing -> case String -> Maybe URI
parseURI (Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs Text
fallbackPathOrUrl) of
Just URI
uri -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToUrl (URI -> Text
forall a. Show a => a -> Text
tshow URI
uri)
Maybe URI
Nothing -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
redirectToPath Text
fallbackPathOrUrl
{-# INLINABLE redirectBackWithFallback #-}