Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requests hang forever when using integers as values in multipart #230

Closed
helderbarboza opened this issue Jul 17, 2018 · 3 comments
Closed

Comments

@helderbarboza
Copy link

Environment

uname -a output:

Linux hostname-pc 4.17.3-100.fc27.x86_64 #1 SMP Tue Jun 26 14:19:03 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

elixir --version output:

Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Elixir 1.6.2 (compiled with OTP 19)

Current behavior

When passing a integer value as third argument to add_field/4, it never returns when executing the request:

alias Tesla.Multipart
chat_id_int = -1_001_143_002_998
token = Application.get_env(:tg, :token)

mp =
  Multipart.new()
  |> Multipart.add_field("chat_id", chat_id_int)
  |> Multipart.add_file("test.txt", name: "document")

Tesla.post("https://api.telegram.org/bot#{token}/sendDocument", mp) # Hangs forever

This works fine:

alias Tesla.Multipart
chat_id_str = "-1001143002998"
token = Application.get_env(:tg, :token)

mp =
  Multipart.new()
  |> Multipart.add_field("chat_id", chat_id_str)
  |> Multipart.add_file("test.txt", name: "document")

Tesla.post("https://api.telegram.org/bot#{token}/sendDocument", mp)

Expected behavior

I would expect it to either work fine with integers or to throw an error when I try to pass something that is not a string, whichever makes more sense.

@teamon
Copy link
Member

teamon commented Jul 18, 2018

I can't test this right now, please try to produce the failing minimal example against requestbin or similar service.

@helderbarboza
Copy link
Author

Using string:

mp =
  Multipart.new()
  |> Multipart.add_field("foo", "123")

Tesla.post("http://requestbin.net/r/1mw0e3c1", mp)

Output:

{:ok,
 %Tesla.Env{
   __client__: %Tesla.Client{fun: nil, post: [], pre: []},
   __module__: Tesla,
   body: "ip:177.124.185.70\n",
   headers: [
     {"connection", "keep-alive"},
     {"date", "Wed, 18 Jul 2018 20:22:07 GMT"},
     {"via", "1.1 vegur"},
     {"server", "cloudflare"},
     {"content-length", "18"},
     {"content-type", "text/html; charset=utf-8"},
     {"set-cookie",
      "__cfduid=d0511378e77d3b91c1043de753a3482371531945327; expires=Thu, 18-Jul-19 20:22:07 GMT; path=/; domain=.requestbin.net; HttpOnly"},
     {"sponsored-by", "http://requestbin.net"},
     {"cf-ray", "43c7a897729ab8b9-MIA"}
   ],
   method: :post,
   opts: [],
   query: [],
   status: 200,
   url: "http://requestbin.net/r/1mw0e3c1"
 }}

Using integer:

mp =
  Multipart.new()
  |> Multipart.add_field("foo", 123)

Tesla.post("http://requestbin.net/r/1mw0e3c1", mp)

Never outputs.

@teamon
Copy link
Member

teamon commented Jul 19, 2018

The hanging part is because of httpc (the default adapter). However, the body should be an Enumerable. When it's binary it's converted to [body] by tesla.

The error is much more clear when used with hackney adapter:

** (Protocol.UndefinedError) protocol Enumerable not implemented for 123. This protocol is implemented for: Date.Range, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Range, Stream
    (elixir) /home/ubuntu/bob/tmp/e00399d85b8d200de0c17f19231c78a9/elixir/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) /home/ubuntu/bob/tmp/e00399d85b8d200de0c17f19231c78a9/elixir/lib/elixir/lib/enum.ex:141: Enumerable.reduce/3
    (elixir) lib/stream.ex:923: Stream.do_enum_transform/7
    (elixir) lib/enum.ex:1919: Enum.reduce/3
    (tesla) lib/tesla/adapter/hackney.ex:74: Tesla.Adapter.Hackney.request_stream/5
    (tesla) lib/tesla/adapter/hackney.ex:31: Tesla.Adapter.Hackney.call/2

I think we need to add a guard to Multipart.add_field/3 to prevent passing unsupported data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants