HTTP2 Internal Server Error in send_file
Closed this issue · 2 comments
I was developing with a local https server and attempting to serve video out of a /priv/static/videos
directory. Playback was handled through the <video>
element. Upon trying to start the video the server gave a 500 error. I was able to reproduce this in a fresh project. When originally trying to reproduce it I was using an http endpoint as I created a new phoenix application. The video played back fine.
It looks to me like an off by 1 error somewhere given that in the error message the length + offset == total file length. I found what I suspect to be the likely condition here but I do not think that is entirely correct because in my testing the server was throwing different errors after that change.
Notably a project using cowboy setup exactly the same does not throw any errors and the video plays fine.
To reproduce the issue
- create a fresh phoenix project
- ensure that you are using https to enable http2
- ensure that the server is serving from wherever you place your video file
- make a video tag that loads said file
I think the file should be "large" but I am not 100% sure. Probably big enough to force the browser to use range requests instead of loading the whole thing at once is enough.
[error] Task #PID<0.3400.0> started from #PID<0.3358.0> terminating
** (RuntimeError) Cannot read 3377 bytes starting at 1293549568 as /home/kyle/repos/bild/_build/dev/lib/bild/priv/static/videos/wall-e.mp4 is only 1293552945 octets in length
(bandit 1.1.1) lib/bandit/http2/adapter.ex:206: Bandit.HTTP2.Adapter.send_file/6
(plug 1.15.2) lib/plug/conn.ex:495: Plug.Conn.send_file/5
(plug 1.15.2) lib/plug/static.ex:301: Plug.Static.send_range/6
(bild 0.1.0) lib/bild_web/endpoint.ex:1: BildWeb.Endpoint.plug_builder_call/2
(bild 0.1.0) deps/plug/lib/plug/debugger.ex:136: BildWeb.Endpoint."call (overridable 3)"/2
(bild 0.1.0) lib/bild_web/endpoint.ex:1: BildWeb.Endpoint.call/2
(phoenix 1.7.10) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
(bandit 1.1.1) lib/bandit/pipeline.ex:101: Bandit.Pipeline.call_plug/2
(bandit 1.1.1) lib/bandit/pipeline.ex:22: Bandit.Pipeline.run/6
(bandit 1.1.1) lib/bandit/http2/stream_task.ex:69: Bandit.HTTP2.StreamTask.run/5
(elixir 1.15.7) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
Function: &Bandit.HTTP2.StreamTask.run/5
Args: [%Bandit.HTTP2.Adapter{connection: #PID<0.3358.0>, transport_info: %Bandit.TransportInfo{secure?: true, sockname: {{127, 0, 0, 1}, 4001}, peername: {{127, 0, 0, 1}, 37440}, peercert: nil}, stream_id: 9, end_stream: false, method: nil, content_encoding: nil, metrics: %{}, opts: []}, %Bandit.TransportInfo{secure?: true, sockname: {{127, 0, 0, 1}, 4001}, peername: {{127, 0, 0, 1}, 37440}, peercert: nil}, [{":method", "GET"}, {":authority", "localhost:4001"}, {":scheme", "https"}, {":path", "/videos/wall-e.mp4"}, {"sec-ch-ua", "\"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\""}, {"accept-encoding", "identity;q=1, *;q=0"}, {"sec-ch-ua-mobile", "?0"}, {"user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"}, {"sec-ch-ua-platform", "\"Linux\""}, {"accept", "*/*"}, {"sec-fetch-site", "same-origin"}, {"sec-fetch-mode", "no-cors"}, {"sec-fetch-dest", "video"}, {"referer", "https://localhost:4001/home"}, {"accept-language", "en-US,en;q=0.9"}, {"cookie", "_bild_web_user_remember_me=SFMyNTY.g2gDbQAAACC7E86Vhco3g5XPq1bovnrNcJG8gu3cvV9Vz9-8XDN4L24GAN-xYxOMAWIATxoA.5VR8XP17tAVGL7h8DapHVpgmvo3-R5uC0vgHMtQOwdo"}, {"cookie", "request_logger=SFMyNTY.g2gDbQAAAAQwVkt4bgYAln0XFIwBYgABUYA.nNaQ_L0LOr2UrlSo0EJOygz9hqzfE_i2uC2u1xcRX14"}, {"cookie", "_bild_key=SFMyNTY.g3QAAAADbQAAAAtfY3NyZl90b2tlbm0AAAAYdFF1Q2hDbGJsMHVyRENQMTdvT09nbHdHbQAAAA5saXZlX3NvY2tldF9pZG0AAAA7dXNlcnNfc2Vzc2lvbnM6WDlHZHY3My1uZUJHNkF2VUljTTVhZkRXbWtYRVgtQWVyd25Na0FVaVJ4UT1tAAAACnVzZXJfdG9rZW5tAAAAIF_Rnb-9_p3gRugL1CHDOWnw1ppFxF_gHq8JzJAFIkcU.r3ZnjEVuzrnAcOCG1pjmYOQJYNephUk9pzQ7KcgI5hw"}, {"dnt", "1"}, {"sec-gpc", "1"}, {"range", "bytes=1293549568-"}], {Phoenix.Endpoint.SyncCodeReloadPlug, {BildWeb.Endpoint, []}}, %Bandit.Telemetry{span_name: :request, telemetry_span_context: #Reference<0.1154210362.590086146.209286>, start_time: -576460164637618959, start_metadata: %{telemetry_span_context: #Reference<0.1154210362.590086146.209286>, connection_telemetry_span_context: #Reference<0.1154210362.590348289.24513>, stream_id: 9}}]
Sample home.html.heex
<.flash_group flash={@flash} />
<div class="width-screen height-screen">
<video class="max-h-[500px]" controls>
<source src={~p"/videos/ride-of-the-valkyries.webm"} />
</video>
<.link href="https://creativecommons.org/licenses/by/3.0/">License</.link>
<.link href="https://www.youtube.com/watch?v=uNkRW_9pHRQ">Source</.link>
</div>
The exact video used is too large to upload here but it is about 130mb.