You've already forked tribes-plugin-sender
forked from tribes/tribes-plugin-template
cdbfef7cd3
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.
77 lines
1.9 KiB
Elixir
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
|