Files
self cdbfef7cd3 fix: serve sender hls public path
Accept the current /sender/hls route in the Sender HLS plug while preserving the legacy plugin-slug path. Add direct plug coverage for both path shapes.
2026-06-18 02:16:57 +02:00

77 lines
1.9 KiB
Elixir

defmodule TribeOne.TribesPlugin.SenderWeb.HLSPlug do
@moduledoc false
import Plug.Conn
alias TribeOne.TribesPlugin.Sender.{HLS, Stats}
alias Tribes.RequestInfo
def init(opts), do: opts
def call(%{method: method, path_info: ["sender", "hls" | path_segments]} = conn, _opts)
when method in ["GET", "HEAD"] do
serve(conn, path_segments)
end
def call(
%{method: method, path_info: ["tribe-one-sender", "hls" | path_segments]} = conn,
_opts
)
when method in ["GET", "HEAD"] do
serve(conn, path_segments)
end
def call(conn, _opts), do: conn
defp serve(conn, path_segments) do
case HLS.resolve_path(path_segments) do
{:ok, path} ->
_count = record_hls_access(conn, path_segments)
conn
|> put_resp_content_type(HLS.content_type(path))
|> put_resp_header("cache-control", HLS.cache_control(path))
|> send_file_response(path)
|> halt()
{:error, :not_found} ->
conn
|> put_resp_header("cache-control", "no-store")
|> send_resp(:not_found, "Not found")
|> halt()
{:error, :unsafe_path} ->
conn
|> send_resp(:forbidden, "Forbidden")
|> halt()
end
end
defp send_file_response(%{method: "HEAD"} = conn, path) do
{:ok, stat} = File.stat(path)
conn
|> put_resp_header("content-length", Integer.to_string(stat.size))
|> send_resp(200, "")
end
defp send_file_response(conn, path), do: send_file(conn, 200, path)
defp record_hls_access(conn, path_segments) do
request_info = RequestInfo.fetch(conn)
if request_info.trusted_proxy? do
:ignored
else
Stats.record_hls_access(path_segments, request_info.ip, viewer_session_id(conn))
end
end
defp viewer_session_id(conn) do
conn
|> fetch_query_params()
|> Map.get(:params)
|> Map.get("vsid")
end
end