diff --git a/lib/plausible_web/controllers/api/external_controller.ex b/lib/plausible_web/controllers/api/external_controller.ex index 95d4de012..a4339acaa 100644 --- a/lib/plausible_web/controllers/api/external_controller.ex +++ b/lib/plausible_web/controllers/api/external_controller.ex @@ -55,7 +55,7 @@ defmodule PlausibleWeb.Api.ExternalController do end defp create_event(conn, params) do - uri = params["url"] && URI.parse(params["url"]) + uri = params["url"] && URI.parse(URI.decode(params["url"])) user_agent = Plug.Conn.get_req_header(conn, "user-agent") |> List.first() if UAInspector.bot?(user_agent) do @@ -69,6 +69,7 @@ defmodule PlausibleWeb.Api.ExternalController do ref = parse_referrer(uri, params["referrer"]) country_code = visitor_country(conn) salts = Plausible.Session.Salts.fetch() + referrer_source = if params["source"], do: URI.decode(params["source"]), else: get_referrer_source(ref) event_attrs = %{ timestamp: NaiveDateTime.utc_now(), @@ -80,7 +81,7 @@ defmodule PlausibleWeb.Api.ExternalController do country_code: country_code, operating_system: ua && os_name(ua), browser: ua && browser_name(ua), - referrer_source: params["source"] || referrer_source(ref), + referrer_source: referrer_source, referrer: clean_referrer(ref), screen_size: calculate_screen_size(params["screen_width"]) } @@ -176,9 +177,9 @@ defmodule PlausibleWeb.Api.ExternalController do end end - defp referrer_source(nil), do: nil + defp get_referrer_source(nil), do: nil - defp referrer_source(ref) do + defp get_referrer_source(ref) do case ref.source do :unknown -> clean_uri(ref.referer) diff --git a/test/plausible_web/controllers/api/external_controller_test.exs b/test/plausible_web/controllers/api/external_controller_test.exs index e979f1525..a3f081d8e 100644 --- a/test/plausible_web/controllers/api/external_controller_test.exs +++ b/test/plausible_web/controllers/api/external_controller_test.exs @@ -398,6 +398,25 @@ defmodule PlausibleWeb.Api.ExternalControllerTest do assert pageview["country_code"] == "US" end + test "URL and source are decoded", %{conn: conn} do + params = %{ + name: "pageview", + url: "http://www.example.com/opportunity/category/%D8%AC%D9%88%D8%A7%D8%A6%D8%B2-%D9%88%D9%85%D8%B3%D8%A7%D8%A8%D9%82%D8%A7%D8%AA", + source: "Hello%20World", + domain: "external-controller-test-21.com" + } + + conn + |> put_req_header("content-type", "text/plain") + |> post("/api/event", Jason.encode!(params)) + + pageview = get_event("external-controller-test-21.com") + + assert pageview["pathname"] == "/opportunity/category/جوائز-ومسابقات" + assert pageview["referrer_source"] == "Hello World" + end + + test "responds 400 when required fields are missing", %{conn: conn} do params = %{}