hyperbole-0.7.0: src/Web/Hyperbole/Server/Uploads.hs
module Web.Hyperbole.Server.Uploads where
import Control.Monad.Trans.Resource (InternalState, closeInternalState, createInternalState)
import Data.String.Conversions (cs)
import Effectful
import Effectful.Exception (bracket)
import Network.Wai qualified as Wai
import Network.Wai.Parse (File, FileInfo (..), ParseRequestBodyOptions)
import Network.Wai.Parse qualified as Wai
import Web.Hyperbole.Types.Request (FileParam, Param, UploadedFile (..))
withPostBody :: (IOE :> es) => ParseRequestBodyOptions -> Wai.Request -> ([Param] -> [FileParam] -> Eff es a) -> Eff es a
withPostBody options req action = withUploadState $ \state -> do
(params, files) <- acceptFileUploads state
action params $ fmap fileParam files
where
withUploadState :: (IOE :> es) => (InternalState -> Eff es a) -> Eff es a
withUploadState = bracket createInternalState closeInternalState
acceptFileUploads :: (IOE :> es) => InternalState -> Eff es ([Param], [File FilePath])
acceptFileUploads state = do
liftIO $ Wai.parseRequestBodyEx options (Wai.tempFileBackEnd state) req
fileParam :: Wai.File FilePath -> FileParam
fileParam (key, f) = (key, fileInfo f)
fileInfo :: Wai.FileInfo FilePath -> UploadedFile
fileInfo FileInfo{fileName, fileContentType, fileContent} =
UploadedFile
{ filePath = fileContent
, fileName = cs fileName
, contentType = cs fileContentType
}