Compare commits

...

9 Commits

Author SHA1 Message Date
Oleg Grenrus
b57528eff2 Update changelog 2017-12-18 19:54:39 +02:00
Oleg Grenrus
2cd18a2539 Fix #835. Use Escaped to prevent double-escaping 2017-12-18 19:52:32 +02:00
Oleg Grenrus
c9f0ebb6c2 Allow hspec-wai-0.9 2017-12-18 10:32:34 +02:00
Oleg Grenrus
80230ca157
Merge pull request #877 from phadej/r0.12-http-types-0.11
release 0.12: allow http-types-0.11
2017-12-18 10:27:38 +02:00
Oleg Grenrus
3522c2acf4 release 0.12: allow http-types-0.11 2017-12-18 09:04:06 +02:00
Oleg Grenrus
e886ab83ab
Merge pull request #860 from haskell-servant/issue-858-accept-hdr
Send Accept header in servant-client
2017-11-11 00:05:11 +02:00
Oleg Grenrus
66cd8b843b Build only master and release-0.12 on travis 2017-11-10 23:29:48 +02:00
Oleg Grenrus
8574d8d2a9 Send Accept header in servant-client
Fixes #858. The bug was introduced in servant-client-core refactor
(servant-client-0.12).

See 8973cf56f1/servant-client/src/Servant/Common/Req.hs (L151-L179)
for the unbroken variant in servant-client-0.11
2017-11-10 23:28:26 +02:00
Oleg Grenrus
83aea36c14 Fix typo in changelog 2017-11-08 12:50:06 +02:00
9 changed files with 71 additions and 17 deletions

View File

@ -10,6 +10,11 @@ sudo: false
git: git:
submodules: false # whether to recursively clone submodules submodules: false # whether to recursively clone submodules
branches:
only:
- master
- release-0.12
cache: cache:
directories: directories:
- $HOME/.cabal/packages - $HOME/.cabal/packages

View File

@ -1,5 +1,6 @@
name: servant-client-core name: servant-client-core
version: 0.12 version: 0.12
x-revision: 1
synopsis: Core functionality and class for client function generation for servant APIs synopsis: Core functionality and class for client function generation for servant APIs
description: description:
This library provides backend-agnostic generation of client functions. For This library provides backend-agnostic generation of client functions. For
@ -49,7 +50,7 @@ library
, generics-sop >= 0.1.0.0 && < 0.4 , generics-sop >= 0.1.0.0 && < 0.4
, http-api-data >= 0.3.6 && < 0.4 , http-api-data >= 0.3.6 && < 0.4
, http-media >= 0.6.2 && < 0.8 , http-media >= 0.6.2 && < 0.8
, http-types >= 0.8.6 && < 0.11 , http-types >= 0.8.6 && < 0.12
, mtl >= 2.1 && < 2.3 , mtl >= 2.1 && < 2.3
, network-uri >= 2.6 && < 2.7 , network-uri >= 2.6 && < 2.7
, safe >= 0.3.9 && < 0.4 , safe >= 0.3.9 && < 0.4

View File

@ -1,6 +1,12 @@
[The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant-client/CHANGELOG.md) [The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant-client/CHANGELOG.md)
[Changelog for `servant` package contains significant entries for all core packages.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md) [Changelog for `servant` package contains significant entries for all core packages.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md)
0.12.0.1
--------
- Send `Accept` header.
([#858](https://github.com/haskell-servant/servant/issues/858))
0.12 0.12
---- ----

View File

@ -1,5 +1,6 @@
name: servant-client name: servant-client
version: 0.12 version: 0.12.0.1
x-revision: 1
synopsis: automatical derivation of querying functions for servant webservices synopsis: automatical derivation of querying functions for servant webservices
description: description:
This library lets you derive automatically Haskell functions that This library lets you derive automatically Haskell functions that
@ -45,7 +46,7 @@ library
, http-client >= 0.4.30 && < 0.6 , http-client >= 0.4.30 && < 0.6
, http-client-tls >= 0.2.2 && < 0.4 , http-client-tls >= 0.2.2 && < 0.4
, http-media >= 0.6.2 && < 0.8 , http-media >= 0.6.2 && < 0.8
, http-types >= 0.8.6 && < 0.11 , http-types >= 0.8.6 && < 0.12
, exceptions >= 0.8 && < 0.9 , exceptions >= 0.8 && < 0.9
, monad-control >= 1.0.0.4 && < 1.1 , monad-control >= 1.0.0.4 && < 1.1
, mtl >= 2.1 && < 2.3 , mtl >= 2.1 && < 2.3

View File

@ -28,6 +28,7 @@ import Data.ByteString.Builder (toLazyByteString)
import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString.Lazy as BSL
import Data.Foldable (toList) import Data.Foldable (toList)
import Data.Functor.Alt (Alt (..)) import Data.Functor.Alt (Alt (..))
import Data.Maybe (maybeToList)
import Data.Monoid ((<>)) import Data.Monoid ((<>))
import Data.Proxy (Proxy (..)) import Data.Proxy (Proxy (..))
import Data.Sequence (fromList) import Data.Sequence (fromList)
@ -133,16 +134,26 @@ requestToClientRequest burl r = Client.defaultRequest
<> toLazyByteString (requestPath r) <> toLazyByteString (requestPath r)
, Client.queryString = renderQuery True . toList $ requestQueryString r , Client.queryString = renderQuery True . toList $ requestQueryString r
, Client.requestHeaders = , Client.requestHeaders =
let orig = toList $ requestHeaders r maybeToList acceptHdr ++ maybeToList contentTypeHdr ++ headers
in maybe orig (: orig) contentTypeHdr
, Client.requestBody = body , Client.requestBody = body
, Client.secure = isSecure , Client.secure = isSecure
} }
where where
-- Content-Type and Accept are specified by requestBody and requestAccept
headers = filter (\(h, _) -> h /= "Accept" && h /= "Content-Type") $
toList $requestHeaders r
acceptHdr
| null hs = Nothing
| otherwise = Just ("Accept", renderHeader hs)
where
hs = toList $ requestAccept r
(body, contentTypeHdr) = case requestBody r of (body, contentTypeHdr) = case requestBody r of
Nothing -> (Client.RequestBodyLBS "", Nothing) Nothing -> (Client.RequestBodyLBS "", Nothing)
Just (RequestBodyLBS body', typ) Just (RequestBodyLBS body', typ)
-> (Client.RequestBodyLBS body', Just (hContentType, renderHeader typ)) -> (Client.RequestBodyLBS body', Just (hContentType, renderHeader typ))
isSecure = case baseUrlScheme burl of isSecure = case baseUrlScheme burl of
Http -> False Http -> False
Https -> True Https -> True

