diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index c0effbac2..9de785116 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -320,6 +320,10 @@ def get_file_path(audio_file): ) path = "/music" + audio_file.replace(prefix, "", 1) if path.startswith("http://") or path.startswith("https://"): + protocol, remainder = path.split("://", 1) + hostname, r_path = remainder.split("/", 1) + r_path = urllib.parse.quote(r_path) + path = protocol + "://" + hostname + "/" + r_path return (settings.PROTECT_FILES_PATH + "/media/" + path).encode("utf-8") # needed to serve files with % or ? chars path = urllib.parse.quote(path) diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py index 0339437d4..22f7da635 100644 --- a/api/tests/music/test_views.py +++ b/api/tests/music/test_views.py @@ -247,6 +247,18 @@ def test_serve_file_in_place_nginx_encode_url( assert response["X-Accel-Redirect"] == expected +def test_serve_s3_nginx_encode_url(mocker, settings): + settings.PROTECT_FILE_PATH = "/_protected/media" + settings.REVERSE_PROXY_TYPE = "nginx" + audio_file = mocker.Mock(url="https://s3.storage.example/path/to/mp3?aws=signature") + + expected = ( + b"/_protected/media/https://s3.storage.example/path/to/mp3%3Faws%3Dsignature" + ) + + assert views.get_file_path(audio_file) == expected + + @pytest.mark.parametrize( "proxy,serve_path,expected", [ diff --git a/changes/changelog.d/s3-proxy.bugfix b/changes/changelog.d/s3-proxy.bugfix new file mode 100644 index 000000000..0afe65caf --- /dev/null +++ b/changes/changelog.d/s3-proxy.bugfix @@ -0,0 +1 @@ +Fix audio serving issues under S3/nginx when signatures are enabled