analytics/lib/plausible_web/plugs/tracker.ex

78 lines
2.0 KiB
Elixir
Raw Normal View History

defmodule PlausibleWeb.Tracker do
import Plug.Conn
2020-11-03 12:35:08 +03:00
use Agent
2020-11-03 12:20:11 +03:00
base_variants = [
"hash",
"outbound-links",
"exclusions",
"compat",
"local",
"manual",
"file-downloads",
"pageview-props",
"tagged-events",
"revenue"
]
# Generates Power Set of all variants
variants =
1..Enum.count(base_variants)
|> Enum.map(fn x ->
Combination.combine(base_variants, x)
|> Enum.map(fn y -> Enum.sort(y) |> Enum.join(".") end)
end)
|> List.flatten()
@base_filenames ["plausible", "script", "analytics"]
@files_available ["plausible.js", "p.js"] ++ Enum.map(variants, fn v -> "plausible.#{v}.js" end)
def init(opts) do
Keyword.merge(opts, files_available: MapSet.new(@files_available))
end
def call(conn, files_available: files_available) do
filename =
case conn.request_path do
"/js/p.js" ->
"p.js"
"/js/" <> requested_filename ->
sorted_script_variant(requested_filename)
_ ->
nil
end
2020-11-03 12:20:11 +03:00
if filename && MapSet.member?(files_available, filename) do
location = Application.app_dir(:plausible, "priv/tracker/js/" <> filename)
conn
|> put_resp_header("content-type", "application/javascript")
|> put_resp_header("x-content-type-options", "nosniff")
|> put_resp_header("cross-origin-resource-policy", "cross-origin")
|> put_resp_header("access-control-allow-origin", "*")
|> put_resp_header("cache-control", "public, max-age=86400, must-revalidate")
|> send_file(200, location)
|> halt()
else
conn
end
end
defp sorted_script_variant(requested_filename) do
case String.split(requested_filename, ".") do
[base_filename | rest] when base_filename in @base_filenames ->
sorted_variants =
rest
|> List.delete("js")
|> Enum.sort()
Enum.join(["plausible"] ++ sorted_variants ++ ["js"], ".")
_ ->
nil
end
end
end