[#1509] purge media from cache after delete See merge request pleroma/pleroma!2539stable
commit
6dd1575c64
@ -0,0 +1,40 @@
|
||||
#!/bin/sh
|
||||
|
||||
# A simple shell script to delete a media from the Nginx cache.
|
||||
|
||||
SCRIPTNAME=${0##*/}
|
||||
|
||||
# NGINX cache directory
|
||||
CACHE_DIRECTORY="/tmp/pleroma-media-cache"
|
||||
|
||||
## Return the files where the items are cached.
|
||||
## $1 - the filename, can be a pattern .
|
||||
## $2 - the cache directory.
|
||||
## $3 - (optional) the number of parallel processes to run for grep.
|
||||
get_cache_files() {
|
||||
local max_parallel=${3-16}
|
||||
find $2 -maxdepth 2 -type d | xargs -P $max_parallel -n 1 grep -E Rl "^KEY:.*$1" | sort -u
|
||||
}
|
||||
|
||||
## Removes an item from the given cache zone.
|
||||
## $1 - the filename, can be a pattern .
|
||||
## $2 - the cache directory.
|
||||
purge_item() {
|
||||
for f in $(get_cache_files $1 $2); do
|
||||
echo "found file: $f"
|
||||
[ -f $f ] || continue
|
||||
echo "Deleting $f from $2."
|
||||
rm $f
|
||||
done
|
||||
} # purge_item
|
||||
|
||||
purge() {
|
||||
for url in "$@"
|
||||
do
|
||||
echo "$SCRIPTNAME delete \`$url\` from cache ($CACHE_DIRECTORY)"
|
||||
purge_item $url $CACHE_DIRECTORY
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
purge $1
|
@ -0,0 +1,26 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# 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()
|
||||
|> do_purge(urls)
|
||||
end
|
||||
|
||||
defp do_purge(true, urls) do
|
||||
provider = Config.get([:media_proxy, :invalidation, :provider])
|
||||
options = Config.get(provider)
|
||||
provider.purge(urls, options)
|
||||
end
|
||||
|
||||
defp do_purge(_, _), do: :ok
|
||||
end
|
@ -0,0 +1,40 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# 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 ->
|
||||
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
|
@ -0,0 +1,41 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# 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 =
|
||||
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
|
||||
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
|
@ -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
|
@ -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
|
Loading…
Reference in new issue