@@ -10,7 +10,8 @@ import Network.HTTP.Types (Status (..))
10import Control.Monad.IO.Class (liftIO)
10import Control.Monad.IO.Class (liftIO)
11import Data.CaseInsensitive (original)
11import Data.CaseInsensitive (original)
13−import qualified Data.Enumerator.List as EL
13+import Data.Conduit
14+import Data.Conduit.Lazy (lazyConsume)
15import qualified Data.Map as Map
16import qualified Data.Map as Map
16import qualified Data.ByteString.Lazy as BS
17import qualified Data.ByteString.Lazy as BS
@@ -28,15 +29,18 @@ safeRead d s = case reads s of
28cgiToApp :: CGI CGIResult -> Application
29cgiToApp :: CGI CGIResult -> Application
29cgiToApp = cgiToAppGeneric id
30cgiToApp = cgiToAppGeneric id
32+unbufferSource :: Monad m => BufferedSource m a -> Source m a
33+unbufferSource bsrc = Source $ return $ PreparedSource
34+ { sourcePull = bsourcePull bsrc
35+ , sourceClose = bsourceClose bsrc
31cgiToAppGeneric :: Monad m
38cgiToAppGeneric :: Monad m
32 => (m (Headers, CGIResult) -> IO (Headers, CGIResult))
39 => (m (Headers, CGIResult) -> IO (Headers, CGIResult))
33 -> CGIT m CGIResult
40 -> CGIT m CGIResult
34 -> Application
41 -> Application
35cgiToAppGeneric toIO cgi env = do
42cgiToAppGeneric toIO cgi env = do
36− -- Note: the next line will read the entire request body into memory.
37− -- This is a flaw in enumerator-based WAI. Conduit-based WAI will allow
38− -- for lazy I/O here.
39− input <- fmap BS.fromChunks EL.consume
43+ input <- fmap BS.fromChunks $ lazyConsume $ unbufferSource $ requestBody env
40 let vars = map (first fixVarName . go) (requestHeaders env)
44 let vars = map (first fixVarName . go) (requestHeaders env)
41 ++ getCgiVars env
45 ++ getCgiVars env
42 (inputs, body') = decodeInput vars input
46 (inputs, body') = decodeInput vars input