Phoenix / Plug send file error

Recently, we have issues with user initiated download with Phoenix / Plug.
All versions are updated.
This used to work flawlessly.
What is the best approach to send a file to the user?

PS: full_path is the full path extracted with Path.expand(). And it’s working and tested with File.read!().

plug

conn
|> put_resp_content_type(filetype)
|> put_resp_header("content-disposition", "attachment; filename=#{export_name}")
|> send_file(200, full_path)

or

phoenix

conn
|> send_download({:file, full_path}, filename: export_name, content_type: filetype, charset: "utf-8")

Now, most of the time we got 502 Bad Gateway from NGINX.

Do you get any logs from Phoenix?

1 Like

None, even on development mode.
Only if the file doesn’t exists (not in this case).
If I inspect conn, all seems fine.

If you aren’t getting any logs when the request comes in then it sounds like there is some issue with NGINX seeing your phoenix program. Does this happen with any other route or just files?

1 Like

Just files. All other routes are fine.
Our app generates a new file (report) and sends to the user.

Those are the errors in NGINX error log

upstream sent too big header while reading response header from upstream
no live upstreams while connecting to upstream

Anyone have some extra advices?

A quick Google search lead me to this.

According to that page, nginx buffers the full response before sending it on to the client. Maybe the response is too big and adjusting the buffer sizes will solve the issue?

EDIT: Be sure to read the comments on that page.

1 Like

Yep, that was fun when I was uploading 400 megs of files to parse in a single ‘POST’… ^.^;

I’ve changed my pipeline to exclude NavigationHistory export path.
My export generated a long path and header grew more than it should.
Now it’s working as intended.
Thanks everyone.

Ex: /pt/export/report/users/?filetype=xlsx&compress=false&filename=report_all_users&group=&id=&from=0&limit=ALL&report_subdomain=global&report_id=6

pipeline :app do

plug NavigationHistory.Tracker, excluded_paths: [~r(auth.), ~r(export.)], history_size: 5

end