on master help sign in
Added enumerator buffer function.
commit1b2f9de8b61065424871816b04c968dd6cc10781 authorMichael Snoyman <michael@snoyman.com> dateFri 9 Apr 2010, 17:58 (17 years ago) parentc1fdc97
3 files changed+31−7
Network/Wai/Enumerator.hs+28−5 test.hs+2−1 wai.cabal+1−1
Network/Wai/Enumerator.hs+28−5
@@ -15,6 +15,8 @@ module Network.Wai.Enumerator
1515 -- ** FilePath
1616 , fromFile
1717 , fromEitherFile
18+ -- * Filters
19+ , buffer
1820 ) where
1921
2022import Network.Wai (Enumerator (..), Source (..))
@@ -67,16 +69,16 @@ fromLBS' lbs' = Enumerator $ \iter a0 -> lbs' >>= \lbs ->
6769-- deadlocked.
6870toSource :: Enumerator -> IO Source
6971toSource (Enumerator e) = do
70− buffer <- newEmptyMVar
71− _ <- forkIO $ e (helper buffer) () >> putMVar buffer Nothing
72− return $ source buffer
72+ buff <- newEmptyMVar
73+ _ <- forkIO $ e (helper buff) () >> putMVar buff Nothing
74+ return $ source buff
7375 where
7476 helper :: MVar (Maybe B.ByteString)
7577 -> ()
7678 -> B.ByteString
7779 -> IO (Either () ())
78− helper buffer _ bs = do
79− putMVar buffer $ Just bs
80+ helper buff _ bs = do
81+ putMVar buff $ Just bs
8082 return $ Right ()
8183 source :: MVar (Maybe B.ByteString)
8284 -> Source
@@ -115,3 +117,24 @@ fromFile fp = Enumerator $ \iter a0 -> withBinaryFile fp ReadMode $ \h ->
115117-- be convenient for server implementations not optimizing file sending.
116118fromEitherFile :: Either FilePath Enumerator -> Enumerator
117119fromEitherFile = either fromFile id
120+
121+-- | Buffer chunks until we have a chunk of 'defaultChunkSize', and then send
122+-- it.
123+buffer :: Enumerator -> Enumerator
124+buffer (Enumerator e) =
125+ Enumerator go
126+ where
127+ go iter seed = do
128+ res <- e (iter' iter) (B.empty, seed)
129+ case res of
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)
135+ else do
136+ let (x, y) = B.splitAt (defaultChunkSize - B.length buff) bs
137+ res <- iter seed $ buff `B.append` x
138+ case res of
139+ Left seed' -> return $ Left (y, seed') -- y is ignored
140+ Right seed' -> return $ Right (y, seed')
test.hs+2−1
@@ -1,5 +1,6 @@
11{-# LANGUAGE Rank2Types #-}
22import Network.Wai
3+import Network.Wai.Enumerator (buffer)
34import Network.Wai.Handler.SimpleServer
45import qualified Data.ByteString.Char8 as B8
56import qualified Network.Wai.Source as Source
@@ -23,7 +24,7 @@ postResponse :: Enumerator -> IO Response
2324postResponse rb = return Response
2425 { status = Status200
2526 , responseHeaders = [(ContentType, B8.pack "text/plain")]
26− , responseBody = Right rb
27+ , responseBody = Right $ buffer rb
2728 }
2829
2930index :: Either FilePath a
wai.cabal+1−1
@@ -1,5 +1,5 @@
11Name: wai
2−Version: 0.0.0
2+Version: 0.0.1
33Synopsis: Web Application Interface.
44Description: Provides a common protocol for communication between web aplications and web servers.
55License: BSD3