module Network.Wai.Streaming ( Flush(..)
, streamingRequest
, streamingResponse
, streamingBody
, streamingResponseF
, streamingBodyF
) where
import Streaming
import Network.Wai
import Control.Monad (unless)
import Data.ByteString (ByteString)
import Data.ByteString.Builder (byteString, Builder)
import Network.HTTP.Types.Header
import Network.HTTP.Types.Status
import Streaming.Prelude as S
import Data.ByteString as BS
data Flush a = Chunk a
| Flush
deriving (Show, Functor)
streamingRequest :: MonadIO m => Request -> Stream (Of ByteString) m ()
streamingRequest req = loop
where
go = liftIO (requestBody req)
loop = do
bs <- go
unless (BS.null bs) $ do
yield bs
loop
streamingResponse :: Stream (Of ByteString) IO r
-> Status
-> ResponseHeaders
-> Response
streamingResponse src status headers =
responseStream status headers (streamingBody src)
streamingBody :: Stream (Of ByteString) IO r -> StreamingBody
streamingBody src write flush = void $ effects $ for src writer
where
writer a = do
lift (write (byteString a))
lift flush
streamingResponseF :: Stream (Of (Flush Builder)) IO r
-> Status
-> ResponseHeaders
-> Response
streamingResponseF src status headers =
responseStream status headers (streamingBodyF src)
streamingBodyF :: Stream (Of (Flush Builder)) IO r -> StreamingBody
streamingBodyF src write flush = void $ effects $ for src writer
where
writer (Chunk a) = lift (write a)
writer Flush = lift flush