HTTPoison file upload from binary

I am trying to send a file using the HTTPoison :multipart request and the following is working fine when the file is on disk.

{:file, "/path/to/file",
  {"form-data", [{"name", "inline"}, {"filename", "penguins.jpg"}]},
  [{"Content-Type", "image/jpg"}]
}

However in my particular use case I already have the file contents in memory and not persisted to disk. Does anyone know how to pass in the content as binary instead of a file path? I have tried all sorts with no luck so far.

5 Likes

Have you tried wrapping it a StringIO (https://hexdocs.pm/elixir/StringIO.html)?

2 Likes

I do not think that it is possible. HTTPotion is only a shallow wrapper around the erlang library hackney which itself does not support sending binary data from memory.

2 Likes

That’s what I thought, I was digging through the hackney code and I couldn’t see anything in there that looked like it would support this.

I don’t think this would work as it’s using the filelib and file modules on the given input.

3 Likes

Hi,

I had to solve this recently to send emails with attachments via the Mailgun API. This is what I ended up with:

 def send_with_attachment(from, to, subject, text, filename, content_type, iodata) do
    api_key = Application.get_env(:app, App.Mailer)[:api_key]
    HTTPoison.post("https://api.mailgun.net/v2/proxypay.co.ao/messages",
      {:multipart, [
          {"from", from},
          {"to", to},
          {"subject", subject},
          {"text", text},
          {"attachment", IO.iodata_to_binary(iodata),
           {"form-data", [
               {"name", "\"attachment\""},
               {"filename", "\"#{filename}\""}]},
           [{"Content-Type", content_type}]}]}, [],
      [timeout: @timeout, recv_timeout: @recv_timeout,
       hackney: [basic_auth: {"api", api_key}]])
  end

Regards,

12 Likes

Awesome, thanks for your example.

What’s event better is I didn’t mention that my post is also to the Mailgun API, so that example truely hits the spot.

Many thanks, I will give it a try.

3 Likes