@@ -25,11 +25,11 @@ module Network.Wai.Parse
2525#endif
2626 ) where
2727
28+import qualified Data.ByteString.Search as Search
2829import qualified Data.ByteString as S
2930import qualified Data.ByteString.Lazy as L
3031import qualified Data.ByteString.Char8 as S8
3132import Data.Word (Word8)
32−import Data.Bits
3333import Data.Maybe (fromMaybe)
3434import Data.List (sortBy)
3535import Data.Function (on)
@@ -46,38 +46,11 @@ import Control.Monad (when, unless)
4646import Control.Monad.Trans.Class (lift)
4747import Control.Monad.Trans.Resource (allocate, release, register)
4848
49−uncons :: S.ByteString -> Maybe (Word8, S.ByteString)
50−uncons s
51− | S.null s = Nothing
52− | otherwise = Just (S.head s, S.tail s)
53−
5449breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
5550breakDiscard w s =
5651 let (x, y) = S.break (== w) s
5752 in (x, S.drop 1 y)
5853
59−qsDecode :: S.ByteString -> S.ByteString
60−qsDecode z = fst $ S.unfoldrN (S.length z) go z
61− where
62− go bs =
63− case uncons bs of
64− Nothing -> Nothing
65− Just (43, ws) -> Just (32, ws) -- plus to space
66− Just (37, ws) -> Just $ fromMaybe (37, ws) $ do -- percent
67− (x, xs) <- uncons ws
68− x' <- hexVal x
69− (y, ys) <- uncons xs
70− y' <- hexVal y
71− Just $ (combine x' y', ys)
72− Just (w, ws) -> Just (w, ws)
73− hexVal w
74− | 48 <= w && w <= 57 = Just $ w - 48 -- 0 - 9
75− | 65 <= w && w <= 70 = Just $ w - 55 -- A - F
76− | 97 <= w && w <= 102 = Just $ w - 87 -- a - f
77− | otherwise = Nothing
78− combine :: Word8 -> Word8 -> Word8
79− combine a b = shiftL a 4 .|. b
80−
8154-- | Parse the HTTP accept string to determine supported content types.
8255parseHttpAccept :: S.ByteString -> [S.ByteString]
8356parseHttpAccept = map fst
@@ -226,7 +199,7 @@ parsePieces sink bound =
226199 let iter front bs = return $ front . (:) bs
227200 (wasFound, front) <- sinkTillBound bound iter seed
228201 let bs = S.concat $ front []
229− let x' = (name, qsDecode bs)
202+ let x' = (name, bs)
230203 yield $ Left x'
231204 when wasFound loop
232205 _ -> do
@@ -248,8 +221,14 @@ data Bound = FoundBound S.ByteString S.ByteString
248221 deriving (Eq, Show)
249222
250223findBound :: S.ByteString -> S.ByteString -> Bound
251−findBound b bs = go [0..S.length bs - 1]
224+findBound b bs = handleBreak $ Search.breakOn b bs
252225 where
226+ handleBreak (h, t)
227+ | S.null t = go [lowBound..S.length bs - 1]
228+ | otherwise = FoundBound h $ S.drop (S.length b) t
229+
230+ lowBound = max 0 $ S.length bs - S.length b
231+
253232 go [] = NoBound
254233 go (i:is)
255234 | mismatch [0..S.length b - 1] [i..S.length bs - 1] = go is