{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Rib.Server
(
serve
, getHTMLFileUrl
)
where
import Prelude hiding (init, last)
import Control.Monad (guard)
import Data.List (isSuffixOf)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import Safe (initMay, lastMay)
import Development.Shake.FilePath
import Network.Wai.Application.Static (defaultFileServerSettings, ssListing, ssLookupFile, staticApp)
import qualified Network.Wai.Handler.Warp as Warp
import WaiAppStatic.Types (LookupResult (..), Pieces, StaticSettings, fromPiece, unsafeToPiece)
staticSiteServerSettings :: FilePath -> StaticSettings
staticSiteServerSettings root = settings
{ ssLookupFile = lookupFileForgivingHtmlExt
, ssListing = Nothing
}
where
settings = defaultFileServerSettings root
lookupFileForgivingHtmlExt :: Pieces -> IO LookupResult
lookupFileForgivingHtmlExt pieces = ssLookupFile settings pieces >>= \case
LRNotFound -> ssLookupFile settings (addHtmlExt pieces)
x -> pure x
addHtmlExt :: Pieces -> Pieces
addHtmlExt xs = fromMaybe xs $ do
init <- fmap fromPiece <$> initMay xs
last <- fromPiece <$> lastMay xs
guard $ not $ ".html" `isSuffixOf` T.unpack last
pure $ fmap unsafeToPiece $ init <> [last <> ".html"]
getHTMLFileUrl
:: FilePath
-> Text
getHTMLFileUrl = T.pack . ("/" ++) . dropExtension
serve
:: Int
-> FilePath
-> IO ()
serve port path = do
putStrLn $ "[Rib] Serving at http://localhost:" <> show port
Warp.run port $ staticApp $ staticSiteServerSettings path