@@ -12,8 +12,11 @@ module Network.Wai.Enumerator
1212 , toSource
1313 -- ** Handle
1414 , fromHandle
15+ , fromHandleFinally
1516 -- ** FilePath
1617 , fromFile
18+ , fromFileFinally
19+ , fromTempFile
1720 , fromResponseBody
1821 ) where
1922
@@ -21,10 +24,12 @@ import Network.Wai (Enumerator (..), Source (..), ResponseBody (..))
2124import qualified Network.Wai.Source as Source
2225import qualified Data.ByteString.Lazy as L
2326import qualified Data.ByteString as B
27+import System.Directory (removeFile)
2428import System.IO (withBinaryFile, IOMode (ReadMode), Handle, hIsEOF)
2529import Data.ByteString.Lazy.Internal (defaultChunkSize)
2630import Control.Concurrent (forkIO)
2731import Control.Concurrent.MVar
32+import Control.Exception
2833import Control.Monad ((<=<))
2934
3035-- | Performs a specified conversion on each 'B.ByteString' output by an
@@ -105,11 +110,27 @@ fromHandle h = Enumerator $ \iter a -> do
105110 Left a' -> return $ Left a'
106111 Right a' -> runEnumerator (fromHandle h) iter a'
107112
113+-- | Wrapper around fromHandle to perform an action after EOF or an exception
114+fromHandleFinally :: Handle -> IO a -> Enumerator
115+fromHandleFinally h onEOF = Enumerator $ \iter a0 ->
116+ finally (runEnumerator (fromHandle h) iter a0)
117+ onEOF
118+
108119-- | A little wrapper around 'fromHandle' which first opens a file for reading.
109120fromFile :: FilePath -> Enumerator
110121fromFile fp = Enumerator $ \iter a0 -> withBinaryFile fp ReadMode $ \h ->
111122 runEnumerator (fromHandle h) iter a0
112123
124+-- | Wrapper around fromFile to perform an action after the file is closed.
125+fromFileFinally :: FilePath -> IO a -> Enumerator
126+fromFileFinally fp onClose = Enumerator $ \iter a0 ->
127+ finally (runEnumerator (fromFile fp) iter a0)
128+ onClose
129+
130+-- | Enumerator to read and remove a file
131+fromTempFile :: FilePath -> Enumerator
132+fromTempFile fp = fromFileFinally fp $ removeFile fp
133+
113134-- | Since the response body is defined as a 'ResponseBody', this function
114135-- simply reduces the whole value to an enumerator. This can be convenient for
115136-- server implementations not optimizing file sending.