on master help sign in
Optional timeout protection
3745201Michael Snoyman
Network/Wai/Handler/Warp.hs+17−4
@@ -1,6 +1,7 @@
1{-# LANGUAGE DeriveDataTypeable #-}
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
4+{-# LANGUAGE CPP #-}
4---------------------------------------------------------
5---------------------------------------------------------
5-- |
6-- |
6-- Module : Network.Wai.Handler.Warp
7-- Module : Network.Wai.Handler.Warp
@@ -58,6 +59,7 @@ import Data.Monoid (mconcat)
58import Network.Socket.SendFile (sendFile)
59import Network.Socket.SendFile (sendFile)
59
60
60import Control.Monad.IO.Class (liftIO)
61import Control.Monad.IO.Class (liftIO)
62+import System.Timeout (timeout)
61
63
62run :: Port -> Application -> IO ()
64run :: Port -> Application -> IO ()
63run port = withSocketsDo .
65run port = withSocketsDo .
@@ -102,10 +104,11 @@ parseRequest port remoteHost' = do
102 parseRequest' port headers' remoteHost'
104 parseRequest' port headers' remoteHost'
103
105
104-- FIXME come up with good values here
106-- FIXME come up with good values here
105−maxHeaders, maxHeaderLength, bytesPerRead :: Int
107+maxHeaders, maxHeaderLength, bytesPerRead, readTimeout :: Int
106maxHeaders = 30
108maxHeaders = 30
107maxHeaderLength = 1024
109maxHeaderLength = 1024
108bytesPerRead = 4096
110bytesPerRead = 4096
111+readTimeout = 3000000
109
112
110takeUntilBlank :: Int
113takeUntilBlank :: Int
111 -> ([ByteString] -> [ByteString])
114 -> ([ByteString] -> [ByteString])
@@ -146,6 +149,7 @@ data InvalidRequest =
146 | TooManyHeaders
149 | TooManyHeaders
147 | IncompleteHeaders
150 | IncompleteHeaders
148 | OverLargeHeader
151 | OverLargeHeader
152+ | SocketTimeout
149 deriving (Show, Typeable)
153 deriving (Show, Typeable)
150instance Exception InvalidRequest
154instance Exception InvalidRequest
151
155
@@ -310,8 +314,17 @@ iterSocket socket =
310 go (E.Chunks cs) = liftIO (Sock.sendMany socket cs) >> E.continue go
314 go (E.Chunks cs) = liftIO (Sock.sendMany socket cs) >> E.continue go
311
315
312enumSocket len socket (E.Continue k) = do
316enumSocket len socket (E.Continue k) = do
317+#if NO_TIMEOUT_PROTECTION
313 bs <- liftIO $ Sock.recv socket len
318 bs <- liftIO $ Sock.recv socket len
319+ go bs
320+#else
321+ mbs <- liftIO $ timeout readTimeout $ Sock.recv socket len
322+ case mbs of
323+ Nothing -> E.throwError SocketTimeout
324+ Just bs -> go bs
325+#endif
326+ where
327+ go bs
314− if S.length bs == 0
328+ | S.length bs == 0 = E.continue k
315− then E.continue k
316− else k (E.Chunks [bs]) >>== enumSocket len socket
329+ | otherwise = k (E.Chunks [bs]) >>== enumSocket len socket
317enumSocket _ _ step = E.returnI step
330enumSocket _ _ step = E.returnI step
warp.cabal+12−1
@@ -11,18 +11,29 @@ Build-Type: Simple
11Cabal-Version: >=1.6
11Cabal-Version: >=1.6
12Stability: Stable
12Stability: Stable
13
13
14+flag timeout-protection
15+ Description: Use timeouts (very performance-costly) to protect against DOS attacks.
16+ Default: True
17+flag network-bytestring
18+
14Library
19Library
15 Build-Depends: base >= 3 && < 5
20 Build-Depends: base >= 3 && < 5
16 , bytestring >= 0.9 && < 0.10
21 , bytestring >= 0.9 && < 0.10
17 , wai >= 0.3.0 && < 0.4
22 , wai >= 0.3.0 && < 0.4
18− , network >= 2.3 && < 2.4
19 , blaze-builder-enumerator >= 0.2 && < 0.3
23 , blaze-builder-enumerator >= 0.2 && < 0.3
20 , transformers >= 0.2 && < 0.3
24 , transformers >= 0.2 && < 0.3
21 , enumerator >= 0.4 && < 0.5
25 , enumerator >= 0.4 && < 0.5
22 , blaze-builder >= 0.2.1.3 && < 0.3
26 , blaze-builder >= 0.2.1.3 && < 0.3
23 , sendfile >= 0.7.2 && < 0.8
27 , sendfile >= 0.7.2 && < 0.8
28+ if flag(network-bytestring)
29+ build-depends: network >= 2.2.1 && < 2.2.3
30+ , network-bytestring >= 0.1.3 && < 0.1.4
31+ else
32+ build-depends: network >= 2.3 && < 2.4
24 Exposed-modules: Network.Wai.Handler.Warp
33 Exposed-modules: Network.Wai.Handler.Warp
25 ghc-options: -Wall
34 ghc-options: -Wall
35+ if !flag(timeout-protection)
36+ Cpp-options: -DNO_TIMEOUT_PROTECTION
26
37
27Executable warp
38Executable warp
28 Main-is: warp.hs
39 Main-is: warp.hs