@@ -181,10 +181,11 @@ parseRequest port remoteHost' = do
181 parseRequest' port headers' remoteHost'
181 parseRequest' port headers' remoteHost'
183-- FIXME come up with good values here
183-- FIXME come up with good values here
184−maxHeaders, maxHeaderLength, bytesPerRead :: Int
184+maxHeaders, maxHeaderLength, bytesPerRead, maxTotalHeaderLength :: Int
185maxHeaders = 30
185maxHeaders = 30
186maxHeaderLength = 1024
186maxHeaderLength = 1024
187bytesPerRead = 4096
187bytesPerRead = 4096
188+maxTotalHeaderLength = 50 * 1024
189sendFileCount :: Integer
190sendFileCount :: Integer
190sendFileCount = 65536
191sendFileCount = 65536
@@ -398,9 +399,6 @@ enumSocket th len socket =
398------ The functions below are not warp-specific and could be split out into a
399------ The functions below are not warp-specific and could be split out into a
399--separate package.
400--separate package.
401−takeHeaders :: E.Iteratee ByteString IO [ByteString]
402−takeHeaders = takeUntilBlank 0 id
404takeUntilBlank :: Int
402takeUntilBlank :: Int
405 -> ([ByteString] -> [ByteString])
403 -> ([ByteString] -> [ByteString])
406 -> E.Iteratee S.ByteString IO [ByteString]
404 -> E.Iteratee S.ByteString IO [ByteString]
@@ -464,3 +462,69 @@ defaultSettings = Settings
465 go :: InvalidRequest -> IO ()
463 go :: InvalidRequest -> IO ()
466 go _ = return ()
464 go _ = return ()
468+ takeHeaders' 0 id id x
470+{-# INLINE takeHeaders #-}
473+ -> ([ByteString] -> [ByteString])
474+ -> ([ByteString] -> [ByteString])
476+ -> E.Iteratee S.ByteString IO [ByteString]
477+takeHeaders' !len _ _ _ | len > maxTotalHeaderLength = E.throwError OverLargeHeader
478+takeHeaders' !len !lines !prepend !bs = do
479+ let !bsLen = {-# SCC "takeHeaders'.bsLen" #-} S.length bs
480+ !mnl = {-# SCC "takeHeaders'.mnl" #-} S.elemIndex 10 bs
482+ -- no newline. prepend entire bs to next line
483+ !Nothing -> {-# SCC "takeHeaders'.noNewline" #-} do
484+ let !len' = len + bsLen
486+ takeHeaders' len' lines (prepend . (:) bs) more
487+ Just !nl -> {-# SCC "takeHeaders'.newline" #-} do
490+ !line = {-# SCC "takeHeaders'.line" #-}
492+ -- line data included in this chunk
493+ then S.concat $! prepend [SU.unsafeTake (checkCR bs end) bs]
494+ --then S.concat $! prepend [SU.unsafeTake (end-1) bs]
495+ -- no line data in this chunk (all in prepend, or empty line)
496+ else S.concat $! prepend []
499+ then {-# SCC "takeHeaders'.noMoreHeaders" #-} do
500+ let !lines' = {-# SCC "takeHeaders'.noMoreHeaders.lines'" #-} lines []
502+ then {-# SCC "takeHeaders'.noMoreHeaders.yield" #-} do
503+ let !rest = {-# SCC "takeHeaders'.noMoreHeaders.yield.rest" #-} SU.unsafeDrop start bs
504+ E.yield lines' $! E.Chunks [rest]
508+ else {-# SCC "takeHeaders'.moreHeaders" #-} do
509+ let !len' = len + start
510+ !lines' = {-# SCC "takeHeaders.lines'" #-} lines . (:) line
511+ !more <- {-# SCC "takeHeaders'.more" #-}
513+ then return $! SU.unsafeDrop start bs
515+ {-# SCC "takeHeaders'.takeMore" #-} takeHeaders' len' lines' id more
516+{-# INLINE takeHeaders' #-}
521+ !Nothing -> E.throwError IncompleteHeaders
523+{-# INLINE forceHead #-}
527+ in if '\r' == B.index bs p
530+{-# INLINE checkCR #-}