ema-0.12.0.0: src/Ema/Server/HTTP.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
module Ema.Server.HTTP where
import Control.Monad.Logger
import Data.LVar (LVar)
import Data.LVar qualified as LVar
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import Ema.Asset (
Asset (AssetGenerated, AssetStatic),
Format (Html, Other),
)
import Ema.Route.Class (IsRoute (RouteModel, routePrism))
import Ema.Route.Prism (
fromPrism_,
)
import Ema.Server.Common
import Ema.Site (EmaStaticSite)
import Network.HTTP.Types qualified as H
import Network.Wai qualified as Wai
import Network.Wai.Middleware.Static qualified as Static
import Optics.Core (review)
httpApp ::
forall r.
(Eq r, Show r, IsRoute r, EmaStaticSite r) =>
(Loc -> LogSource -> LogLevel -> LogStr -> IO ()) ->
LVar (RouteModel r) ->
-- The shim to include in every HTML response
Maybe LByteString ->
Wai.Application
httpApp logger model mShim req f = flip runLoggingT logger $ do
let shim = fromMaybe "" mShim
val <- LVar.get model
let pathInfo = Wai.pathInfo req
path = T.intercalate "/" pathInfo
mr = decodeUrlRoute @r val path
logInfoNS "ema.http" $ "GET " <> path <> " as " <> show mr
case mr of
Left err -> do
logErrorNS "App" $ badRouteEncodingMsg err
let s = emaErrorHtmlResponse (badRouteEncodingMsg err) <> shim
liftIO $ f $ Wai.responseLBS H.status500 [(H.hContentType, "text/html")] s
Right Nothing -> do
let s = emaErrorHtmlResponse decodeRouteNothingMsg <> shim
liftIO $ f $ Wai.responseLBS H.status404 [(H.hContentType, "text/html")] s
Right (Just r) -> do
renderCatchingErrors val r >>= \case
AssetStatic staticPath -> do
let mimeType = Static.getMimeType staticPath
liftIO $ f $ Wai.responseFile H.status200 [(H.hContentType, mimeType)] staticPath Nothing
AssetGenerated Html html -> do
let s = html <> toLazy wsClientHtml <> shim
liftIO $ f $ Wai.responseLBS H.status200 [(H.hContentType, "text/html")] s
AssetGenerated Other s -> do
let mimeType = Static.getMimeType $ review (fromPrism_ $ routePrism val) r
liftIO $ f $ Wai.responseLBS H.status200 [(H.hContentType, mimeType)] s