2
votes

I have an application that generates a PDF in memory. I need to return that PDF back to the browser. The request is of type POST but I am having problems using send_download. Currently, I am only able to get it working with a GET request.

Here is what I have tried:

In the controller, this works if the request is a get: (note pdf is bytes (<<37, 56, 66 ...>> etc)

send_download(conn, {:binary, pdf}, [filename: "doc.pdf"]

This however does not work if I turn the request into a POST. I get no errors on the server when I do.

I have also tried:

  conn
    |> put_resp_content_type("application/pdf")
    |> put_resp_header("content-disposition", "attachment; filename=html.pdf")
    |> send_file(200, pdf)

But I get the following error when I try:

cannot send_file/5 with null byte

pdf var which holds the bytes is not null. I have an inspect right before this and its not nil.

I have searched and can't seem to find an answer to something that seems so simple. send_file does not seem to be the correct function since the docs say it takes a full path and not the file in bytes...

I am trying to avoid writing the file to disk.

Thanks in advance.

1
The error you are getting has nothing to do with the pdf var being nil. It is saying that one of the bytes in your binary is a null byte. I do not know enough about PDF's to know whether or not it is normal to have a null byte, I also do not know why the send_file function would care. - Justin Wood

1 Answers

3
votes

I found the solution: send_file expects a full path and not binary data of the file. Use send_resp instead.

 conn
    |> put_resp_content_type("application/pdf")
    |> put_resp_header("content-disposition", "attachment; filename=html.pdf")
    |> Plug.Conn.send_resp(:ok, pdf)