on master help sign in
pauseTimeout function
commit1db5d2eb7524165c2b958e9c96a07284d344b8e7 authorMichael Snoyman <michael@snoyman.com> dateFri 20 Mar 2015, 11:27 (12 years ago) parent8655714
4 files changed+37−7
warp/ChangeLog.md+2−1 warp/Network/Wai/Handler/Warp.hs+23−3 warp/Network/Wai/Handler/Warp/Request.hs+10−2 warp/warp.cabal+2−1
warp/ChangeLog.md+2−1
@@ -1,4 +1,4 @@
1−## 3.0.9.4
1+## 3.0.10
22
33* Fix [missing `IORef` tweak](https://github.com/yesodweb/wai/issues/351)
44* Disable timeouts as soon as request body is fully consumed. This addresses
@@ -6,6 +6,7 @@
66 until a zero-length `ByteString` is returned, but that is suboptimal for some
77 cases. For more information, see [issue
88 351](https://github.com/yesodweb/wai/issues/351).
9+* Add `pauseTimeout` function
910
1011## 3.0.9.3
1112
warp/Network/Wai/Handler/Warp.hs+23−3
@@ -23,8 +23,15 @@
2323-- corner case is partial request body consumption; in that case, Warp's
2424-- timeout handling is still in effect, and the timeout will not be triggered
2525-- again. Therefore, it is recommended that once you start consuming the
26−-- request body, you consume the entire body promptly. For more information,
27−-- see <https://github.com/yesodweb/wai/issues/351>.
26+-- request body, you either:
27+--
28+-- * consume the entire body promptly
29+--
30+-- * call the 'pauseTimeout' function
31+--
32+-- For more information, see <https://github.com/yesodweb/wai/issues/351>.
33+--
34+--
2835module Network.Wai.Handler.Warp (
2936 -- * Run a Warp server
3037 run
@@ -81,6 +88,8 @@ module Network.Wai.Handler.Warp (
8188 , Port
8289 , InvalidRequest (..)
8390 , ConnSendFileOverride (..)
91+ -- * Per-request utilities
92+ , pauseTimeout
8493 -- * Connection
8594 , Connection (..)
8695 , socketConnection
@@ -113,10 +122,12 @@ import Network.Wai.Handler.Warp.Settings
113122import Network.Wai.Handler.Warp.Timeout
114123import Network.Wai.Handler.Warp.Types
115124import Control.Exception (SomeException)
116−import Network.Wai (Request, Response)
125+import Network.Wai (Request, Response, vault)
117126import Network.Socket (SockAddr)
118127import Data.Streaming.Network (HostPreference)
119128import Data.ByteString (ByteString)
129+import qualified Data.Vault.Lazy as Vault
130+import Data.Maybe (fromMaybe)
120131
121132-- | Port to listen on. Default value: 3000
122133--
@@ -292,3 +303,12 @@ setProxyProtocolRequired y = y { settingsProxyProtocol = ProxyProtocolRequired }
292303-- Since 3.0.5
293304setProxyProtocolOptional :: Settings -> Settings
294305setProxyProtocolOptional y = y { settingsProxyProtocol = ProxyProtocolOptional }
306+
307+-- | Explicitly pause the slowloris timeout.
308+--
309+-- This is useful for cases where you partially consume a request body. For
310+-- more information, see <https://github.com/yesodweb/wai/issues/351>
311+--
312+-- Since 3.0.10
313+pauseTimeout :: Request -> IO ()
314+pauseTimeout = fromMaybe (return ()) . Vault.lookup pauseTimeoutKey . vault
warp/Network/Wai/Handler/Warp/Request.hs+10−2
@@ -6,6 +6,7 @@
66module Network.Wai.Handler.Warp.Request (
77 recvRequest
88 , headerLines
9+ , pauseTimeoutKey
910 ) where
1011
1112import qualified Control.Concurrent as Conc (yield)
@@ -16,7 +17,6 @@ import qualified Data.ByteString as S
1617import qualified Data.ByteString.Unsafe as SU
1718import qualified Data.CaseInsensitive as CI
1819import qualified Data.IORef as I
19−import Data.Monoid (mempty)
2020import qualified Network.HTTP.Types as H
2121import Network.Socket (SockAddr)
2222import Network.Wai
@@ -30,6 +30,8 @@ import Network.Wai.Handler.Warp.Types
3030import Network.Wai.Internal
3131import Prelude hiding (lines)
3232import Control.Monad (when)
33+import qualified Data.Vault.Lazy as Vault
34+import System.IO.Unsafe (unsafePerformIO)
3335
3436----------------------------------------------------------------
3537
@@ -74,7 +76,9 @@ recvRequest settings conn ii addr src = do
7476 , isSecure = False
7577 , remoteHost = addr
7678 , requestBody = rbody'
77− , vault = mempty
79+ , vault = Vault.insert pauseTimeoutKey
80+ (Timeout.pause th)
81+ Vault.empty
7882 , requestBodyLength = bodyLength
7983 , requestHeaderHost = idxhdr ! idxHost
8084 , requestHeaderRange = idxhdr ! idxRange
@@ -261,3 +265,7 @@ checkCR :: ByteString -> Int -> Int
261265checkCR bs pos = if pos > 0 && 13 == S.index bs p then p else pos -- 13 is CR
262266 where
263267 !p = pos - 1
268+
269+pauseTimeoutKey :: Vault.Key (IO ())
270+pauseTimeoutKey = unsafePerformIO Vault.newKey
271+{-# NOINLINE pauseTimeoutKey #-}
warp/warp.cabal+2−1
@@ -1,5 +1,5 @@
11Name: warp
2−Version: 3.0.9.4
2+Version: 3.0.10
33Synopsis: A fast, light-weight web server for WAI applications.
44License: MIT
55License-file: LICENSE
@@ -46,6 +46,7 @@ Library
4646 , wai >= 3.0 && < 3.1
4747 , text
4848 , streaming-commons >= 0.1.10
49+ , vault >= 0.3
4950 if flag(network-bytestring)
5051 Build-Depends: network >= 2.2.1.5 && < 2.2.3
5152 , network-bytestring >= 0.1.3 && < 0.1.4