git.iko.soy/typeable/http-api-data
on master help sign in
Use uri-bytestring for a more efficient url-encoding and decoding
ea020aeNickolay Kudasov
http-api-data.cabal+1−1
@@ -26,11 +26,11 @@ library
26 , bytestring
26 , bytestring
27 , containers
27 , containers
28 , hashable
28 , hashable
29− , network-uri >= 2.6 && < 2.7
30 , text >= 0.5
29 , text >= 0.5
31 , time
30 , time
32 , time-locale-compat >=0.1.1.0 && <0.2
31 , time-locale-compat >=0.1.1.0 && <0.2
33 , unordered-containers
32 , unordered-containers
33+ , uri-bytestring
34 if flag(use-text-show)
34 if flag(use-text-show)
35 cpp-options: -DUSE_TEXT_SHOW
35 cpp-options: -DUSE_TEXT_SHOW
36 build-depends: text-show >= 2
36 build-depends: text-show >= 2
src/Web/Internal/FormUrlEncoded.hs+12−12
@@ -19,6 +19,7 @@ import Data.Traversable
19
19
20import Control.Arrow ((***))
20import Control.Arrow ((***))
21import Control.Monad ((<=<))
21import Control.Monad ((<=<))
22+import Data.ByteString.Builder (toLazyByteString, shortByteString)
22import qualified Data.ByteString.Lazy as BSL
23import qualified Data.ByteString.Lazy as BSL
23import qualified Data.ByteString.Lazy.Char8 as BSL8
24import qualified Data.ByteString.Lazy.Char8 as BSL8
24import qualified Data.Foldable as F
25import qualified Data.Foldable as F
@@ -28,6 +29,7 @@ import qualified Data.HashMap.Strict as HashMap
28import Data.Int
29import Data.Int
29import Data.IntMap (IntMap)
30import Data.IntMap (IntMap)
30import qualified Data.IntMap as IntMap
31import qualified Data.IntMap as IntMap
32+import Data.List (intersperse)
31import Data.Map (Map)
33import Data.Map (Map)
32import qualified Data.Map as Map
34import qualified Data.Map as Map
33import Data.Monoid
35import Data.Monoid
@@ -43,8 +45,7 @@ import Data.Word
43
45
44import GHC.Exts (IsList (..))
46import GHC.Exts (IsList (..))
45import GHC.Generics
47import GHC.Generics
46−import Network.URI (escapeURIString, isUnreserved,
48+import URI.ByteString (urlEncodeQuery, urlDecodeQuery)
47− unEscapeString)
48
49
49import Web.Internal.HttpApiData
50import Web.Internal.HttpApiData
50
51
@@ -366,12 +367,12 @@ instance (GFromForm f) => GFromForm (M1 C x f) where
366-- >>> urlEncodeForm [("fullname", "Andres Löh")]
367-- >>> urlEncodeForm [("fullname", "Andres Löh")]
367-- "fullname=Andres%20L%C3%B6h"
368-- "fullname=Andres%20L%C3%B6h"
368urlEncodeForm :: Form -> BSL.ByteString
369urlEncodeForm :: Form -> BSL.ByteString
369−urlEncodeForm xs = BSL.intercalate "&" $ map (BSL.fromStrict . encodePair) $ toList xs
370+urlEncodeForm = toLazyByteString . mconcat . intersperse (shortByteString "&") . map encodePair . toList
370 where
371 where
371− escape = Text.encodeUtf8 . Text.pack . escapeURIString isUnreserved . Text.unpack
372+ escape = urlEncodeQuery . Text.encodeUtf8
372
373
373 encodePair (k, "") = escape k
374 encodePair (k, "") = escape k
374− encodePair (k, v) = escape k <> "=" <> escape v
375+ encodePair (k, v) = escape k <> shortByteString "=" <> escape v
375
376
376
377
377-- | Decode an @application/x-www-form-urlencoded@ 'BSL.ByteString' to a 'Form'.
378-- | Decode an @application/x-www-form-urlencoded@ 'BSL.ByteString' to a 'Form'.
@@ -408,16 +409,15 @@ urlEncodeForm xs = BSL.intercalate "&" $ map (BSL.fromStrict . encodePair) $ toL
408urlDecodeForm :: BSL.ByteString -> Either Text Form
409urlDecodeForm :: BSL.ByteString -> Either Text Form
409urlDecodeForm bs = toForm <$> traverse parsePair pairs
410urlDecodeForm bs = toForm <$> traverse parsePair pairs
410 where
411 where
411− pairs = map (Text.decodeUtf8With lenientDecode . BSL.toStrict) (BSL8.split '&' bs)
412+ pairs = map (BSL8.split '=') (BSL8.split '&' bs)
412
413
413− unescape = Text.pack . unEscapeString . Text.unpack . Text.replace "+" "%20"
414+ unescape = Text.decodeUtf8With lenientDecode . urlDecodeQuery . BSL.toStrict
414
415
415− parsePair :: Text -> Either Text (Text, Text)
416 parsePair p =
416 parsePair p =
417− case Text.splitOn "=" p of
417+ case map unescape p of
418− [k, v] -> return (unescape k, unescape v)
418+ [k, v] -> return (k, v)
419− [k] -> return (unescape k, "" )
419+ [k] -> return (k, "")
420− _ -> Left $ "not a valid pair: " <> p
420+ xs -> Left $ "not a valid pair: " <> Text.intercalate "=" xs
421
421
422data Proxy3 a b c = Proxy3
422data Proxy3 a b c = Proxy3
423
423