From 12af10423819f0381d35e9d238fc32d9bf2b016e Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Sat, 4 May 2024 20:53:04 +0200 Subject: [PATCH] Enable SVG preview caching --- lib/asciinema_web.ex | 1 + lib/asciinema_web/caching.ex | 17 +++++++++++++++++ .../controllers/recording/thumbnail.html.heex | 2 +- .../controllers/recording_controller.ex | 11 +++++++++-- lib/asciinema_web/controllers/recording_html.ex | 3 +++ 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 lib/asciinema_web/caching.ex diff --git a/lib/asciinema_web.ex b/lib/asciinema_web.ex index eaa801ec7..d07181c08 100644 --- a/lib/asciinema_web.ex +++ b/lib/asciinema_web.ex @@ -52,6 +52,7 @@ defmodule AsciinemaWeb do import AsciinemaWeb.Auth, only: [require_current_user: 2] import AsciinemaWeb.Plug.ReturnTo import AsciinemaWeb.Plug.Authz + import AsciinemaWeb.Caching unquote(verified_routes()) diff --git a/lib/asciinema_web/caching.ex b/lib/asciinema_web/caching.ex new file mode 100644 index 000000000..978b188d3 --- /dev/null +++ b/lib/asciinema_web/caching.ex @@ -0,0 +1,17 @@ +defmodule AsciinemaWeb.Caching do + import Plug.Conn + + def put_etag(conn, content) do + etag = Crypto.md5(to_string(content)) + + conn + |> put_resp_header("etag", etag) + |> register_before_send(fn conn -> + if etag in get_req_header(conn, "if-none-match") do + send_resp(conn, 304, "") + else + conn + end + end) + end +end diff --git a/lib/asciinema_web/controllers/recording/thumbnail.html.heex b/lib/asciinema_web/controllers/recording/thumbnail.html.heex index 5ae18794c..42a29b02b 100644 --- a/lib/asciinema_web/controllers/recording/thumbnail.html.heex +++ b/lib/asciinema_web/controllers/recording/thumbnail.html.heex @@ -2,5 +2,5 @@ class="thumbnail" style={"background-color: #{theme(@asciicast).bg}; border-right: 1ch solid #{theme(@asciicast).bg}"} > - ".svg?v=t"} /> + ".svg?f=t&v=#{svg_cache_key(@asciicast)}"} /> diff --git a/lib/asciinema_web/controllers/recording_controller.ex b/lib/asciinema_web/controllers/recording_controller.ex index 0de4e1339..3ca7f0b0b 100644 --- a/lib/asciinema_web/controllers/recording_controller.ex +++ b/lib/asciinema_web/controllers/recording_controller.ex @@ -3,6 +3,7 @@ defmodule AsciinemaWeb.RecordingController do alias Asciinema.{Recordings, PngGenerator} alias Asciinema.Recordings.Asciicast alias AsciinemaWeb.PlayerOpts + alias AsciinemaWeb.RecordingHTML plug :clear_main_class plug :load_asciicast when action in [:show, :edit, :update, :delete, :iframe] @@ -102,6 +103,9 @@ defmodule AsciinemaWeb.RecordingController do end end + # 1 hour + @svg_max_age 3600 + def do_show(conn, "svg", asciicast) do if asciicast.archived_at do path = Application.app_dir(:asciinema, "priv/static/images/archived.png") @@ -112,12 +116,15 @@ defmodule AsciinemaWeb.RecordingController do |> send_file(200, path) else variant = - case conn.params["v"] do + case conn.params["f"] do "t" -> :thumbnail _ -> :show end - render(conn, variant, asciicast: asciicast) + conn + |> put_resp_header("cache-control", "public, max-age=#{@svg_max_age}, must-revalidate") + |> put_etag(RecordingHTML.svg_cache_key(asciicast)) + |> render(variant, asciicast: asciicast) end end diff --git a/lib/asciinema_web/controllers/recording_html.ex b/lib/asciinema_web/controllers/recording_html.ex index ec9f8b724..a81d67cc5 100644 --- a/lib/asciinema_web/controllers/recording_html.ex +++ b/lib/asciinema_web/controllers/recording_html.ex @@ -221,6 +221,9 @@ defmodule AsciinemaWeb.RecordingHTML do asciicast.views_count end + def svg_cache_key(asciicast), + do: Timex.to_unix(asciicast.updated_at) - Timex.to_unix(asciicast.inserted_at) + def head("show.html", assigns), do: head_for_show(assigns) def head(_, _), do: nil end