fix mediaproxy invalidations

This commit is contained in:
Maksim Pechnikov 2020-05-23 21:08:07 +03:00
parent aa06fc584b
commit 755bf36437
8 changed files with 100 additions and 43 deletions

View File

@ -405,11 +405,10 @@ config :pleroma, :media_proxy,
],
whitelist: []
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http, %{
"method" => :purge,
"headers" => [],
"options" => []
}
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
method: :purge,
headers: [],
options: []
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script, script_path: nil

View File

@ -283,11 +283,10 @@ This strategy allow perform custom http request to purge cache.
Example:
```elixir
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http, %{
"method" => :purge,
"headers" => [],
"options" => []
}
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
method: :purge,
headers: [],
options: []
```
## Link previews

View File

@ -5,9 +5,10 @@
defmodule Pleroma.Web.MediaProxy.Invalidation do
@moduledoc false
@callback purge(list(String.t()), map()) :: {:ok, String.t()} | {:error, String.t()}
@callback purge(list(String.t()), Keyword.t()) :: {:ok, String.t()} | {:error, String.t()}
alias Pleroma.Config
alias Pleroma.Web.MediaProxy
@spec purge(list(String.t())) :: {:ok, String.t()} | {:error, String.t()}
def purge(urls) do
@ -19,7 +20,11 @@ defmodule Pleroma.Web.MediaProxy.Invalidation do
defp do_purge(true, urls) do
provider = Config.get([:media_proxy, :invalidation, :provider])
options = Config.get(provider)
provider.purge(urls, options)
urls
|> List.wrap()
|> Enum.map(&MediaProxy.url(&1))
|> provider.purge(options)
end
defp do_purge(_, _), do: :ok

View File

@ -10,15 +10,14 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.Http do
@impl Pleroma.Web.MediaProxy.Invalidation
def purge(urls, opts) do
method = Map.get(opts, :method, :purge)
headers = Map.get(opts, :headers, [])
options = Map.get(opts, :options, [])
method = Keyword.get(opts, :method, :purge)
headers = Keyword.get(opts, :headers, [])
options = Keyword.get(opts, :options, [])
Logger.debug("Running cache purge: #{inspect(urls)}")
Enum.each(urls, fn url ->
with {:error, error} <-
do_purge(method, url |> Pleroma.Web.MediaProxy.url(), headers, options) do
with {:error, error} <- do_purge(method, url, headers, options) do
Logger.error("Error while cache purge: url - #{url}, error: #{inspect(error)}")
end
end)

View File

@ -10,32 +10,34 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.Script do
require Logger
@impl Pleroma.Web.MediaProxy.Invalidation
def purge(urls, %{script_path: script_path} = _options) do
def purge(urls, opts) do
args =
urls
|> List.wrap()
|> Enum.uniq()
|> Enum.join(" ")
path = Path.expand(script_path)
Logger.debug("Running cache purge: #{inspect(urls)}, #{path}")
case do_purge(path, [args]) do
{result, exit_status} when exit_status > 0 ->
Logger.error("Error while cache purge: #{inspect(result)}")
{:error, inspect(result)}
_ ->
{:ok, "success"}
end
opts
|> Keyword.get(:script_path, nil)
|> do_purge([args])
|> handle_error
end
def purge(_, _), do: {:error, "not found script path"}
defp do_purge(path, args) do
defp do_purge(script_path, args) when is_binary(script_path) do
path = Path.expand(script_path)
Logger.debug("Running cache purge: #{inspect(args)}, #{inspect(path)}")
System.cmd(path, args)
rescue
error -> {inspect(error), 1}
error -> error
end
defp do_purge(_, _), do: {:error, "not found script path"}
defp handle_error({_result, 0}), do: {:ok, "success"}
defp handle_error({:error, error}), do: handle_error(error)
defp handle_error(error) do
Logger.error("Error while cache purge: #{inspect(error)}")
{:error, inspect(error)}
end
end

View File

@ -0,0 +1,51 @@
defmodule Pleroma.Web.MediaProxy.InvalidationTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
alias Pleroma.Config
alias Pleroma.Web.MediaProxy.Invalidation
import ExUnit.CaptureLog
import Mock
import Tesla.Mock
setup do: clear_config([:media_proxy])
describe "Invalidation.Http" do
test "perform request to clear cache" do
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Http)
Config.put([Invalidation.Http], method: :purge, headers: [{"x-refresh", 1}])
mock(fn
%{
method: :purge,
url: "http://example.com/media/example.jpg",
headers: [{"x-refresh", 1}]
} ->
%Tesla.Env{status: 200}
end)
assert capture_log(fn ->
assert Invalidation.purge(["http://example.com/media/example.jpg"]) ==
{:ok, "success"}
end) =~ "Running cache purge: [\"http://example.com/media/example.jpg\"]"
end
end
describe "Invalidation.Script" do
test "run script to clear cache" do
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Script)
Config.put([Invalidation.Script], script_path: "purge-nginx")
with_mocks [{System, [], [cmd: fn _, _ -> {"ok", 0} end]}] do
assert capture_log(fn ->
assert Invalidation.purge(["http://example.com/media/example.jpg"]) ==
{:ok, "success"}
end) =~ "Running cache purge: [\"http://example.com/media/example.jpg\"]"
end
end
end
end

View File

@ -14,7 +14,7 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
refute capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example.jpg"],
%{}
[]
) == {:ok, "success"}
end) =~ "Error while cache purge"
end
@ -28,7 +28,7 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
assert capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example1.jpg"],
%{}
[]
) == {:ok, "success"}
end) =~ "Error while cache purge: url - http://example.com/media/example1.jpg"
end

View File

@ -8,13 +8,15 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
assert capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
%{script_path: "./example"}
) == {:error, "\"%ErlangError{original: :enoent}\""}
end) =~ "Error while cache purge: \"%ErlangError{original: :enoent}\""
script_path: "./example"
) == {:error, "%ErlangError{original: :enoent}"}
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
%{}
) == {:error, "not found script path"}
capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
[]
) == {:error, "\"not found script path\""}
end)
end
end