diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index aaea3f46c..ddea6a4fb 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -262,6 +262,12 @@ Urls of attachments pass to script as arguments.
* `script_path`: path to external script.
+Example:
+```elixir
+config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script,
+ script_path: "./installation/nginx-cache-purge.example"
+```
+
#### Pleroma.Web.MediaProxy.Invalidation.Http
This strategy allow perform custom http request to purge cache.
@@ -270,6 +276,14 @@ This strategy allow perform custom http request to purge cache.
* `headers`: http headers. default is empty
* `options`: request options. default is empty
+Example:
+```elixir
+config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
+ method: :purge,
+ headers: [],
+ options: []
+```
+
## Link previews
### Pleroma.Web.Metadata (provider)
diff --git a/lib/pleroma/web/media_proxy/invalidation.ex b/lib/pleroma/web/media_proxy/invalidation.ex
index 371aa8ae0..c037ff13e 100644
--- a/lib/pleroma/web/media_proxy/invalidation.ex
+++ b/lib/pleroma/web/media_proxy/invalidation.ex
@@ -1,8 +1,15 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.MediaProxy.Invalidation do
+ @moduledoc false
+
@callback purge(list(String.t()), map()) :: {:ok, String.t()} | {:error, String.t()}
alias Pleroma.Config
+ @spec purge(list(String.t())) :: {:ok, String.t()} | {:error, String.t()}
def purge(urls) do
[:media_proxy, :invalidation, :enabled]
|> Config.get()
@@ -13,7 +20,6 @@ defmodule Pleroma.Web.MediaProxy.Invalidation do
provider = Config.get([:media_proxy, :invalidation, :provider])
options = Config.get(provider)
provider.purge(urls, options)
- :ok
end
defp do_purge(_, _), do: :ok
diff --git a/lib/pleroma/web/media_proxy/invalidations/http.ex b/lib/pleroma/web/media_proxy/invalidations/http.ex
index 66fafa7ba..07248df6e 100644
--- a/lib/pleroma/web/media_proxy/invalidations/http.ex
+++ b/lib/pleroma/web/media_proxy/invalidations/http.ex
@@ -1,16 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.MediaProxy.Invalidation.Http do
+ @moduledoc false
@behaviour Pleroma.Web.MediaProxy.Invalidation
+ require Logger
+
@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, [])
+ Logger.debug("Running cache purge: #{inspect(urls)}")
+
Enum.each(urls, fn url ->
- Pleroma.HTTP.request(method, url, "", headers, options)
+ with {:error, error} <- do_purge(method, url, headers, options) do
+ Logger.error("Error while cache purge: url - #{url}, error: #{inspect(error)}")
+ end
end)
{:ok, "success"}
end
+
+ defp do_purge(method, url, headers, options) do
+ case Pleroma.HTTP.request(method, url, "", headers, options) do
+ {:ok, %{status: status} = env} when 400 <= status and status < 500 ->
+ {:error, env}
+
+ {:error, error} = error ->
+ error
+
+ _ ->
+ {:ok, "success"}
+ end
+ end
end
diff --git a/lib/pleroma/web/media_proxy/invalidations/script.ex b/lib/pleroma/web/media_proxy/invalidations/script.ex
index 94c79511a..6be782132 100644
--- a/lib/pleroma/web/media_proxy/invalidations/script.ex
+++ b/lib/pleroma/web/media_proxy/invalidations/script.ex
@@ -1,6 +1,14 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.MediaProxy.Invalidation.Script do
+ @moduledoc false
+
@behaviour Pleroma.Web.MediaProxy.Invalidation
+ require Logger
+
@impl Pleroma.Web.MediaProxy.Invalidation
def purge(urls, %{script_path: script_path} = _options) do
args =
@@ -9,7 +17,25 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.Script do
|> Enum.uniq()
|> Enum.join(" ")
- System.cmd(Path.expand(script_path), [args])
- {:ok, "success"}
+ 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
+ end
+
+ def purge(_, _), do: {:error, "not found script path"}
+
+ defp do_purge(path, args) do
+ System.cmd(path, args)
+ rescue
+ error -> {inspect(error), 1}
end
end
diff --git a/test/web/media_proxy/invalidations/http_test.exs b/test/web/media_proxy/invalidations/http_test.exs
new file mode 100644
index 000000000..8a3b4141c
--- /dev/null
+++ b/test/web/media_proxy/invalidations/http_test.exs
@@ -0,0 +1,35 @@
+defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
+ use ExUnit.Case
+ alias Pleroma.Web.MediaProxy.Invalidation
+
+ import ExUnit.CaptureLog
+ import Tesla.Mock
+
+ test "logs hasn't error message when request is valid" do
+ mock(fn
+ %{method: :purge, url: "http://example.com/media/example.jpg"} ->
+ %Tesla.Env{status: 200}
+ end)
+
+ refute capture_log(fn ->
+ assert Invalidation.Http.purge(
+ ["http://example.com/media/example.jpg"],
+ %{}
+ ) == {:ok, "success"}
+ end) =~ "Error while cache purge"
+ end
+
+ test "it write error message in logs when request invalid" do
+ mock(fn
+ %{method: :purge, url: "http://example.com/media/example1.jpg"} ->
+ %Tesla.Env{status: 404}
+ end)
+
+ 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
+end
diff --git a/test/web/media_proxy/invalidations/script_test.exs b/test/web/media_proxy/invalidations/script_test.exs
new file mode 100644
index 000000000..1358963ab
--- /dev/null
+++ b/test/web/media_proxy/invalidations/script_test.exs
@@ -0,0 +1,20 @@
+defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
+ use ExUnit.Case
+ alias Pleroma.Web.MediaProxy.Invalidation
+
+ import ExUnit.CaptureLog
+
+ test "it logger error when script not found" 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}\""
+
+ assert Invalidation.Script.purge(
+ ["http://example.com/media/example.jpg"],
+ %{}
+ ) == {:error, "not found script path"}
+ end
+end