@@ -15,6 +15,8 @@ module Network.Wai.Enumerator
15 -- ** FilePath
15 -- ** FilePath
16 , fromFile
16 , fromFile
17 , fromEitherFile
17 , fromEitherFile
20import Network.Wai (Enumerator (..), Source (..))
22import Network.Wai (Enumerator (..), Source (..))
@@ -67,16 +69,16 @@ fromLBS' lbs' = Enumerator $ \iter a0 -> lbs' >>= \lbs ->
67-- deadlocked.
69-- deadlocked.
68toSource :: Enumerator -> IO Source
70toSource :: Enumerator -> IO Source
69toSource (Enumerator e) = do
71toSource (Enumerator e) = do
70− buffer <- newEmptyMVar
72+ buff <- newEmptyMVar
71− _ <- forkIO $ e (helper buffer) () >> putMVar buffer Nothing
73+ _ <- forkIO $ e (helper buff) () >> putMVar buff Nothing
72− return $ source buffer
74+ return $ source buff
74 helper :: MVar (Maybe B.ByteString)
76 helper :: MVar (Maybe B.ByteString)
76 -> B.ByteString
78 -> B.ByteString
77 -> IO (Either () ())
79 -> IO (Either () ())
78− helper buffer _ bs = do
80+ helper buff _ bs = do
79− putMVar buffer $ Just bs
81+ putMVar buff $ Just bs
80 return $ Right ()
82 return $ Right ()
81 source :: MVar (Maybe B.ByteString)
83 source :: MVar (Maybe B.ByteString)
@@ -115,3 +117,24 @@ fromFile fp = Enumerator $ \iter a0 -> withBinaryFile fp ReadMode $ \h ->
115-- be convenient for server implementations not optimizing file sending.
117-- be convenient for server implementations not optimizing file sending.
116fromEitherFile :: Either FilePath Enumerator -> Enumerator
118fromEitherFile :: Either FilePath Enumerator -> Enumerator
117fromEitherFile = either fromFile id
119fromEitherFile = either fromFile id
121+-- | Buffer chunks until we have a chunk of 'defaultChunkSize', and then send
123+buffer :: Enumerator -> Enumerator
124+buffer (Enumerator e) =
128+ res <- e (iter' iter) (B.empty, seed)
130+ Left (_, seed') -> return $ Left seed'
131+ Right (buff, seed') -> iter seed' buff
132+ iter' iter (buff, seed) bs = do
133+ if B.length buff + B.length bs < defaultChunkSize
134+ then return $ Right (buff `B.append` bs, seed)
136+ let (x, y) = B.splitAt (defaultChunkSize - B.length buff) bs
137+ res <- iter seed $ buff `B.append` x
139+ Left seed' -> return $ Left (y, seed') -- y is ignored
140+ Right seed' -> return $ Right (y, seed')