@@ -0,0 +1,33 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Network.Wai.Middleware.StreamFile where
4+
5+import Network.Wai
6+import Network.Wai.Internal
7+import Network.Wai (Middleware, responseToStream)
8+import Network.HTTP.Types (Status, ResponseHeaders)
9+import qualified Data.ByteString.Char8 as S8
10+import qualified Data.ByteString as S
11+import qualified Data.Streaming.Blaze as B
12+import qualified Blaze.ByteString.Builder as Blaze
13+import Control.Monad (unless)
14+import Data.Function (fix)
15+import System.Posix
16+
17+streamFile :: Middleware
18+streamFile app env sendResponse = app env $ \res ->
19+ case res of
20+ ResponseFile _ _ fp _ -> withBody sendBody
21+ where
22+ (s, hs, withBody) = responseToStream res
23+ sendBody :: StreamingBody -> IO ResponseReceived
24+ sendBody body = do
25+ len <- getFileSize fp
26+ let hs' = ("Content-Length", (S8.pack (show len))) : hs
27+ sendResponse $ responseStream s hs' body
28+ _ -> sendResponse res
29+
30+getFileSize :: FilePath -> IO FileOffset
31+getFileSize path = do
32+ stat <- getFileStatus path
33+ return (fileSize stat)