tesla icon indicating copy to clipboard operation
tesla copied to clipboard

httpc adapter does not escape %

Open chulkilee opened this issue 6 years ago • 4 comments

Environment

  • tesla: 1.3.0
  • hackney: 1.15.2
Erlang/OTP 22 [erts-10.5.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.9.4 (compiled with Erlang/OTP 22)

Problem

When the httpc adapter is used, % in query value is not encoded correctly. See the follow example:

Tesla.get!(Tesla.client([Tesla.Middleware.JSON], Tesla.Adapter.Httpc), "https://postman-echo.com/get", query: [a: "a % b"]).body["url"]
"https://postman-echo.com/get?a=a+%+b"

Tesla.get!(Tesla.client([Tesla.Middleware.JSON], Tesla.Adapter.Hackney), "https://postman-echo.com/get", query: [a: "a % b"]).body["url"]
"https://postman-echo.com/get?a=a+%25+b"

Tesla.build_url("https://example.com", a: "a % b")
"https://example.com?a=a+%25+b"

chulkilee avatar Nov 21 '19 19:11 chulkilee

Both adapters use Tesla.build_url(env.url, env.query), I'll need to investigate this further.

teamon avatar Nov 24 '19 14:11 teamon

httpc is weird...

:httpc.request(:get, {'https://***.com?a=x$y', []}, [], [])
# a=x$y
:httpc.request(:get, {'https://***.com?a=x%24y', []}, [], [])
# a=x%24y

:httpc.request(:get, {'https://***.com?a=x%y', []}, [], [])
# a=x%y
:httpc.request(:get, {'https://***.com?a=x%25y', []}, [], [])
# a=x%y

teamon avatar Nov 24 '19 14:11 teamon

Looks like ERL-636

iex(12)> :uri_string.normalize('x%y')
'x%y'
iex(13)> :uri_string.normalize('x%25y')
'x%y'
iex(14)> :uri_string.normalize('x$y')
'x$y'
iex(15)> :uri_string.normalize('x%24y')
'x%24y'

teamon avatar Nov 24 '19 14:11 teamon

Surprisingly, with erlang 22.1.7 & elixir 1.9.4-otp-22 I see the exact same behaviour.

teamon avatar Nov 24 '19 14:11 teamon

Using:

Erlang/OTP 25 [erts-13.1.3] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.14.4) - press Ctrl+C to exit (type h() ENTER for help)

I got:

iex(1)> :uri_string.normalize('x%y')
'x%y'
iex(2)> :uri_string.normalize('x%25y')
'x%25y'
iex(3)> :uri_string.normalize('x$y')
'x$y'
iex(4)> :uri_string.normalize('x%24y')
'x%24y'
iex(1)> Tesla.get!(Tesla.client([Tesla.Middleware.JSON], Tesla.Adapter.Httpc), "https://postman-echo.com/get", query: [a: "a % b"]).body["url"]
"https://postman-echo.com/get?a=a+%25+b"
iex(2)>

So it seems to be fixed by now in OTP.

yordis avatar Sep 10 '23 11:09 yordis