1 module Network.HTTP.Lucu.StaticFile
2 ( staticFile -- FilePath -> ResourceDef
3 , handleStaticFile -- FilePath -> Resource ()
8 import Control.Monad.Trans
9 import qualified Data.ByteString.Lazy.Char8 as B
10 import Data.ByteString.Lazy.Char8 (ByteString)
11 import Network.HTTP.Lucu.Abortion
12 import Network.HTTP.Lucu.Config
13 import Network.HTTP.Lucu.ETag
14 import Network.HTTP.Lucu.MIMEType.Guess
15 import Network.HTTP.Lucu.Resource
16 import Network.HTTP.Lucu.Resource.Tree
17 import Network.HTTP.Lucu.Response
18 import System.Directory
19 import System.Posix.Files
23 staticFile :: FilePath -> ResourceDef
26 resUsesNativeThread = False
28 , resGet = Just $ handleStaticFile path
36 handleStaticFile :: FilePath -> Resource ()
38 = do exist <- liftIO $ fileExist path
40 -- 存在はした。讀めるかどうかは知らない。
41 do readable <- liftIO $ fileAccess path True False False
44 $ abort Forbidden [] Nothing
47 tag <- liftIO $ generateETagFromFile path
48 lastMod <- liftIO $ getModificationTime path
49 foundEntity tag lastMod
53 case guessTypeByFileName (cnfExtToMIMEType conf) path of
55 Just mime -> setContentType mime
58 (liftIO $ B.readFile path) >>= outputBS
64 generateETagFromFile :: FilePath -> IO ETag
65 generateETagFromFile path
66 = do stat <- getFileStatus path
67 let inode = fromEnum $ fileID stat
68 size = fromEnum $ fileSize stat
69 lastmod = fromEnum $ modificationTime stat
70 return $ strongETag $ printf "%x-%x-%x" inode size lastmod