packages feed

warp 3.3.7 → 3.3.8

raw patch · 7 files changed

+44/−27 lines, 7 files

Files

ChangeLog.md view
@@ -1,3 +1,9 @@+## 3.3.8++* Maximum header size is configurable.+  [#781](https://github.com/yesodweb/wai/pull/781)+* Ignoring an exception from shutdown (gracefulClose).+ ## 3.3.7  * InvalidArgument (Bad file descriptor) is ignored in `receive`.
Network/Wai/Handler/Warp.hs view
@@ -74,6 +74,7 @@   , setGracefulShutdownTimeout   , setGracefulCloseTimeout1   , setGracefulCloseTimeout2+  , setMaxTotalHeaderLength     -- ** Getters   , getPort   , getHost@@ -123,7 +124,7 @@   , defaultPushPromise   ) where -import Control.Exception (SomeException, throwIO, throw)+import Control.Exception (SomeException, throwIO) import Data.Streaming.Network (HostPreference) import qualified Data.Vault.Lazy as Vault import Data.X509@@ -435,6 +436,13 @@ setGracefulShutdownTimeout :: Maybe Int                            -> Settings -> Settings setGracefulShutdownTimeout time y = y { settingsGracefulShutdownTimeout = time }++-- | Set the maximum header size that Warp will tolerate when using HTTP/1.x.+--+-- Since 3.3.8+setMaxTotalHeaderLength :: Int -> Settings -> Settings+setMaxTotalHeaderLength maxTotalHeaderLength settings = settings+  { settingsMaxTotalHeaderLength = maxTotalHeaderLength }  -- | Explicitly pause the slowloris timeout. --
Network/Wai/Handler/Warp/Request.hs view
@@ -38,13 +38,7 @@ import Network.Wai.Handler.Warp.Imports hiding (readInt, lines) import Network.Wai.Handler.Warp.ReadInt import Network.Wai.Handler.Warp.RequestHeader-import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath)---------------------------------------------------------------------- FIXME come up with good values here-maxTotalHeaderLength :: Int-maxTotalHeaderLength = 50 * 1024+import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath, settingsMaxTotalHeaderLength)  ---------------------------------------------------------------- @@ -68,7 +62,7 @@             -- Body producing action used for flushing the request body  recvRequest firstRequest settings conn ii th addr src transport = do-    hdrlines <- headerLines firstRequest src+    hdrlines <- headerLines (settingsMaxTotalHeaderLength settings) firstRequest src     (method, unparsedPath, path, query, httpversion, hdr) <- parseHeaderLines hdrlines     let idxhdr = indexRequestHeader hdr         expect = idxhdr ! fromEnum ReqExpect@@ -107,8 +101,8 @@  ---------------------------------------------------------------- -headerLines :: Bool -> Source -> IO [ByteString]-headerLines firstRequest src = do+headerLines :: Int -> Bool -> Source -> IO [ByteString]+headerLines maxTotalHeaderLength firstRequest src = do     bs <- readSource src     if S.null bs         -- When we're working on a keep-alive connection and trying to@@ -116,7 +110,7 @@         -- lack of data as a real exception. See the http1 function in         -- the Run module for more details.         then if firstRequest then throwIO ConnectionClosedByPeer else throwIO NoKeepAliveRequest-        else push src (THStatus 0 id id) bs+        else push maxTotalHeaderLength src (THStatus 0 id id) bs  data NoKeepAliveRequest = NoKeepAliveRequest     deriving (Show, Typeable)@@ -226,8 +220,8 @@ close = throwIO IncompleteHeaders -} -push :: Source -> THStatus -> ByteString -> IO [ByteString]-push src (THStatus len lines prepend) bs'+push :: Int -> Source -> THStatus -> ByteString -> IO [ByteString]+push maxTotalHeaderLength src (THStatus len lines prepend) bs'         -- Too many bytes         | len > maxTotalHeaderLength = throwIO OverLargeHeader         | otherwise = push' mnl@@ -255,13 +249,13 @@     push' Nothing = do         bst <- readSource' src         when (S.null bst) $ throwIO IncompleteHeaders-        push src status bst+        push maxTotalHeaderLength src status bst       where         len' = len + bsLen         prepend' = S.append bs         status = THStatus len' lines prepend'     -- Found a newline, but next line continues as a multiline header-    push' (Just (end, True)) = push src status rest+    push' (Just (end, True)) = push maxTotalHeaderLength src status rest       where         rest = S.drop (end + 1) bs         prepend' = S.append (SU.unsafeTake (checkCR bs end) bs)@@ -280,12 +274,12 @@                       in if start < bsLen then                              -- more bytes in this chunk, push again                              let bs'' = SU.unsafeDrop start bs-                              in push src status bs''+                              in push maxTotalHeaderLength src status bs''                            else do                              -- no more bytes in this chunk, ask for more                              bst <- readSource' src                              when (S.null bs) $ throwIO IncompleteHeaders-                             push src status bst+                             push maxTotalHeaderLength src status bst       where         start = end + 1 -- start of next chunk         line = SU.unsafeTake (checkCR bs end) bs
Network/Wai/Handler/Warp/Run.hs view
@@ -76,7 +76,7 @@             if tm == 0 then                 close s               else-                gracefulClose s tm+                gracefulClose s tm `E.catch` \(E.SomeException _) -> return () #else       , connClose = close s #endif
Network/Wai/Handler/Warp/Settings.hs view
@@ -128,6 +128,10 @@       -- Default: 2000.       --       -- Since 3.3.5+    , settingsMaxTotalHeaderLength :: Int+      -- ^ Determines the maximum header size that Warp will tolerate when using HTTP/1.x.+      -- +      -- Since 3.3.8     }  -- | Specify usage of the PROXY protocol.@@ -166,6 +170,7 @@     , settingsGracefulShutdownTimeout = Nothing     , settingsGracefulCloseTimeout1 = 0     , settingsGracefulCloseTimeout2 = 2000+    , settingsMaxTotalHeaderLength = 50 * 1024     }  -- | Apply the logic provided by 'defaultOnException' to determine if an
test/RequestSpec.hs view
@@ -7,6 +7,7 @@ import Network.Wai.Handler.Warp.File (parseByteRanges) import Network.Wai.Handler.Warp.Request import Network.Wai.Handler.Warp.Types+import Network.Wai.Handler.Warp.Settings (settingsMaxTotalHeaderLength, defaultSettings) import Test.Hspec import Test.Hspec.QuickCheck import qualified Data.ByteString as S@@ -17,6 +18,9 @@ main :: IO () main = hspec spec +defaultMaxTotalHeaderLength :: Int+defaultMaxTotalHeaderLength = settingsMaxTotalHeaderLength defaultSettings+ spec :: Spec spec = do   describe "headerLines" $ do@@ -63,29 +67,29 @@   describe "headerLines" $ do       it "can handle a nomarl case" $ do           src <- mkSourceFunc ["Status: 200\r\nContent-Type: text/plain\r\n\r\n"] >>= mkSource-          x <- headerLines True src+          x <- headerLines defaultMaxTotalHeaderLength True src           x `shouldBe` ["Status: 200", "Content-Type: text/plain"]        it "can handle a nasty case (1)" $ do           src <- mkSourceFunc ["Status: 200", "\r\nContent-Type: text/plain", "\r\n\r\n"] >>= mkSource-          x <- headerLines True src+          x <- headerLines defaultMaxTotalHeaderLength True src           x `shouldBe` ["Status: 200", "Content-Type: text/plain"]        it "can handle a nasty case (1)" $ do           src <- mkSourceFunc ["Status: 200", "\r", "\nContent-Type: text/plain", "\r", "\n\r\n"] >>= mkSource-          x <- headerLines True src+          x <- headerLines defaultMaxTotalHeaderLength True src           x `shouldBe` ["Status: 200", "Content-Type: text/plain"]        it "can handle a nasty case (1)" $ do           src <- mkSourceFunc ["Status: 200", "\r", "\n", "Content-Type: text/plain", "\r", "\n", "\r", "\n"] >>= mkSource-          x <- headerLines True src+          x <- headerLines defaultMaxTotalHeaderLength True src           x `shouldBe` ["Status: 200", "Content-Type: text/plain"]        it "can handle an illegal case (1)" $ do           src <- mkSourceFunc ["\nStatus:", "\n 200", "\nContent-Type: text/plain", "\r\n\r\n"] >>= mkSource-          x <- headerLines True src+          x <- headerLines defaultMaxTotalHeaderLength True src           x `shouldBe` []-          y <- headerLines True src+          y <- headerLines defaultMaxTotalHeaderLength True src           y `shouldBe` ["Status: 200", "Content-Type: text/plain"]    where@@ -111,7 +115,7 @@                     writeIORef ref z                     return y     src' <- mkSource src-    res <- headerLines True src'+    res <- headerLines defaultMaxTotalHeaderLength True src'     return (res, src')  consumeLen :: Int -> Source -> IO S8.ByteString
warp.cabal view
@@ -1,5 +1,5 @@ Name:                warp-Version:             3.3.7+Version:             3.3.8 Synopsis:            A fast, light-weight web server for WAI applications. License:             MIT License-file:        LICENSE