shahryarjb
NGINX doesn't let phoenix to send file to it's user
hello, I create these post before and made my code in localhost that works for me perfect
,
https://forum.elixirforum.com/t/downloading-with-user-token/
https://forum.elixirforum.com/t/how-can-i-send-a-chunked-file-to-a-user-for-download
but today I decided to move my project into my server, the server uses NGINX and docker but doesn’t let me download with Phoenix, Please see my code!!
my code:
def download(conn, file_path, file_type, file_name, "normal") do
file = File.read!("#{file_path}")
conn
|> put_resp_content_type("#{file_type}")
|> put_resp_header("Content-disposition","attachment; filename=\"#{file_name}#{Path.extname(file_path)}\"")
|> put_resp_header("X-Accel-Redirect", "/tempfile/download/#{file_name}#{Path.extname(file_path)}")
|> put_resp_header("Content-Type", "application/octet-stream")
|> send_resp(200, file)
end
I have tested 2 file format and size, the lowest size and big file, but they were different.
when I tested big file I had this error just in my safari that my browser download html file and tells me
no route found for GET /lms/download/c416ed0c-67d3-455c-b6f3-77273228be22.mp4 (KhatoghalamWeb.Router)
but the low size shows me a nginix default error
404 Not Found
nginx
you can see these link online: http://bit.ly/31yFISx
Middle of the page you can see this image and click on download icon
chrome error:
This site can’t be reached The web page at https://newkhat.khatoghalam.com/lms/download?chapter_id=5e638cce-e6b0-4d14-89f8-1f754c191ea9&type=رایگان might be temporarily down or it may have moved permanently to a new web address.
ERR_INVALID_RESPONSE
how can I fix this ?
Update
Big file download like video iex console on server:
[info] GET /lms/download
[debug] Processing with KhatoghalamWeb.ClientLmsController.download/2
Parameters: %{"chapter_id" => "5e638cce-e6b0-4d14-89f8-1f754c191ea9", "type" => "رایگان"}
Pipelines: [:browser, :csrf]
[debug] QUERY OK source="lms_chapters" db=1.9ms queue=0.3ms
SELECT l0."id", l1."id", l1."course_id", l0."download_link", l0."inserted_at", l0."updated_at" FROM "lms_chapters" AS l0 INNER JOIN "lms_headlines" AS l1 ON l1."id" = l0."headline_id" WHERE (l0."id" = $1) AND (((l0."status" = TRUE) AND (l1."status" = TRUE)) AND (l0."type" = 'رایگان')) [<<94, 99, 140, 206, 230, 176, 77, 20, 137, 248, 31, 117, 76, 25, 30, 169>>]
[debug] QUERY OK source="lms_courses" db=2.1ms queue=0.1ms
SELECT l0."id" FROM "lms_courses" AS l0 INNER JOIN "lms_categories" AS l1 ON l1."id" = l0."category_id" WHERE (l0."id" = $1) AND ((l0."status" = TRUE) AND (l1."status" = TRUE)) [<<57, 222, 97, 78, 28, 189, 70, 214, 160, 161, 15, 29, 94, 185, 131, 112>>]
[info] Sent 200 in 9ms
[info] GET /tempfile/download/5e638cce-e6b0-4d14-89f8-1f754c191ea9.mp4
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /tempfile/download/5e638cce-e6b0-4d14-89f8-1f754c191ea9.mp4 (KhatoghalamWeb.Router)
(khatoghalam) lib/phoenix/router.ex:316: KhatoghalamWeb.Router.call/2
(khatoghalam) lib/khatoghalam_web/endpoint.ex:1: KhatoghalamWeb.Endpoint.plug_builder_call/2
(khatoghalam) lib/plug/debugger.ex:122: KhatoghalamWeb.Endpoint."call (overridable 3)"/2
(khatoghalam) lib/khatoghalam_web/endpoint.ex:1: KhatoghalamWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /khatogh/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /khatogh/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
(cowboy) /khatogh/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
low file size in server iex console
[info] GET /lms/download
[debug] Processing with KhatoghalamWeb.ClientLmsController.download/2
Parameters: %{"chapter_id" => "c416ed0c-67d3-455c-b6f3-77273228be22", "type" => "رایگان"}
Pipelines: [:browser, :csrf]
[debug] QUERY OK source="lms_chapters" db=2.0ms queue=0.7ms
SELECT l0."id", l1."id", l1."course_id", l0."download_link", l0."inserted_at", l0."updated_at" FROM "lms_chapters" AS l0 INNER JOIN "lms_headlines" AS l1 ON l1."id" = l0."headline_id" WHERE (l0."id" = $1) AND (((l0."status" = TRUE) AND (l1."status" = TRUE)) AND (l0."type" = 'رایگان')) [<<196, 22, 237, 12, 103, 211, 69, 92, 182, 243, 119, 39, 50, 40, 190, 34>>]
[debug] QUERY OK source="lms_courses" db=1.2ms queue=0.9ms
SELECT l0."id" FROM "lms_courses" AS l0 INNER JOIN "lms_categories" AS l1 ON l1."id" = l0."category_id" WHERE (l0."id" = $1) AND ((l0."status" = TRUE) AND (l1."status" = TRUE)) [<<57, 222, 97, 78, 28, 189, 70, 214, 160, 161, 15, 29, 94, 185, 131, 112>>]
Marked As Solved
OvermindDL1
You aren’t sending the file, you are sending the contents, your code should be like:
def download(conn, file_path, file_type, file_name, "normal") do
conn
|> put_resp_content_type("#{file_type}")
|> put_resp_header("Content-disposition","attachment; filename=\"#{file_name}#{Path.extname(file_path)}\"")
|> put_resp_header("Content-Type", "application/octet-stream")
|> send_file(200, "#{file_path}")
end
It takes a filename, it can’t stream an existing body. send_file/5 works by asking the kernel to send the file contents to the socket, it never enters userspace at all, no faster method of sending a file (in general, in reality it chunks it in certain modes, streams it in others, etc… it tries to do whatever is fastest and most efficient without overwhelming things).
Also Liked
OvermindDL1
You might be sending too much data in one burst since you say it only doesn’t work on “big files”.
This is loading the entire big file into active memory, yet you aren’t doing anything to it, unsure why?
Then you are sending the file out in one big message instead of streaming it out.
You should be using send_file/5 instead, this will stream it out, not eating RAM, and will naturally throttle to how fast the proxy will send it. Or you can chunk it manually but that’s a lot of work for no gain. ^.^;
If you switch to that though, does it work now?
NobbZ
How does your routes look like?
NobbZ
What’s your route for the /tempfile/...? You are redirecting there and therefore that’s what the client will request eventually.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










