Besto

Besto

HTTPoison POST multipart with more form than the file

I’m trying to build a function to send a file through a POST request in multipart format, using this as guide, but HTTPoison keeps giving me two errors no matter what changes I make to the form. They are all

HTTPoison.post("https://api.telegram.org/myCredentials", {:multipart, form}, headers)

and the versions of my form and the errors are the following (whether I use headers or not):

1st and 2nd Version (same error for both):

form = [{"photo", [{"name", "myphoto.jpg"}, {:file, "files/aphoto.jpg"}]}, {"chat_id", 237799110}]
-----
form = [photo: [{"name", "myphoto.jpg"}, {:file, "files/aphoto.jpg"}], chat_id: 237799110]

Which give me this error:

** (FunctionClauseError) no function clause matching in anonymous fn/2 in :hackney_multipart.len_mp_stream/2
      (hackney) c:/Users/venta/projects/elixir/wrapper/deps/hackney/src/hackney_multipart.erl:159: anonymous fn({"photo", [{"name", "myphoto.jpg"}, {:file, "files/aphoto.jpg"}]}, 0) in :hackney_multipart.len_mp_stream/2
       (stdlib) lists.erl:1263: :lists.foldl/3
      (hackney) c:/Users/venta/projects/elixir/wrapper/deps/hackney/src/hackney_multipart.erl:159: :hackney_multipart.len_mp_stream/2
      (hackney) c:/Users/venta/projects/elixir/wrapper/deps/hackney/src/hackney_request.erl:319: :hackney_request.handle_body/4
      (hackney) c:/Users/venta/projects/elixir/wrapper/deps/hackney/src/hackney_request.erl:81: :hackney_request.perform/2
      (hackney) c:/Users/venta/projects/elixir/wrapper/deps/hackney/src/hackney.erl:373: :hackney.send_request/2
    (httpoison) lib/httpoison/base.ex:432: HTTPoison.Base.request/9

I checked the code for Hackney and the line that is erroring out is one that is supposed to get the file and an accSize, but it gets passed the whole form, not the file, and Hackney can’t do anything with it. I’m wondering how to pass a form with a file inside, since the API I’m using requires that the file be inside a “photo” object as such: {“chat_id”: someid, “photo”: file_in_multipart/form-data, “otherkeys”: othervals}

Most Liked

swelham

swelham

I have also been battling with a multipart post recently and I have ended up with this as the solution which should hopefully help you out.

data = [
      {"to", to},
      {"subject", subject},
      {"text", render_template("#{template}.text", data)},
      {"html", render_template("#{template}.html", data)},
      {:file, "/some/file.jpg",
          {"form-data", [{"name", "inline"}, {"filename", "some-file-name.jpg"}]},
          [{"Content-Type", "image/jpg"}]
        }
    ]

This is what my data structure ends up looking like before being passed into HTTPoison like so

HTTPoison.post!("url", {:multipart, data})

I hope this helps in some form or another.

Besto

Besto

Sorry, I deleted half the code that was irrelevant and added a commetary at the end. How would you put that file inside a nested form?

Edit: and it does help. I can see a pattern. I’ll try some more with it.
Edit2: I’ll do some testing with nodejs where I have managed to send multipart files to the API, see the response it gives using netcat and see if I can reproduce that with elixir using some way around the nesting, which is what seems to be stopping HTTPoison from working.

bibblyb

bibblyb

Sorry to bump an old thread, I’m sure the original poster figured it out, gave up, or moved onto something else, but in case anyone is interested/finds it useful, I believe this is the code he needs:

form = [
  {
    :file,
    "files/aphoto.jpg",
    {"form-data", [{"name", "photo"}, {"filename", "myphoto.jpg"}]},
    [] # pass along empty ExtraHeaders
  },
  {"chat_id", "237799110"}
]

HTTPoison.post("https://api.telegram.org/myCredentials", {:multipart, form}, headers)

The important part for providing a custom name to your file parameter within the form is the “name” param of “form-data”, as well as passing the empty ExtraHeaders param to ensure when creating the header for the file we go straight here:

hackney/src/hackney_multipart.erl at e6d84f40a4d2d650659ac54dba99c0bcbbb86af4 · benoitc/hackney · GitHub

Otherwise it will create default Content-Disposition form-data attributes:
https://github.com/benoitc/hackney/blob/e6d84f40a4d2d650659ac54dba99c0bcbbb86af4/src/hackney_multipart.erl#L226-L231

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement