{-# LANGUAGE NoRebindableSyntax #-} {-# OPTIONS_GHC -Wno-type-defaults #-} module Literate.Web.Live.HTTP where -- import Network.Wai.Middleware.Static qualified as Static import Control.Concurrent.STM (STM) import Control.Concurrent.STM qualified as STM import Control.Monad.Classes qualified as MC import Data.ByteString.Lazy qualified as BSL import Data.Function (($)) import Data.Map.Strict qualified as Map import Data.Maybe (Maybe (..), fromMaybe) import Data.Semigroup (Semigroup (..)) import Data.Text qualified as Text import Data.Text.Lazy qualified as TextL import Data.Text.Lazy.IO qualified as TextL import Literate.Web qualified as Web import Network.HTTP.Types qualified as H import Network.Wai qualified as Wai import System.IO (IO) import System.IO qualified as Sys import Literate.Web.Live.Asset import Literate.Web.Live.Common httpApp :: m ~ IO => STM model -> (model -> m (Map.Map Web.OutputPath (m BSL.ByteString))) -> -- The shim to include in every HTML response Maybe BSL.ByteString -> Wai.Application httpApp modelSTM siteMap mShim req res = do let shim = fromMaybe "" mShim let path = Text.intercalate "/" $ Wai.pathInfo req model <- STM.atomically modelSTM TextL.hPutStrLn Sys.stderr $ "httpApp: GET " <> TextL.fromStrict path site <- siteMap model Sys.hPrint Sys.stderr ( ["httpApp"] :: [TextL.Text] , ("path", decodeOutputPath path) , ("site" :: TextL.Text, (Map.keys site)) ) case Map.lookup (decodeOutputPath path) site of Nothing -> do let s = liveErrorHtmlResponse decodeRouteNothingMsg <> shim res $ Wai.responseLBS H.status404 [(H.hContentType, "text/html")] s Just contentIO -> do content <- MC.exec @IO contentIO res $ Wai.responseLBS H.status200 [(H.hContentType, "text/html")] content {- case mr of Left err -> do logErrorNS "App" $ badRouteEncodingMsg err let s = liveErrorHtmlResponse (badRouteEncodingMsg err) <> shim liftIO $ res $ Wai.responseLBS H.status500 [(H.hContentType, "text/html")] s Right Nothing -> do let s = liveErrorHtmlResponse decodeRouteNothingMsg <> shim liftIO $ res $ 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 $ res $ Wai.responseFile H.status200 [(H.hContentType, mimeType)] staticPath Nothing AssetGenerated Html html -> do let s = html <> toLazy wsClientHtml <> shim liftIO $ res $ Wai.responseLBS H.status200 [(H.hContentType, "text/html")] s AssetGenerated Other s -> do let mimeType = Static.getMimeType $ review (fromPrism_ $ routePrism val) r liftIO $ res $ Wai.responseLBS H.status200 [(H.hContentType, mimeType)] s -}