@@ -38,13 +38,7 @@ import Network.Wai.Handler.Warp.Header
3838import Network.Wai.Handler.Warp.Imports hiding (readInt, lines)
3939import Network.Wai.Handler.Warp.ReadInt
4040import Network.Wai.Handler.Warp.RequestHeader
41−import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath)
42−
43−----------------------------------------------------------------
44−
45−-- FIXME come up with good values here
46−maxTotalHeaderLength :: Int
47−maxTotalHeaderLength = 50 * 1024
41+import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath, settingsMaxTotalHeaderLength)
4842
4943----------------------------------------------------------------
5044
@@ -68,7 +62,7 @@ recvRequest :: Bool -- ^ first request on this connection?
6862 -- Body producing action used for flushing the request body
6963
7064recvRequest firstRequest settings conn ii th addr src transport = do
71− hdrlines <- headerLines firstRequest src
65+ hdrlines <- headerLines (settingsMaxTotalHeaderLength settings) firstRequest src
7266 (method, unparsedPath, path, query, httpversion, hdr) <- parseHeaderLines hdrlines
7367 let idxhdr = indexRequestHeader hdr
7468 expect = idxhdr ! fromEnum ReqExpect
@@ -107,8 +101,8 @@ recvRequest firstRequest settings conn ii th addr src transport = do
107101
108102----------------------------------------------------------------
109103
110−headerLines :: Bool -> Source -> IO [ByteString]
111−headerLines firstRequest src = do
104+headerLines :: Int -> Bool -> Source -> IO [ByteString]
105+headerLines maxTotalHeaderLength firstRequest src = do
112106 bs <- readSource src
113107 if S.null bs
114108 -- When we're working on a keep-alive connection and trying to
@@ -116,7 +110,7 @@ headerLines firstRequest src = do
116110 -- lack of data as a real exception. See the http1 function in
117111 -- the Run module for more details.
118112 then if firstRequest then throwIO ConnectionClosedByPeer else throwIO NoKeepAliveRequest
119− else push src (THStatus 0 id id) bs
113+ else push maxTotalHeaderLength src (THStatus 0 id id) bs
120114
121115data NoKeepAliveRequest = NoKeepAliveRequest
122116 deriving (Show, Typeable)
@@ -226,8 +220,8 @@ close :: Sink ByteString IO a
226220close = throwIO IncompleteHeaders
227221-}
228222
229−push :: Source -> THStatus -> ByteString -> IO [ByteString]
230−push src (THStatus len lines prepend) bs'
223+push :: Int -> Source -> THStatus -> ByteString -> IO [ByteString]
224+push maxTotalHeaderLength src (THStatus len lines prepend) bs'
231225 -- Too many bytes
232226 | len > maxTotalHeaderLength = throwIO OverLargeHeader
233227 | otherwise = push' mnl
@@ -255,13 +249,13 @@ push src (THStatus len lines prepend) bs'
255249 push' Nothing = do
256250 bst <- readSource' src
257251 when (S.null bst) $ throwIO IncompleteHeaders
258− push src status bst
252+ push maxTotalHeaderLength src status bst
259253 where
260254 len' = len + bsLen
261255 prepend' = S.append bs
262256 status = THStatus len' lines prepend'
263257 -- Found a newline, but next line continues as a multiline header
264− push' (Just (end, True)) = push src status rest
258+ push' (Just (end, True)) = push maxTotalHeaderLength src status rest
265259 where
266260 rest = S.drop (end + 1) bs
267261 prepend' = S.append (SU.unsafeTake (checkCR bs end) bs)
@@ -280,12 +274,12 @@ push src (THStatus len lines prepend) bs'
280274 in if start < bsLen then
281275 -- more bytes in this chunk, push again
282276 let bs'' = SU.unsafeDrop start bs
283− in push src status bs''
277+ in push maxTotalHeaderLength src status bs''
284278 else do
285279 -- no more bytes in this chunk, ask for more
286280 bst <- readSource' src
287281 when (S.null bs) $ throwIO IncompleteHeaders
288− push src status bst
282+ push maxTotalHeaderLength src status bst
289283 where
290284 start = end + 1 -- start of next chunk
291285 line = SU.unsafeTake (checkCR bs end) bs