git.iko.soy/typeable/http-api-data
on master help sign in
Use uri-bytestring for a more efficient url-encoding and decoding
commitea020ae86c95e51b830e6a9841a4b0d516ea8e64 authorNickolay Kudasov <nickolay.kudasov@gmail.com> dateTue 30 Aug 2016, 17:05 (10 years ago) parent02fadd3
2 files changed+13−13
http-api-data.cabal+1−1 src/Web/Internal/FormUrlEncoded.hs+12−12
http-api-data.cabal+1−1
@@ -26,11 +26,11 @@ library
2626 , bytestring
2727 , containers
2828 , hashable
29− , network-uri >= 2.6 && < 2.7
3029 , text >= 0.5
3130 , time
3231 , time-locale-compat >=0.1.1.0 && <0.2
3332 , unordered-containers
33+ , uri-bytestring
3434 if flag(use-text-show)
3535 cpp-options: -DUSE_TEXT_SHOW
3636 build-depends: text-show >= 2
src/Web/Internal/FormUrlEncoded.hs+12−12
@@ -19,6 +19,7 @@ import Data.Traversable
1919
2020import Control.Arrow ((***))
2121import Control.Monad ((<=<))
22+import Data.ByteString.Builder (toLazyByteString, shortByteString)
2223import qualified Data.ByteString.Lazy as BSL
2324import qualified Data.ByteString.Lazy.Char8 as BSL8
2425import qualified Data.Foldable as F
@@ -28,6 +29,7 @@ import qualified Data.HashMap.Strict as HashMap
2829import Data.Int
2930import Data.IntMap (IntMap)
3031import qualified Data.IntMap as IntMap
32+import Data.List (intersperse)
3133import Data.Map (Map)
3234import qualified Data.Map as Map
3335import Data.Monoid
@@ -43,8 +45,7 @@ import Data.Word
4345
4446import GHC.Exts (IsList (..))
4547import GHC.Generics
46−import Network.URI (escapeURIString, isUnreserved,
47− unEscapeString)
48+import URI.ByteString (urlEncodeQuery, urlDecodeQuery)
4849
4950import Web.Internal.HttpApiData
5051
@@ -366,12 +367,12 @@ instance (GFromForm f) => GFromForm (M1 C x f) where
366367-- >>> urlEncodeForm [("fullname", "Andres Löh")]
367368-- "fullname=Andres%20L%C3%B6h"
368369urlEncodeForm :: Form -> BSL.ByteString
369−urlEncodeForm xs = BSL.intercalate "&" $ map (BSL.fromStrict . encodePair) $ toList xs
370+urlEncodeForm = toLazyByteString . mconcat . intersperse (shortByteString "&") . map encodePair . toList
370371 where
371− escape = Text.encodeUtf8 . Text.pack . escapeURIString isUnreserved . Text.unpack
372+ escape = urlEncodeQuery . Text.encodeUtf8
372373
373374 encodePair (k, "") = escape k
374− encodePair (k, v) = escape k <> "=" <> escape v
375+ encodePair (k, v) = escape k <> shortByteString "=" <> escape v
375376
376377
377378-- | 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
408409urlDecodeForm :: BSL.ByteString -> Either Text Form
409410urlDecodeForm bs = toForm <$> traverse parsePair pairs
410411 where
411− pairs = map (Text.decodeUtf8With lenientDecode . BSL.toStrict) (BSL8.split '&' bs)
412+ pairs = map (BSL8.split '=') (BSL8.split '&' bs)
412413
413− unescape = Text.pack . unEscapeString . Text.unpack . Text.replace "+" "%20"
414+ unescape = Text.decodeUtf8With lenientDecode . urlDecodeQuery . BSL.toStrict
414415
415− parsePair :: Text -> Either Text (Text, Text)
416416 parsePair p =
417− case Text.splitOn "=" p of
418− [k, v] -> return (unescape k, unescape v)
419− [k] -> return (unescape k, "" )
420− _ -> Left $ "not a valid pair: " <> p
417+ case map unescape p of
418+ [k, v] -> return (k, v)
419+ [k] -> return (k, "")
420+ xs -> Left $ "not a valid pair: " <> Text.intercalate "=" xs
421421
422422data Proxy3 a b c = Proxy3
423423