@@ -58,6 +58,7 @@ module Network.Wai.Handler.Warp
58 , T.initialize
58 , T.initialize
60 , takeHeaders
60 , takeHeaders
@@ -487,7 +488,7 @@ takeUntil c bs =
487parseFirst :: ByteString
488parseFirst :: ByteString
488 -> ResourceT IO (ByteString, ByteString, ByteString, H.HttpVersion)
489 -> ResourceT IO (ByteString, ByteString, ByteString, H.HttpVersion)
489parseFirst s =
490parseFirst s =
490− case S.split 32 s of -- ' '
491+ case filter (not . S.null) $ S.split 32 s of -- ' '
491 [method, query, http'] -> do
492 [method, query, http'] -> do
492 let (hfirst, hsecond) = B.splitAt 5 http'
493 let (hfirst, hsecond) = B.splitAt 5 http'
493 if hfirst == "HTTP/"
494 if hfirst == "HTTP/"
@@ -649,11 +650,7 @@ fmap2 _ (C.Done i x) = C.Done i x
649parseHeaderNoAttr :: ByteString -> H.Header
650parseHeaderNoAttr :: ByteString -> H.Header
650parseHeaderNoAttr s =
651parseHeaderNoAttr s =
651 let (k, rest) = S.breakByte 58 s -- ':'
652 let (k, rest) = S.breakByte 58 s -- ':'
652− restLen = S.length rest
653+ rest' = S.dropWhile (\c -> c == 32 || c == 9) $ S.drop 1 rest
653− -- FIXME check for colon without following space?
654− rest' = if restLen > 1 && SU.unsafeTake 2 rest == ": "
655− then SU.unsafeDrop 2 rest
657 in (CI.mk k, rest')
654 in (CI.mk k, rest')
659connSource :: Connection -> T.Handle -> C.Source (ResourceT IO) ByteString
656connSource :: Connection -> T.Handle -> C.Source (ResourceT IO) ByteString
@@ -756,8 +753,15 @@ takeHeaders =
756 prepend' = prepend . S.append bs
753 prepend' = prepend . S.append bs
757 status = THStatus len' lines prepend'
754 status = THStatus len' lines prepend'
758 in C.NeedInput (push status) close
755 in C.NeedInput (push status) close
756+ -- Found a newline, but next line continues as a multiline header
758+ let rest = S.drop (end + 1) bs
759+ prepend' = prepend . S.append (SU.unsafeTake (checkCR bs end) bs)
761+ status = THStatus len' lines prepend'
759 -- Found a newline at position end.
763 -- Found a newline at position end.
760− Just end ->
764+ Just (end, False) ->
761 let start = end + 1 -- start of next chunk
765 let start = end + 1 -- start of next chunk
763 -- There were some bytes before the newline, get them
767 -- There were some bytes before the newline, get them
@@ -786,7 +790,15 @@ takeHeaders =
786 else C.NeedInput (push status) close
790 else C.NeedInput (push status) close
788 bsLen = S.length bs
792 bsLen = S.length bs
789− mnl = S.elemIndex 10 bs
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
799+ let c = S.index bs (nl + 1)
800+ in Just (nl, c == 32 || c == 9)
801+ else Just (nl, False)
790{-# INLINE takeHeaders #-}
802{-# INLINE takeHeaders #-}
792checkCR :: ByteString -> Int -> Int
804checkCR :: ByteString -> Int -> Int