From d585b95e85569fae87629589856ffff0a4175cca Mon Sep 17 00:00:00 2001 From: Max Veytsman Date: Fri, 16 Aug 2024 15:31:39 -0400 Subject: [PATCH] Add a cached reader to the parsers plug --- lib/bike_brigade_web/endpoint.ex | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/bike_brigade_web/endpoint.ex b/lib/bike_brigade_web/endpoint.ex index 19402051..1d7e05c3 100644 --- a/lib/bike_brigade_web/endpoint.ex +++ b/lib/bike_brigade_web/endpoint.ex @@ -50,6 +50,7 @@ defmodule BikeBrigadeWeb.Endpoint do plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], + body_reader: {CacheBodyReader, :read_body, []}, pass: ["*/*"], json_decoder: Phoenix.json_library() @@ -58,3 +59,26 @@ defmodule BikeBrigadeWeb.Endpoint do plug Plug.Session, @session_options plug BikeBrigadeWeb.Router end + +defmodule CacheBodyReader do + @moduledoc """ + Inspired by https://hexdocs.pm/plug/1.6.0/Plug.Parsers.html#module-custom-body-reader + """ + + alias Plug.Conn + + @cache_body_for_proxy_path "/analytics" + + @doc """ + Read the raw body and store it for later use in the connection. + It ignores the updated connection returned by `Plug.Conn.read_body/2` to not break CSRF. + """ + @spec read_body(Conn.t(), Plug.opts()) :: {:ok, String.t(), Conn.t()} + def read_body(%Conn{request_path: @cache_body_for_proxy_path <> _} = conn, opts) do + {:ok, body, _conn} = Conn.read_body(conn, opts) + conn = update_in(conn.assigns[:raw_body], &[body | &1 || []]) + {:ok, body, conn} + end + + def read_body(conn, opts), do: Conn.read_body(conn, opts) +end