View File

@ -1,5 +1,6 @@
name: servant-server name: servant-server
version: 0.12 version: 0.12
x-revision: 1
synopsis: A family of combinators for defining webservices APIs and serving them synopsis: A family of combinators for defining webservices APIs and serving them
description: description:
A family of combinators for defining webservices APIs and serving them A family of combinators for defining webservices APIs and serving them
@ -64,7 +65,7 @@ library
, containers >= 0.5 && < 0.6 , containers >= 0.5 && < 0.6
, exceptions >= 0.8 && < 0.9 , exceptions >= 0.8 && < 0.9
, http-api-data >= 0.3 && < 0.4 , http-api-data >= 0.3 && < 0.4
, http-types >= 0.8 && < 0.11 , http-types >= 0.8 && < 0.12
, network-uri >= 2.6 && < 2.7 , network-uri >= 2.6 && < 2.7
, monad-control >= 1.0.0.4 && < 1.1 , monad-control >= 1.0.0.4 && < 1.1
, mtl >= 2 && < 2.3 , mtl >= 2 && < 2.3
@ -136,7 +137,7 @@ test-suite spec
, directory , directory
, exceptions , exceptions
, hspec == 2.* , hspec == 2.*
, hspec-wai >= 0.8 && <0.9 , hspec-wai >= 0.8 && <0.10
, http-types , http-types
, mtl , mtl
, network >= 2.6 , network >= 2.6

View File

