summaryrefslogtreecommitdiff
path: root/test/web/media_proxy/media_proxy_controller_test.exs
diff options
context:
space:
mode:
Diffstat (limited to 'test/web/media_proxy/media_proxy_controller_test.exs')
-rw-r--r--test/web/media_proxy/media_proxy_controller_test.exs327
1 files changed, 274 insertions, 53 deletions
diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs
index d4db44c63..e9b584822 100644
--- a/test/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/web/media_proxy/media_proxy_controller_test.exs
@@ -8,34 +8,34 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
import Mock
alias Pleroma.Web.MediaProxy
- alias Pleroma.Web.MediaProxy.MediaProxyController
alias Plug.Conn
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
- test "it returns 404 when MediaProxy disabled", %{conn: conn} do
- clear_config([:media_proxy, :enabled], false)
-
- assert %Conn{
- status: 404,
- resp_body: "Not Found"
- } = get(conn, "/proxy/hhgfh/eeeee")
-
- assert %Conn{
- status: 404,
- resp_body: "Not Found"
- } = get(conn, "/proxy/hhgfh/eeee/fff")
- end
-
- describe "" do
+ describe "Media Proxy" do
setup do
clear_config([:media_proxy, :enabled], true)
clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
+
[url: MediaProxy.encode_url("https://google.fn/test.png")]
end
+ test "it returns 404 when disabled", %{conn: conn} do
+ clear_config([:media_proxy, :enabled], false)
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/hhgfh/eeeee")
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/hhgfh/eeee/fff")
+ end
+
test "it returns 403 for invalid signature", %{conn: conn, url: url} do
Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
%{path: path} = URI.parse(url)
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
} = get(conn, "/proxy/hhgfh/eeee/fff")
end
- test "redirects on valid url when filename is invalidated", %{conn: conn, url: url} do
+ test "redirects to valid url when filename is invalidated", %{conn: conn, url: url} do
invalid_url = String.replace(url, "test.png", "test-file.png")
response = get(conn, invalid_url)
assert response.status == 302
@@ -80,42 +80,263 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
end
end
- describe "filename_matches/3" do
- test "preserves the encoded or decoded path" do
- assert MediaProxyController.filename_matches(
- %{"filename" => "/Hello world.jpg"},
- "/Hello world.jpg",
- "http://pleroma.social/Hello world.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/Hello%20world.jpg"},
- "/Hello%20world.jpg",
- "http://pleroma.social/Hello%20world.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"},
- "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
- "http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
- ) == :ok
-
- assert MediaProxyController.filename_matches(
- %{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jp"},
- "/my%2Flong%2Furl%2F2019%2F07%2FS.jp",
- "http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
- ) == {:wrong_filename, "my%2Flong%2Furl%2F2019%2F07%2FS.jpg"}
- end
-
- test "encoded url are tried to match for proxy as `conn.request_path` encodes the url" do
- # conn.request_path will return encoded url
- request_path = "/ANALYSE-DAI-_-LE-STABLECOIN-100-D%C3%89CENTRALIS%C3%89-BQ.jpg"
-
- assert MediaProxyController.filename_matches(
- true,
- request_path,
- "https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg"
- ) == :ok
+ describe "Media Preview Proxy" do
+ def assert_dependencies_installed do
+ missing_dependencies = Pleroma.Helpers.MediaHelper.missing_dependencies()
+
+ assert missing_dependencies == [],
+ "Error: missing dependencies (please refer to `docs/installation`): #{
+ inspect(missing_dependencies)
+ }"
+ end
+
+ setup do
+ clear_config([:media_proxy, :enabled], true)
+ clear_config([:media_preview_proxy, :enabled], true)
+ clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
+
+ original_url = "https://google.fn/test.png"
+
+ [
+ url: MediaProxy.encode_preview_url(original_url),
+ media_proxy_url: MediaProxy.encode_url(original_url)
+ ]
+ end
+
+ test "returns 404 when media proxy is disabled", %{conn: conn} do
+ clear_config([:media_proxy, :enabled], false)
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/preview/hhgfh/eeeee")
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/preview/hhgfh/fff")
+ end
+
+ test "returns 404 when disabled", %{conn: conn} do
+ clear_config([:media_preview_proxy, :enabled], false)
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/preview/hhgfh/eeeee")
+
+ assert %Conn{
+ status: 404,
+ resp_body: "Not Found"
+ } = get(conn, "/proxy/preview/hhgfh/fff")
+ end
+
+ test "it returns 403 for invalid signature", %{conn: conn, url: url} do
+ Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
+ %{path: path} = URI.parse(url)
+
+ assert %Conn{
+ status: 403,
+ resp_body: "Forbidden"
+ } = get(conn, path)
+
+ assert %Conn{
+ status: 403,
+ resp_body: "Forbidden"
+ } = get(conn, "/proxy/preview/hhgfh/eeee")
+
+ assert %Conn{
+ status: 403,
+ resp_body: "Forbidden"
+ } = get(conn, "/proxy/preview/hhgfh/eeee/fff")
+ end
+
+ test "redirects to valid url when filename is invalidated", %{conn: conn, url: url} do
+ invalid_url = String.replace(url, "test.png", "test-file.png")
+ response = get(conn, invalid_url)
+ assert response.status == 302
+ assert redirected_to(response) == url
+ end
+
+ test "responds with 424 Failed Dependency if HEAD request to media proxy fails", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 500, body: ""}
+ end)
+
+ response = get(conn, url)
+ assert response.status == 424
+ assert response.resp_body == "Can't fetch HTTP headers (HTTP 500)."
+ end
+
+ test "redirects to media proxy URI on unsupported content type", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
+ end)
+
+ response = get(conn, url)
+ assert response.status == 302
+ assert redirected_to(response) == media_proxy_url
+ end
+
+ test "with `static=true` and GIF image preview requested, responds with JPEG image", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ assert_dependencies_installed()
+
+ # Setting a high :min_content_length to ensure this scenario is not affected by its logic
+ clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
+
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{
+ status: 200,
+ body: "",
+ headers: [{"content-type", "image/gif"}, {"content-length", "1001718"}]
+ }
+
+ %{method: :get, url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/image.gif")}
+ end)
+
+ response = get(conn, url <> "?static=true")
+
+ assert response.status == 200
+ assert Conn.get_resp_header(response, "content-type") == ["image/jpeg"]
+ assert response.resp_body != ""
+ end
+
+ test "with GIF image preview requested and no `static` param, redirects to media proxy URI",
+ %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
+ end)
+
+ response = get(conn, url)
+
+ assert response.status == 302
+ assert redirected_to(response) == media_proxy_url
+ end
+
+ test "with `static` param and non-GIF image preview requested, " <>
+ "redirects to media preview proxy URI without `static` param",
+ %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
+ end)
+
+ response = get(conn, url <> "?static=true")
+
+ assert response.status == 302
+ assert redirected_to(response) == url
+ end
+
+ test "with :min_content_length setting not matched by Content-Length header, " <>
+ "redirects to media proxy URI",
+ %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ clear_config([:media_preview_proxy, :min_content_length], 100_000)
+
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{
+ status: 200,
+ body: "",
+ headers: [{"content-type", "image/gif"}, {"content-length", "5000"}]
+ }
+ end)
+
+ response = get(conn, url)
+
+ assert response.status == 302
+ assert redirected_to(response) == media_proxy_url
+ end
+
+ test "thumbnails PNG images into PNG", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ assert_dependencies_installed()
+
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
+
+ %{method: :get, url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/image.png")}
+ end)
+
+ response = get(conn, url)
+
+ assert response.status == 200
+ assert Conn.get_resp_header(response, "content-type") == ["image/png"]
+ assert response.resp_body != ""
+ end
+
+ test "thumbnails JPEG images into JPEG", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ assert_dependencies_installed()
+
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
+
+ %{method: :get, url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
+ end)
+
+ response = get(conn, url)
+
+ assert response.status == 200
+ assert Conn.get_resp_header(response, "content-type") == ["image/jpeg"]
+ assert response.resp_body != ""
+ end
+
+ test "redirects to media proxy URI in case of thumbnailing error", %{
+ conn: conn,
+ url: url,
+ media_proxy_url: media_proxy_url
+ } do
+ Tesla.Mock.mock(fn
+ %{method: "head", url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
+
+ %{method: :get, url: ^media_proxy_url} ->
+ %Tesla.Env{status: 200, body: "<html><body>error</body></html>"}
+ end)
+
+ response = get(conn, url)
+
+ assert response.status == 302
+ assert redirected_to(response) == media_proxy_url
end
end
end