Captures the exact raw request body into conn.assigns[:raw_body] for the
SNS webhook route, independent of the host endpoint's Plug.Parsers.
SquatchMail.Web.Router mounts this plug ahead of
SquatchMail.Web.WebhookController for POST .../webhooks/sns/:token only.
It exists because relying on Plug.Parsers's :body_reader to capture the
raw bytes is not sufficient for SNS:
SNS delivers to HTTP/S endpoints with Content-Type: text/plain; charset=UTF-8. Plug.Parsers only invokes its :body_reader for a
content-type one of its configured parsers matches — and the usual parser
list ([:urlencoded, :multipart, :json]) matches none of text/plain. With
pass: ["*/*"], Plug.Parsers therefore returns the request with an empty
params map and the body still unread, so a :body_reader never sees SNS's
bytes and conn.assigns[:raw_body] is never set. SquatchMail.SNS.Processor
then decodes the controller's Jason.encode!(conn.params) fallback — just the
path params — finds no "Type" key, and every SNS message 500s.
Because the host endpoint's Plug.Parsers runs earlier and leaves the
text/plain body unread, this plug (running later, in SquatchMail's own
router pipeline) can still read it. It reads the full body — following
{:more, ...} chunking — and assigns it. SquatchMail.SNS.MessageVerifier
needs those exact bytes to rebuild the signed string, and
SquatchMail.SNS.Processor.process/2 does its own JSON decode of them.
If conn.assigns[:raw_body] is already a binary — e.g. a host wired
SquatchMail.SNS.RawBodyReader into its endpoint's Plug.Parsers
:body_reader (still supported) — this plug leaves it untouched. It is the
reliable default; the body_reader is an optional belt-and-suspenders for hosts
who prefer to capture at the endpoint.