shahryarjb

shahryarjb

hello, I create these post before and made my code in localhost that works for me perfect :sweat_smile: ,

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>>]

Showing Posts 1 to 10

NobbZ

NobbZ

How does your routes look like?

shahryarjb

shahryarjb OP

Hello,

this line:

|> put_resp_header("X-Accel-Redirect", "/tempfile/download/#{file_name}#{Path.extname(file_path)}")

tempfile/download is a fake address, my user sends me request that has a course id like this:

http://localhost:4000/lms/download?chapter_id=2e0b99dd-9219-4752-8007-4eeefcbff6ca&type=%D8%A7%D8%B4%D8%AA%D8%B1%D8%A7%DA%A9%DB%8C

and this router is:

get "/lms/download", ClientLmsController, :download

that’s it, I have no router for fake address in download header

     |> 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")

it should be noted, it works in my localhost default Phoenix server
Thanks

NobbZ

NobbZ

What’s your route for the /tempfile/...? You are redirecting there and therefore that’s what the client will request eventually.

shahryarjb

shahryarjb OP

I have no router for /tempfile/...?, because don’t know what it should do? what does this router run?

I don’t want to redirect, just wanted to show a fake address, what is your suggestion?

|> put_resp_header("X-Accel-Redirect", "/tempfile/download/#{file_name}#{Path.extname(file_path)}")

by the way I have edited /tempfile/download to lms/download, but it wasnt fixed.

my controller /lms/download

def download(conn, %{"chapter_id" => chapter_id, "type" => "رایگان"}) do
    with {:ok, :chapter, chapter_info} <- LmsQuery.chapter_select_download(chapter_id, "رایگان"),
         {:ok, :course, _course_info} <- LmsQuery.course(chapter_info.course_id, "select") do


        Khatoghalam.Extera.Download.download(conn, "/Users/sec_file/#{chapter_info.download_link}", "video/mp4", chapter_info.id, "normal")
    else
      _ ->
        conn
        |> put_flash(:error, "error")
        |> redirect(to: "#{KhatoghalamWeb.Router.Helpers.client_lms_path(conn, :home)}")
    end
  end

  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

that code is all of my code for downloading a file. how can I handle fake pass or a router ?

|> put_resp_header("X-Accel-Redirect", "/tempfile/download/#{file_name}#{Path.extname(file_path)}")

I didnt understand how could I fix it ? would you mind giving a router or example for fixing this? please

alvises

alvises

Can you please show us the router.ex file you should find at lib/khataghalam_web/router.ex of your Phoenix project?

shahryarjb

shahryarjb OP

scope "/", KhatoghalamWeb do
  pipe_through [:browser, :csrf]

  get "/lms/course/:alias_link", ClientLmsController, :course
  get "/lms/download", ClientLmsController, :download
end 

Thanks

OvermindDL1

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?

OvermindDL1

OvermindDL1

And I have no clue what this done, never ran across that before… But it is definitely significantly non-standard.

shahryarjb

shahryarjb OP

no im not sure, I took this code on those link in first post.

but when I use this:

  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_file(200, file)
  end

I have this error:

no function clause matching in Plug.Conn.send_file/5
shahryarjb

shahryarjb OP

I made mistake this works in localhost now I should test it on server

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews