Hagia
log in
morj / dwierz
overview
files
history
wiki
Viewing at
module Static
( serveStatic
) where

import qualified Network.Wai as Wai

import Data.Text (Text)
import Data.MonoTraversable (ointercalate, onull)
import Data.Text (unpack)
import Data.Sequences (isSuffixOf)
import Data.Text.Encoding (encodeUtf8)

serveStatic :: FilePath -> [Text] -> (Wai.Response -> IO Wai.ResponseReceived) -> IO Wai.ResponseReceived
serveStatic staticRoot pathInfo respond = do
let path = renderPath pathInfo
let contentType = guessMime path
let fullPath = staticRoot <> "/" <> unpack path
respond $ Wai.responseFile (toEnum 200) [("content-type", encodeUtf8 contentType)] fullPath Nothing

renderPath :: [Text] -> Text
renderPath =
ointercalate "/"
. filter (not . onull)
. filter (/= "..") -- better choice would be to collapse with previous, but
-- ehh. User-agents usually expand it themselves.
. filter (/= ".")

guessMime :: Text -> Text
guessMime fullPath
| ".apng" `isSuffixOf` fullPath = "image/apng"
| ".avif" `isSuffixOf` fullPath = "image/avif"
| ".gif" `isSuffixOf` fullPath = "image/gif"
| ".jpg" `isSuffixOf` fullPath = "image/jpeg"
| ".jpeg" `isSuffixOf` fullPath = "image/jpeg"
| ".png" `isSuffixOf` fullPath = "image/png"
| ".svg" `isSuffixOf` fullPath = "image/svg+xml"
| ".webp" `isSuffixOf` fullPath = "image/webp"
| otherwise = "image/png" -- ehh UA'll figure it out