-
-
Notifications
You must be signed in to change notification settings - Fork 420
Description
First of all, this is a wonderful project and very useful. Now, down to business.
When using defaults, servant-client code can double-encode percent signs in query parameters. Consider this (incomplete) example:
newtype UrlEncoded = UrlEncoded { unUrlEncoded :: ByteString }
instance ToHttpApiData UrlEncoded where
toQueryParam = decodeUtf8 . urlEncode True . unUrlEncoded
type ExampleEndpoint = QueryParam "value" UrlEncoded :> GetNoContent
exampleEndpoint :: UrlEncoded -> ClientM ()
exampleEndpoint = client $ Proxy @ExampleEndpoint
problemCall :: ClientM ()
problemCall = exampleEndpoint $ UrlEncoded "\x01"Running problemCall creates a request with query string ?value=%2501. I believe the reason is that the HasClient instance of QueryParam uses toQueryParam when adding the parameter to the (servant) Request it builds up, then defaultMakeClientRequest calls renderQuery which re-encodes the string while marshalling a (http-client) Request.
It is my understanding that ToHttpApiData (toQueryParam) is meant to produce escaped output. Therefore, it seems that defaultMakeClientRequest should use a custom version of renderQuery which does not escape values.