on master help sign in
RequestBody is now a Source

This may not be a good move, but here's the rationale. We have a few reasons to avoid buffering: * It's a performance overhead * It's less well understood In this case, none of our code is actually utilizing the buffered aspect of the source. Warp comes the closest, but in fact only uses it internally. After it's done with the buffered actions, it applies isolate, which creates an unbuffered source again. Overall, I'm beginning to think that the place for buffering is only internal, and all external interfaces should be unbuffered (there's a similar commit to http-conduit).

commitd26504183f0b9202b7f64995eac560b5a06c311a authorMichael Snoyman <michael@snoyman.com> dateTue 17 Jan 2012, 17:37 (15 years ago) parent9c51b73
6 files changed+8−12
wai-extra/Network/Wai/Handler/CGI.hs+1−2 wai-extra/Network/Wai/Middleware/RequestLogger.hs+1−2 wai-frontend-monadcgi/Network/Wai/Frontend/MonadCGI.hs+1−2 wai-test/Network/Wai/Test.hs+2−3 wai/Network/Wai.hs+1−1 warp/Network/Wai/Handler/Warp.hs+2−2
wai-extra/Network/Wai/Handler/CGI.hs+1−2
@@ -95,7 +95,6 @@ runGeneric vars inputH outputH xsendfile app = do
9595 a:_ -> addrAddress a
9696 [] -> error $ "Invalid REMOTE_ADDR or REMOTE_HOST: " ++ remoteHost'
9797 C.runResourceT $ do
98− input <- C.bufferSource $ inputH contentLength
9998 let env = Request
10099 { requestMethod = rmethod
101100 , rawPathInfo = B.pack pinfo
@@ -108,7 +107,7 @@ runGeneric vars inputH outputH xsendfile app = do
108107 , isSecure = isSecure'
109108 , remoteHost = addr
110109 , httpVersion = H.http11 -- FIXME
111− , requestBody = input
110+ , requestBody = inputH contentLength
112111 , vault = mempty
113112 }
114113 -- FIXME worry about exception?
wai-extra/Network/Wai/Middleware/RequestLogger.hs+1−2
@@ -102,8 +102,7 @@ logHandleDev cb app req = do
102102 , "\n"
103103 ]
104104 -- we just consumed the body- fill the enumerator back up so it is available again
105− body' <- C.bufferSource $ CL.sourceList body
106− app req { requestBody = body' }
105+ app req { requestBody = CL.sourceList body }
107106 where
108107 paramsToBS prefix params =
109108 if null params then ""
wai-frontend-monadcgi/Network/Wai/Frontend/MonadCGI.hs+1−2
@@ -10,7 +10,6 @@ import Network.HTTP.Types (Status (..))
1010import Control.Monad.IO.Class (liftIO)
1111import Data.CaseInsensitive (original)
1212
13−import Data.Conduit
1413import Data.Conduit.Lazy (lazyConsume)
1514
1615import qualified Data.Map as Map
@@ -34,7 +33,7 @@ cgiToAppGeneric :: Monad m
3433 -> CGIT m CGIResult
3534 -> Application
3635cgiToAppGeneric toIO cgi env = do
37− input <- fmap BS.fromChunks $ lazyConsume $ unbufferSource $ requestBody env
36+ input <- fmap BS.fromChunks $ lazyConsume $ requestBody env
3837 let vars = map (first fixVarName . go) (requestHeaders env)
3938 ++ getCgiVars env
4039 (inputs, body') = decodeInput vars input
wai-test/Network/Wai/Test.hs+2−3
@@ -74,7 +74,7 @@ defaultRequest = Request
7474 , remoteHost = error "Network.Wai.Test.defaultRequest{remoteHost}"
7575 , pathInfo = []
7676 , queryString = []
77− , requestBody = error "requestBody of defaultRequest"
77+ , requestBody = mempty
7878 , vault = mempty
7979 }
8080
@@ -82,8 +82,7 @@ srequest :: SRequest -> Session SResponse
8282srequest (SRequest req bod) = do
8383 app <- ask
8484 liftIO $ C.runResourceT $ do
85− body <- C.bufferSource $ CL.sourceList $ L.toChunks bod
86− let req' = req { requestBody = body }
85+ let req' = req { requestBody = CL.sourceList $ L.toChunks bod }
8786 res <- app req'
8887 sres <- runResponse res
8988 -- FIXME cookie processing
wai/Network/Wai.hs+1−1
@@ -95,7 +95,7 @@ data Request = Request
9595 , pathInfo :: [Text]
9696 -- | Parsed query string information
9797 , queryString :: H.Query
98− , requestBody :: C.BufferedSource IO B.ByteString
98+ , requestBody :: C.Source IO B.ByteString
9999 -- | A location for arbitrary data to be shared by applications and middleware.
100100 , vault :: Vault
101101 }
warp/Network/Wai/Handler/Warp.hs+2−2
@@ -319,7 +319,7 @@ parseRequest' port (firstLine:otherLines) remoteHost' src = do
319319 let serverName' = takeUntil 58 host -- ':'
320320 -- FIXME isolate takes an Integer instead of Int or Int64. If this is a
321321 -- performance penalty, we may need our own version.
322− rbody <- C.bufferSource $
322+ rbody <- C.prepareSource $
323323 if len == 0
324324 then mempty
325325 else src C.$= CB.isolate len
@@ -335,7 +335,7 @@ parseRequest' port (firstLine:otherLines) remoteHost' src = do
335335 , requestHeaders = heads
336336 , isSecure = False
337337 , remoteHost = remoteHost'
338− , requestBody = rbody
338+ , requestBody = C.Source $ return rbody
339339 , vault = mempty
340340 }
341341