@@ -1,6 +1,7 @@
1{-# LANGUAGE DeriveDataTypeable #-}
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
4---------------------------------------------------------
5---------------------------------------------------------
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)
60import Control.Monad.IO.Class (liftIO)
61import Control.Monad.IO.Class (liftIO)
62+import System.Timeout (timeout)
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'
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
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
149 deriving (Show, Typeable)
153 deriving (Show, Typeable)
150instance Exception InvalidRequest
154instance Exception InvalidRequest
@@ -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
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
321+ mbs <- liftIO $ timeout readTimeout $ Sock.recv socket len
323+ Nothing -> E.throwError SocketTimeout
314− if S.length bs == 0
328+ | S.length bs == 0 = 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