@@ -2,6 +2,7 @@
22{-# LANGUAGE OverloadedStrings #-}
33{-# LANGUAGE ExistentialQuantification #-}
44{-# LANGUAGE PatternGuards #-}
5+{-# LANGUAGE TypeFamilies #-}
56-- | Some helpers for parsing data out of a raw WAI 'Request'.
67
78module Network.Wai.Parse
@@ -50,6 +51,10 @@ import Data.Either (partitionEithers)
5051import Control.Monad (when, unless)
5152import Control.Monad.Trans.Class (lift)
5253import 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)
57+#endif
5358
5459breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
5560breakDiscard w s =
@@ -184,7 +189,11 @@ conduitRequestBody _ UrlEncoded = do
184189conduitRequestBody backend (Multipart bound) =
185190 parsePieces backend $ S8.pack "--" `S.append` bound
186191
192+#if MIN_VERSION_conduit(1, 0, 0)
193+takeLine :: MonadSink S.ByteString m (Maybe S.ByteString)
194+#else
187195takeLine :: Monad m => Pipe S.ByteString S.ByteString o u m (Maybe S.ByteString)
196+#endif
188197takeLine =
189198 go id
190199 where
@@ -199,7 +208,11 @@ takeLine =
199208 when (S.length y > 1) $ leftover $ S.drop 1 y
200209 return $ Just $ killCR x
201210
211+#if MIN_VERSION_conduit(1, 0, 0)
212+takeLines :: MonadSink S.ByteString (ResourceT IO) [S.ByteString]
213+#else
202214takeLines :: Pipe S.ByteString S.ByteString o u (ResourceT IO) [S.ByteString]
215+#endif
203216takeLines = do
204217 res <- takeLine
205218 case res of
@@ -212,7 +225,11 @@ takeLines = do
212225
213226parsePieces :: BackEnd y
214227 -> S.ByteString
228+#if MIN_VERSION_conduit(1, 0, 0)
229+ -> ConduitM S.ByteString (Either Param (File y)) (ResourceT IO) ()
230+#else
215231 -> Pipe S.ByteString S.ByteString (Either Param (File y)) u (ResourceT IO) ()
232+#endif
216233parsePieces sink bound =
217234 loop
218235 where
@@ -287,12 +304,37 @@ sinkTillBound' :: S.ByteString
287304 -> S.ByteString
288305 -> FileInfo ()
289306 -> BackEnd y
307+#if MIN_VERSION_conduit(1, 0, 0)
308+ -> ConduitM S.ByteString o (ResourceT IO) (Bool, y)
309+#else
290310 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, y)
291−sinkTillBound' bound name fi sink = conduitTillBound bound >+> withUpstream (sinkToPipe $ sink name fi)
311+#endif
312+sinkTillBound' bound name fi sink =
313+#if MIN_VERSION_conduit(1, 0, 0)
314+ streamFromPipe $ anyOutput $
315+#endif
316+ conduitTillBound bound >+> withUpstream (fix $ sink name fi)
317+ where
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 ())
324+
325+ anyOutput p = p >+> dropInput
326+ dropInput = NeedInput (const dropInput) return
327+#else
328+ fix = sinkToPipe
329+#endif
292330
293331conduitTillBound :: Monad m
294332 => S.ByteString -- bound
333+#if MIN_VERSION_conduit(1, 0, 0)
334+ -> Pipe S.ByteString S.ByteString S.ByteString () m Bool
335+#else
295336 -> Pipe S.ByteString S.ByteString S.ByteString u m Bool
337+#endif
296338conduitTillBound bound =
297339 go id
298340 where
@@ -323,11 +365,26 @@ conduitTillBound bound =
323365sinkTillBound :: S.ByteString
324366 -> (x -> S.ByteString -> IO x)
325367 -> x
368+#if MIN_VERSION_conduit(1, 0, 0)
369+ -> MonadSink S.ByteString (ResourceT IO) (Bool, x)
370+#else
326371 -> Pipe S.ByteString S.ByteString o u (ResourceT IO) (Bool, x)
372+#endif
327373sinkTillBound bound iter seed0 =
328− conduitTillBound bound >+> withUpstream (CL.foldM iter' seed0)
374+#if MIN_VERSION_conduit(1, 0, 0)
375+ streamFromPipe $
376+#endif
377+ (conduitTillBound bound >+> (withUpstream $ ij $ CL.foldM iter' seed0))
329378 where
330379 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 ())
385+#else
386+ ij = id
387+#endif
331388
332389parseAttrs :: S.ByteString -> [(S.ByteString, S.ByteString)]
333390parseAttrs = map go . S.split 59 -- semicolon