@@ -2,6 +2,7 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE ExistentialQuantification #-}
3{-# LANGUAGE ExistentialQuantification #-}
4{-# LANGUAGE PatternGuards #-}
4{-# LANGUAGE PatternGuards #-}
5+{-# LANGUAGE TypeFamilies #-}
5-- | Some helpers for parsing data out of a raw WAI 'Request'.
6-- | Some helpers for parsing data out of a raw WAI 'Request'.
7module Network.Wai.Parse
8module Network.Wai.Parse
@@ -50,6 +51,10 @@ import Data.Either (partitionEithers)
50import Control.Monad (when, unless)
51import Control.Monad (when, unless)
51import Control.Monad.Trans.Class (lift)
52import Control.Monad.Trans.Class (lift)
52import Control.Monad.Trans.Resource (allocate, release, register)
53import Control.Monad.Trans.Resource (allocate, release, register)
54+#if MIN_VERSION_conduit(1, 0, 0)
55+import Data.Conduit.Internal (Pipe (NeedInput, HaveOutput), (>+>), withUpstream, Sink (..), injectLeftovers, streamFromPipe, ConduitM)
56+import Data.Void (Void)
54breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
59breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
55breakDiscard w s =
60breakDiscard w s =
@@ -184,7 +189,11 @@ conduitRequestBody _ UrlEncoded = do
184conduitRequestBody backend (Multipart bound) =
189conduitRequestBody backend (Multipart bound) =
185 parsePieces backend $ S8.pack "--" `S.append` bound
190 parsePieces backend $ S8.pack "--" `S.append` bound
192+#if MIN_VERSION_conduit(1, 0, 0)
193+takeLine :: MonadSink S.ByteString m (Maybe S.ByteString)
187takeLine :: Monad m => Pipe S.ByteString S.ByteString o u m (Maybe S.ByteString)
195takeLine :: Monad m => Pipe S.ByteString S.ByteString o u m (Maybe S.ByteString)
188takeLine =
197takeLine =
@@ -199,7 +208,11 @@ takeLine =
199 when (S.length y > 1) $ leftover $ S.drop 1 y
208 when (S.length y > 1) $ leftover $ S.drop 1 y
200 return $ Just $ killCR x
209 return $ Just $ killCR x
211+#if MIN_VERSION_conduit(1, 0, 0)
212+takeLines :: MonadSink S.ByteString (ResourceT IO) [S.ByteString]
202takeLines :: Pipe S.ByteString S.ByteString o u (ResourceT IO) [S.ByteString]
214takeLines :: Pipe S.ByteString S.ByteString o u (ResourceT IO) [S.ByteString]
203takeLines = do
216takeLines = do
204 res <- takeLine
217 res <- takeLine
205 case res of
218 case res of
@@ -212,7 +225,11 @@ takeLines = do
213parsePieces :: BackEnd y
226parsePieces :: BackEnd y
214 -> S.ByteString
227 -> S.ByteString
228+#if MIN_VERSION_conduit(1, 0, 0)
229+ -> ConduitM S.ByteString (Either Param (File y)) (ResourceT IO) ()
215 -> Pipe S.ByteString S.ByteString (Either Param (File y)) u (ResourceT IO) ()
231 -> Pipe S.ByteString S.ByteString (Either Param (File y)) u (ResourceT IO) ()
216parsePieces sink bound =
233parsePieces sink bound =
@@ -287,12 +304,37 @@ sinkTillBound' :: S.ByteString
287 -> S.ByteString
304 -> S.ByteString
288 -> FileInfo ()
305 -> FileInfo ()
289 -> BackEnd y
306 -> BackEnd y
307+#if MIN_VERSION_conduit(1, 0, 0)
308+ -> ConduitM S.ByteString o (ResourceT IO) (Bool, y)
290 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, y)
310 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, y)
291−sinkTillBound' bound name fi sink = conduitTillBound bound >+> withUpstream (sinkToPipe $ sink name fi)
312+sinkTillBound' bound name fi sink =
313+#if MIN_VERSION_conduit(1, 0, 0)
314+ streamFromPipe $ anyOutput $
316+ conduitTillBound bound >+> withUpstream (fix $ sink name fi)
318+#if MIN_VERSION_conduit(1, 0, 0)
319+ fix :: Sink S8.ByteString (ResourceT IO) y -> Pipe Void S8.ByteString Void Bool (ResourceT IO) y
320+ fix (Sink p) = ignoreTerm >+> injectLeftovers p
321+ ignoreTerm = await' >>= maybe (return ()) (\x -> yield' x >> ignoreTerm)
322+ await' = NeedInput (return . Just) (const $ return Nothing)
323+ yield' = HaveOutput (return ()) (return ())
325+ anyOutput p = p >+> dropInput
326+ dropInput = NeedInput (const dropInput) return
293conduitTillBound :: Monad m
331conduitTillBound :: Monad m
294 => S.ByteString -- bound
332 => S.ByteString -- bound
333+#if MIN_VERSION_conduit(1, 0, 0)
334+ -> Pipe S.ByteString S.ByteString S.ByteString () m Bool
295 -> Pipe S.ByteString S.ByteString S.ByteString u m Bool
336 -> Pipe S.ByteString S.ByteString S.ByteString u m Bool
296conduitTillBound bound =
338conduitTillBound bound =
@@ -323,11 +365,26 @@ conduitTillBound bound =
323sinkTillBound :: S.ByteString
365sinkTillBound :: S.ByteString
324 -> (x -> S.ByteString -> IO x)
366 -> (x -> S.ByteString -> IO x)
368+#if MIN_VERSION_conduit(1, 0, 0)
369+ -> MonadSink S.ByteString (ResourceT IO) (Bool, x)
326 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, x)
371 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, x)
327sinkTillBound bound iter seed0 =
373sinkTillBound bound iter seed0 =
374+#if MIN_VERSION_conduit(1, 0, 0)
328− conduitTillBound bound >+> withUpstream (CL.foldM iter' seed0)
377+ (conduitTillBound bound >+> (withUpstream $ ij $ CL.foldM iter' seed0))
330 iter' a b = liftIO $ iter a b
379 iter' a b = liftIO $ iter a b
380+#if MIN_VERSION_conduit(1, 0, 0)
381+ ij p = ignoreTerm >+> injectLeftovers p
382+ ignoreTerm = await' >>= maybe (return ()) (\x -> yield' x >> ignoreTerm)
383+ await' = NeedInput (return . Just) (const $ return Nothing)
384+ yield' = HaveOutput (return ()) (return ())
332parseAttrs :: S.ByteString -> [(S.ByteString, S.ByteString)]
389parseAttrs :: S.ByteString -> [(S.ByteString, S.ByteString)]
333parseAttrs = map go . S.split 59 -- semicolon
390parseAttrs = map go . S.split 59 -- semicolon