module Network.HTTP.RedHandler.FileUtils where
import System.Posix (FileStatus, getFileStatus, fileSize, fileAccess, modificationTime, isDirectory, isRegularFile)
import Control.Exception as Exception (tryJust, ioErrors)
import Foreign.C.Error (getErrno, eNOENT)
sendFileResponse :: String -> IO (Maybe (Integer, String))
sendFileResponse path = do
check <- findRealFilename path
case check of {
Nothing -> return Nothing;
Just (filename,stat) -> do
access <- fileAccess filename True False False
case access of {
False -> return Nothing;
True -> do
let size = toInteger (fileSize stat)
return (Just (size, filename) )
}}
statFile :: String -> IO (Maybe FileStatus)
statFile filename = do
maybe_stat <- tryJust ioErrors (getFileStatus filename)
case maybe_stat of
Left e -> do
errno <- getErrno
if errno == eNOENT
then return Nothing
else ioError e
Right stat ->
return (Just stat)
findRealFilename :: String -> IO (Maybe (String,FileStatus))
findRealFilename filename = do
stat <- statFile filename
case stat of
Nothing -> return Nothing
Just stat
| isDirectory stat -> do
let index_filename = filename ++ '/': "index.html"
stat <- statFile index_filename
case stat of
Nothing -> return Nothing
Just stat -> return (Just (index_filename,stat))
| isRegularFile stat ->
return (Just (filename,stat))
| otherwise ->
return Nothing