@@ -25,11 +25,11 @@ module Network.Wai.Parse
28+import qualified Data.ByteString.Search as Search
28import qualified Data.ByteString as S
29import qualified Data.ByteString as S
29import qualified Data.ByteString.Lazy as L
30import qualified Data.ByteString.Lazy as L
30import qualified Data.ByteString.Char8 as S8
31import qualified Data.ByteString.Char8 as S8
31import Data.Word (Word8)
32import Data.Word (Word8)
33import Data.Maybe (fromMaybe)
33import Data.Maybe (fromMaybe)
34import Data.List (sortBy)
34import Data.List (sortBy)
35import Data.Function (on)
35import Data.Function (on)
@@ -46,38 +46,11 @@ import Control.Monad (when, unless)
46import Control.Monad.Trans.Class (lift)
46import Control.Monad.Trans.Class (lift)
47import Control.Monad.Trans.Resource (allocate, release, register)
47import Control.Monad.Trans.Resource (allocate, release, register)
49−uncons :: S.ByteString -> Maybe (Word8, S.ByteString)
52− | otherwise = Just (S.head s, S.tail s)
54breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
49breakDiscard :: Word8 -> S.ByteString -> (S.ByteString, S.ByteString)
55breakDiscard w s =
50breakDiscard w s =
56 let (x, y) = S.break (== w) s
51 let (x, y) = S.break (== w) s
57 in (x, S.drop 1 y)
52 in (x, S.drop 1 y)
59−qsDecode :: S.ByteString -> S.ByteString
60−qsDecode z = fst $ S.unfoldrN (S.length z) go z
65− Just (43, ws) -> Just (32, ws) -- plus to space
66− Just (37, ws) -> Just $ fromMaybe (37, ws) $ do -- percent
71− Just $ (combine x' y', ys)
72− Just (w, ws) -> Just (w, ws)
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
81-- | Parse the HTTP accept string to determine supported content types.
54-- | Parse the HTTP accept string to determine supported content types.
82parseHttpAccept :: S.ByteString -> [S.ByteString]
55parseHttpAccept :: S.ByteString -> [S.ByteString]
83parseHttpAccept = map fst
56parseHttpAccept = map fst
@@ -226,7 +199,7 @@ parsePieces sink bound =
226 let iter front bs = return $ front . (:) bs
199 let iter front bs = return $ front . (:) bs
227 (wasFound, front) <- sinkTillBound bound iter seed
200 (wasFound, front) <- sinkTillBound bound iter seed
228 let bs = S.concat $ front []
201 let bs = S.concat $ front []
229− let x' = (name, qsDecode bs)
202+ let x' = (name, bs)
230 yield $ Left x'
203 yield $ Left x'
231 when wasFound loop
204 when wasFound loop
@@ -248,8 +221,14 @@ data Bound = FoundBound S.ByteString S.ByteString
248 deriving (Eq, Show)
221 deriving (Eq, Show)
250findBound :: S.ByteString -> S.ByteString -> Bound
223findBound :: S.ByteString -> S.ByteString -> Bound
251−findBound b bs = go [0..S.length bs - 1]
224+findBound b bs = handleBreak $ Search.breakOn b bs
227+ | S.null t = go [lowBound..S.length bs - 1]
228+ | otherwise = FoundBound h $ S.drop (S.length b) t
230+ lowBound = max 0 $ S.length bs - S.length b
253 go [] = NoBound
232 go [] = NoBound
254 go (i:is)
233 go (i:is)
255 | mismatch [0..S.length b - 1] [i..S.length bs - 1] = go is
234 | mismatch [0..S.length b - 1] [i..S.length bs - 1] = go is