@@ -58,6 +58,7 @@ module Network.Wai.Handler.Warp
5858 , T.initialize
5959#if TEST
6060 , takeHeaders
61+ , parseFirst
6162 , readInt
6263#endif
6364 ) where
@@ -487,7 +488,7 @@ takeUntil c bs =
487488parseFirst :: ByteString
488489 -> ResourceT IO (ByteString, ByteString, ByteString, H.HttpVersion)
489490parseFirst s =
490− case S.split 32 s of -- ' '
491+ case filter (not . S.null) $ S.split 32 s of -- ' '
491492 [method, query, http'] -> do
492493 let (hfirst, hsecond) = B.splitAt 5 http'
493494 if hfirst == "HTTP/"
@@ -649,11 +650,7 @@ fmap2 _ (C.Done i x) = C.Done i x
649650parseHeaderNoAttr :: ByteString -> H.Header
650651parseHeaderNoAttr s =
651652 let (k, rest) = S.breakByte 58 s -- ':'
652− restLen = S.length rest
653− -- FIXME check for colon without following space?
654− rest' = if restLen > 1 && SU.unsafeTake 2 rest == ": "
655− then SU.unsafeDrop 2 rest
656− else rest
653+ rest' = S.dropWhile (\c -> c == 32 || c == 9) $ S.drop 1 rest
657654 in (CI.mk k, rest')
658655
659656connSource :: Connection -> T.Handle -> C.Source (ResourceT IO) ByteString
@@ -756,8 +753,15 @@ takeHeaders =
756753 prepend' = prepend . S.append bs
757754 status = THStatus len' lines prepend'
758755 in C.NeedInput (push status) close
756+ -- Found a newline, but next line continues as a multiline header
757+ Just (end, True) ->
758+ let rest = S.drop (end + 1) bs
759+ prepend' = prepend . S.append (SU.unsafeTake (checkCR bs end) bs)
760+ len' = len + end
761+ status = THStatus len' lines prepend'
762+ in push status rest
759763 -- Found a newline at position end.
760− Just end ->
764+ Just (end, False) ->
761765 let start = end + 1 -- start of next chunk
762766 line
763767 -- There were some bytes before the newline, get them
@@ -786,7 +790,15 @@ takeHeaders =
786790 else C.NeedInput (push status) close
787791 where
788792 bsLen = S.length bs
789− mnl = S.elemIndex 10 bs
793+ mnl = do
794+ nl <- S.elemIndex 10 bs
795+ -- check if there are two more bytes in the bs
796+ -- if so, see if the second of those is a horizontal space
797+ if bsLen > nl + 1
798+ then
799+ let c = S.index bs (nl + 1)
800+ in Just (nl, c == 32 || c == 9)
801+ else Just (nl, False)
790802{-# INLINE takeHeaders #-}
791803
792804checkCR :: ByteString -> Int -> Int