Gate for the signed URL space (API doc §1/§2).
Splits conn.request_path into the signature segment and everything after
it, then verifies with AudioProxy.Signature.verify/2 — the signed string
is the raw request path, so no re-encoding ambiguity can creep in.
On success the rest-of-path (leading / included) is stashed in
conn.assigns[:rest_of_path] for the downstream options/source parsers. On
failure the plug halts with the 401 row of AudioProxy.ErrorJSON; a
missing signature segment is just another invalid signature.
Invariants downstream code must respect:
- Parse
assigns.rest_of_path, neverpath_info. The signature covers the raw request path, andconn.path_infocannot reproduce those bytes:Plug.Conn.Adapterbuilds it by splitting on/and dropping empty segments (/{sig}//aand/{sig}/acollide), andPlug.Routeradditionally percent-decodes its own copy for route matching. Neither form is the verified byte sequence. - The signature covers the path only. The query string and the HTTP method are not signed — never let an unsigned query param influence processing, and don't assume a signed URL is GET-only.
rest_of_pathcan be"/"(a request for/{sig}/with a valid signature). That carries no options/source; reject it downstream.
Mount this plug on the signed routes only — /health (and later /metrics)
live outside the signed URL space and must not pass through it.