modern-uri 0.1.1.1 → 0.1.2.0
raw patch · 7 files changed
+37/−16 lines, 7 files
Files
- CHANGELOG.md +6/−0
- Text/URI/Parser/ByteString.hs +2/−1
- Text/URI/Parser/Text/Utils.hs +2/−1
- Text/URI/Render.hs +20/−8
- Text/URI/Types.hs +2/−1
- modern-uri.cabal +2/−2
- tests/Text/URISpec.hs +3/−3
CHANGELOG.md view
@@ -1,3 +1,9 @@+## Modern URI 0.1.2.0++* Fixed handling of `+` in query strings. Now `+` is parsed as space and+ serialized as `%2b` as per RFC 1866 (paragraph 8.2.1). White space in+ query parameters is serialized as `+`.+ ## Modern URI 0.1.1.1 * Fixed implementation of `Text.URI.Lens.queryParam` traversal.
Text/URI/Parser/ByteString.hs view
@@ -226,11 +226,12 @@ pchar' = choice [ unreservedChar , percentEncChar+ , char 43 >> pure 32 , oneOf s <?> "sub-delimiter" , char 58 , char 64 ] where- s = E.fromList (fromIntegral . ord <$> "!$'()*+,;")+ s = E.fromList (fromIntegral . ord <$> "!$'()*,;") {-# INLINE pchar' #-} isAsciiAlpha :: Word8 -> Bool
Text/URI/Parser/Text/Utils.hs view
@@ -151,11 +151,12 @@ pchar' = choice [ unreservedChar , percentEncChar+ , char '+' >> pure ' ' , oneOf s <?> "sub-delimiter" , char ':' , char '@' ] where- s = E.fromList "!$'()*+,;"+ s = E.fromList "!$'()*,;" {-# INLINE pchar' #-} isAsciiAlpha :: Char -> Bool
Text/URI/Render.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-}@@ -180,27 +181,35 @@ case B.uncons bs' of Nothing -> Nothing Just (w, bs'') -> Just $- if nne w- then (chr (fromIntegral w), (bs'', []))- else let c:|cs = encodeByte w- in (c, (bs'', cs))+ if | sap && w == 32 -> ('+', (bs'', []))+ | nne w -> (chr (fromIntegral w), (bs'', []))+ | otherwise ->+ let c:|cs = encodeByte w+ in (c, (bs'', cs)) f (bs', x:xs) = Just (x, (bs', xs)) encodeByte x = '%' :| [intToDigit h, intToDigit l] where (h, l) = fromIntegral x `quotRem` 16 nne = needsNoEscaping (Proxy :: Proxy l)+ sap = spaceAsPlus (Proxy :: Proxy l) txt = unRText rtxt+{-# INLINE percentEncode #-} --- | This type class attaches a predicate that tells which bytes should not--- be percent-encoded to the type level label of kind 'RTextLabel'.+-- | This type class attaches some predicates that control serialization to+-- the type level label of kind 'RTextLabel'. class RLabel (l :: RTextLabel) where - -- | The predicate selects bytes that do not to be percent-escaped in+ -- | The predicate selects bytes that are not to be percent-escaped in -- rendered URI. needsNoEscaping :: Proxy l -> Word8 -> Bool + -- | Whether to serialize space as the plus sign.++ spaceAsPlus :: Proxy l -> Bool+ spaceAsPlus Proxy = False+ -- | Whether to skip percent-escaping altogether for this value. skipEscaping :: Proxy l -> Text -> Bool@@ -226,10 +235,12 @@ instance RLabel 'QueryKey where needsNoEscaping Proxy x = isPChar isDelim' x || x == 47 || x == 63+ spaceAsPlus Proxy = True instance RLabel 'QueryValue where needsNoEscaping Proxy x = isPChar isDelim' x || x == 47 || x == 63+ spaceAsPlus Proxy = True instance RLabel 'Fragment where needsNoEscaping Proxy x =@@ -268,6 +279,7 @@ isDelim' x | x == 33 = True | x == 36 = True- | x >= 39 && x <= 44 = True+ | x >= 39 && x <= 42 = True+ | x == 44 = True | x == 59 = True | otherwise = False
Text/URI/Types.hs view
@@ -86,7 +86,8 @@ , uriPath :: [RText 'PathPiece] -- ^ Path , uriQuery :: [QueryParam]- -- ^ Query parameters+ -- ^ Query parameters, RFC 3986 does not define the inner organization+ -- of query string, so we deconstruct it following RFC 1866 here , uriFragment :: Maybe (RText 'Fragment) -- ^ Fragment, without @#@ } deriving (Show, Eq, Ord, Data, Typeable, Generic)
modern-uri.cabal view
@@ -1,7 +1,7 @@ name: modern-uri-version: 0.1.1.1+version: 0.1.2.0 cabal-version: >= 1.18-tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.1+tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2 license: BSD3 license-file: LICENSE.md author: Mark Karpov <markkarpov92@gmail.com>
tests/Text/URISpec.hs view
@@ -200,9 +200,9 @@ username <- URI.mkUsername "mark:@" password <- URI.mkPassword "secret:@" host <- URI.mkHost "github.com"- path <- mapM URI.mkPathPiece ["mrkkrp", "modern-uri:@"]+ path <- mapM URI.mkPathPiece ["mrkkrp", "modern-uri+:@"] k <- URI.mkQueryKey "foo:@"- v <- URI.mkQueryValue "bar:@"+ v <- URI.mkQueryValue "bar :@" fragment <- URI.mkFragment "fragment:@" return URI { uriScheme = Just scheme@@ -219,7 +219,7 @@ -- | Polymorphic textual rendering of the 'URI' generated by 'mkTestURI'. testURI :: IsString a => a-testURI = "https://mark%3a%40:secret:%40@github.com:443/mrkkrp/modern-uri%3a@?foo:@=bar:@#fragment:@"+testURI = "https://mark%3a%40:secret:%40@github.com:443/mrkkrp/modern-uri+%3a@?foo:@=bar+:@#fragment:@" -- | A utility wrapper around 'URI.parser'.