on master help sign in
setMaximumBodyFlush settings

Pinging @kazu-yamamoto @meteficha. This should be the last commit in this request body flushing saga.

commit0be7202622261f56d94858e463b46d5a8009ef50 authorMichael Snoyman <michael@snoyman.com> dateThu 27 Nov 2014, 07:13 (12 years ago) parent38934e7
5 files changed+53−14
warp/ChangeLog.md+4−1 warp/Network/Wai/Handler/Warp.hs+18 warp/Network/Wai/Handler/Warp/Run.hs+25−12 warp/Network/Wai/Handler/Warp/Settings.hs+5 warp/warp.cabal+1−1
warp/ChangeLog.md+4−1
@@ -1,4 +1,4 @@
1−## 3.0.2.4
1+## 3.0.3
22
33Modify flushing of request bodies. Previously, regardless of the size of the
44request body, the entire body would be flushed. When uploading large files to a
@@ -11,6 +11,9 @@ consumed and, if so, immediately terminate the connection. In the case of
1111chunked request bodies, up to a maximum number of bytes is consumed before the
1212connection is terminated.
1313
14+This is controlled by the new setting `setMaximumBodyFlush`. A value of
15+@Nothing@ will return the original behavior of flushing the entire body.
16+
1417## 3.0.0
1518
1619WAI no longer uses conduit for its streaming interface.
warp/Network/Wai/Handler/Warp.hs+18
@@ -41,6 +41,7 @@ module Network.Wai.Handler.Warp (
4141 , setNoParsePath
4242 , setInstallShutdownHandler
4343 , setServerName
44+ , setMaximumBodyFlush
4445 -- ** Getters
4546 , getPort
4647 , getHost
@@ -210,3 +211,20 @@ setInstallShutdownHandler x y = y { settingsInstallShutdownHandler = x }
210211-- Since 3.0.2
211212setServerName :: ByteString -> Settings -> Settings
212213setServerName x y = y { settingsServerName = x }
214+
215+-- | The maximum number of bytes to flush from an unconsumed request body.
216+--
217+-- By default, Warp does not flush the request body so that, if a large body is
218+-- present, the connection is simply terminated instead of wasting time and
219+-- bandwidth on transmitting it. However, some clients do not deal with that
220+-- situation well. You can either change this setting to @Nothing@ to flush the
221+-- entire body in all cases, or in your application ensure that you always
222+-- consume the entire request body.
223+--
224+-- Default: 8192 bytes.
225+--
226+-- Since 3.0.3
227+setMaximumBodyFlush :: Maybe Int -> Settings -> Settings
228+setMaximumBodyFlush x y
229+ | Just x' <- x, x' < 0 = error "setMaximumBodyFlush: must be positive"
230+ | otherwise = y { settingsMaximumBodyFlush = x }
warp/Network/Wai/Handler/Warp/Run.hs+25−12
@@ -329,18 +329,31 @@ serveConnection conn ii addr isSecure' settings app = do
329329 -- If there is an unknown or large amount of data to still be read
330330 -- from the request body, simple drop this connection instead of
331331 -- reading it all in to satisfy a keep-alive request.
332− let maxToRead = 8192 -- FIXME too low?
333− tryKeepAlive = do
334− -- flush the rest of the request body
335− isComplete <- flushBody (requestBody req) maxToRead
336− when isComplete $ do
337− T.resume th
338− recvSendLoop istatus fromClient
339− case mremainingRef of
340− Just ref -> do
341− remaining <- readIORef ref
342− when (remaining <= maxToRead) tryKeepAlive
343− Nothing -> tryKeepAlive
332+ case settingsMaximumBodyFlush settings of
333+ Nothing -> do
334+ flushEntireBody (requestBody req)
335+ T.resume th
336+ recvSendLoop istatus fromClient
337+ Just maxToRead -> do
338+ let tryKeepAlive = do
339+ -- flush the rest of the request body
340+ isComplete <- flushBody (requestBody req) maxToRead
341+ when isComplete $ do
342+ T.resume th
343+ recvSendLoop istatus fromClient
344+ case mremainingRef of
345+ Just ref -> do
346+ remaining <- readIORef ref
347+ when (remaining <= maxToRead) tryKeepAlive
348+ Nothing -> tryKeepAlive
349+
350+flushEntireBody :: IO ByteString -> IO ()
351+flushEntireBody src =
352+ loop
353+ where
354+ loop = do
355+ bs <- src
356+ unless (S.null bs) loop
344357
345358flushBody :: IO ByteString -- ^ get next chunk
346359 -> Int -- ^ maximum to flush
warp/Network/Wai/Handler/Warp/Settings.hs+5
@@ -65,6 +65,10 @@ data Settings = Settings
6565 -- ^ Default server name if application does not set one.
6666 --
6767 -- Since 3.0.2
68+ , settingsMaximumBodyFlush :: Maybe Int
69+ -- ^ See @setMaximumBodyFlush@.
70+ --
71+ -- Since 3.0.3
6872 }
6973
7074-- | The default settings for the Warp server. See the individual settings for
@@ -84,6 +88,7 @@ defaultSettings = Settings
8488 , settingsNoParsePath = False
8589 , settingsInstallShutdownHandler = const $ return ()
8690 , settingsServerName = S8.pack $ "Warp/" ++ showVersion Paths_warp.version
91+ , settingsMaximumBodyFlush = Just 8192
8792 }
8893
8994-- | Apply the logic provided by 'defaultExceptionHandler' to determine if an
warp/warp.cabal+1−1
@@ -1,5 +1,5 @@
11Name: warp
2−Version: 3.0.2.4
2+Version: 3.0.3
33Synopsis: A fast, light-weight web server for WAI applications.
44License: MIT
55License-file: LICENSE