Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

fromHandleFinally, fromFileFinally, and fromTempFile

  • Loading branch information...
commit b37747ab9e2fd031512661ea57dc52c960edb902 1 parent 2f362ce
softmechanics authored October 23, 2010
21  Network/Wai/Enumerator.hs
@@ -12,8 +12,11 @@ module Network.Wai.Enumerator
12 12
     , toSource
13 13
       -- ** Handle
14 14
     , fromHandle
  15
+    , fromHandleFinally
15 16
       -- ** FilePath
16 17
     , fromFile
  18
+    , fromFileFinally
  19
+    , fromTempFile
17 20
     , fromResponseBody
18 21
     ) where
19 22
 
@@ -21,10 +24,12 @@ import Network.Wai (Enumerator (..), Source (..), ResponseBody (..))
21 24
 import qualified Network.Wai.Source as Source
22 25
 import qualified Data.ByteString.Lazy as L
23 26
 import qualified Data.ByteString as B
  27
+import System.Directory (removeFile)
24 28
 import System.IO (withBinaryFile, IOMode (ReadMode), Handle, hIsEOF)
25 29
 import Data.ByteString.Lazy.Internal (defaultChunkSize)
26 30
 import Control.Concurrent (forkIO)
27 31
 import Control.Concurrent.MVar
  32
+import Control.Exception
28 33
 import Control.Monad ((<=<))
29 34
 
30 35
 -- | Performs a specified conversion on each 'B.ByteString' output by an
@@ -105,11 +110,27 @@ fromHandle h = Enumerator $ \iter a -> do
105 110
                 Left a' -> return $ Left a'
106 111
                 Right a' -> runEnumerator (fromHandle h) iter a'
107 112
 
  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
+
108 119
 -- | A little wrapper around 'fromHandle' which first opens a file for reading.
109 120
 fromFile :: FilePath -> Enumerator
110 121
 fromFile fp = Enumerator $ \iter a0 -> withBinaryFile fp ReadMode $ \h ->
111 122
     runEnumerator (fromHandle h) iter a0
112 123
 
  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
+
113 134
 -- | Since the response body is defined as a 'ResponseBody', this function
114 135
 -- simply reduces the whole value to an enumerator. This can be convenient for
115 136
 -- server implementations not optimizing file sending.
3  wai.cabal
@@ -18,7 +18,8 @@ Source-repository head
18 18
 
19 19
 Library
20 20
   Build-Depends:     base >= 3 && < 5,
21  
-                     bytestring >= 0.9 && < 0.10
  21
+                     bytestring >= 0.9 && < 0.10,
  22
+                     directory
22 23
   Exposed-modules:   Network.Wai
23 24
                      Network.Wai.Enumerator
24 25
                      Network.Wai.Source

0 notes on commit b37747a

Please sign in to comment.
Something went wrong with that request. Please try again.