@ -1,5 +1,14 @@
[The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md) [The latest version of this document is on GitHub.](https://github.com/haskell-servant/servant/blob/master/servant/CHANGELOG.md)
0.12.1
------
### Bug fixes
- Prevent double-escaping in link segments
([#835](https://github.com/haskell-servant/servant/issues/835)
[#878](https://github.com/haskell-servant/servant/pull/878))
0.12 0.12
--- ---
@ -59,7 +68,7 @@
- Lower `:>` and `:<|>` infix precedence to 4 and 3 respectively - Lower `:>` and `:<|>` infix precedence to 4 and 3 respectively
([#761](https://github.com/haskell-servant/servant/issues/761)) ([#761](https://github.com/haskell-servant/servant/issues/761))
This should affect you, except if you define your own infix operators This shouldn't affect you, except if you define your own infix operators
for Servant type-level DSL. for Servant type-level DSL.
### Other changes ### Other changes

View File

@ -1,5 +1,5 @@
name: servant name: servant
version: 0.12 version: 0.12.1
synopsis: A family of combinators for defining webservices APIs synopsis: A family of combinators for defining webservices APIs
description: description:
A family of combinators for defining webservices APIs and serving them A family of combinators for defining webservices APIs and serving them
@ -70,7 +70,7 @@ library
, case-insensitive >= 1.2 && < 1.3 , case-insensitive >= 1.2 && < 1.3
, http-api-data >= 0.3 && < 0.4 , http-api-data >= 0.3 && < 0.4
, http-media >= 0.4 && < 0.8 , http-media >= 0.4 && < 0.8
, http-types >= 0.8 && < 0.11 , http-types >= 0.8 && < 0.12
, natural-transformation >= 0.4 && < 0.5 , natural-transformation >= 0.4 && < 0.5
, mtl >= 2.0 && < 2.3 , mtl >= 2.0 && < 2.3
, mmorph >= 1 && < 1.2 , mmorph >= 1 && < 1.2

View File

@ -126,12 +126,24 @@ import Servant.API.Experimental.Auth ( AuthProtect )
-- The only way of constructing a 'Link' is using 'safeLink', which means any -- The only way of constructing a 'Link' is using 'safeLink', which means any
-- 'Link' is guaranteed to be part of the mentioned API. -- 'Link' is guaranteed to be part of the mentioned API.
data Link = Link data Link = Link
{ _segments :: [String] -- ^ Segments of "foo/bar" would be ["foo", "bar"] { _segments :: [Escaped]
, _queryParams :: [Param] , _queryParams :: [Param]
} deriving Show } deriving Show
newtype Escaped = Escaped String
escaped :: String -> Escaped
escaped = Escaped . escapeURIString isUnreserved
getEscaped :: Escaped -> String
getEscaped (Escaped s) = s
instance Show Escaped where
showsPrec d (Escaped s) = showsPrec d s
show (Escaped s) = show s
linkSegments :: Link -> [String] linkSegments :: Link -> [String]
linkSegments = _segments linkSegments = map getEscaped . _segments
linkQueryParams :: Link -> [Param] linkQueryParams :: Link -> [Param]
linkQueryParams = _queryParams linkQueryParams = _queryParams
@ -149,7 +161,7 @@ data Param
| FlagParam String | FlagParam String
deriving Show deriving Show
addSegment :: String -> Link -> Link addSegment :: Escaped -> Link -> Link
addSegment seg l = l { _segments = _segments l <> [seg] } addSegment seg l = l { _segments = _segments l <> [seg] }
addQueryParam :: Param -> Link -> Link addQueryParam :: Param -> Link -> Link
@ -170,6 +182,14 @@ addQueryParam qp l =
-- >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) -- >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
-- foo%2Fbar -- foo%2Fbar
-- --
-- >>> type SomeRoute = "abc" :> Capture "email" String :> Put '[JSON] ()
-- >>> let someRoute = Proxy :: Proxy SomeRoute
-- >>> safeLink someRoute someRoute "test@example.com"
-- Link {_segments = ["abc","test%40example.com"], _queryParams = []}
--
-- >>> linkURI $ safeLink someRoute someRoute "test@example.com"
-- abc/test%40example.com
--
linkURI :: Link -> URI linkURI :: Link -> URI
linkURI = linkURI' LinkArrayElementBracket linkURI = linkURI' LinkArrayElementBracket
@ -192,7 +212,7 @@ linkURI' :: LinkArrayElementStyle -> Link -> URI
linkURI' addBrackets (Link segments q_params) = linkURI' addBrackets (Link segments q_params) =
URI mempty -- No scheme (relative) URI mempty -- No scheme (relative)
Nothing -- Or authority (relative) Nothing -- Or authority (relative)
(intercalate "/" $ map escape segments) (intercalate "/" $ map getEscaped segments)
(makeQueries q_params) mempty (makeQueries q_params) mempty
where where
makeQueries :: [Param] -> String makeQueries :: [Param] -> String
@ -257,7 +277,7 @@ class HasLink endpoint where
instance (KnownSymbol sym, HasLink sub) => HasLink (sym :> sub) where instance (KnownSymbol sym, HasLink sub) => HasLink (sym :> sub) where
type MkLink (sym :> sub) = MkLink sub type MkLink (sym :> sub) = MkLink sub
toLink _ = toLink _ =
toLink (Proxy :: Proxy sub) . addSegment seg toLink (Proxy :: Proxy sub) . addSegment (escaped seg)
where where
seg = symbolVal (Proxy :: Proxy sym) seg = symbolVal (Proxy :: Proxy sym)
@ -307,14 +327,14 @@ instance (ToHttpApiData v, HasLink sub)
type MkLink (Capture sym v :> sub) = v -> MkLink sub type MkLink (Capture sym v :> sub) = v -> MkLink sub
toLink _ l v = toLink _ l v =
toLink (Proxy :: Proxy sub) $ toLink (Proxy :: Proxy sub) $
addSegment (escape . Text.unpack $ toUrlPiece v) l addSegment (escaped . Text.unpack $ toUrlPiece v) l
instance (ToHttpApiData v, HasLink sub) instance (ToHttpApiData v, HasLink sub)
=> HasLink (CaptureAll sym v :> sub) where => HasLink (CaptureAll sym v :> sub) where
type MkLink (CaptureAll sym v :> sub) = [v] -> MkLink sub type MkLink (CaptureAll sym v :> sub) = [v] -> MkLink sub
toLink _ l vs = toLink _ l vs =
toLink (Proxy :: Proxy sub) $ toLink (Proxy :: Proxy sub) $
foldl' (flip $ addSegment . escape . Text.unpack . toUrlPiece) l vs foldl' (flip $ addSegment . escaped . Text.unpack . toUrlPiece) l vs
instance HasLink sub => HasLink (Header sym a :> sub) where instance HasLink sub => HasLink (Header sym a :> sub) where
type MkLink (Header sym a :> sub) = MkLink sub type MkLink (Header sym a :> sub) = MkLink sub