From f0bea39d6a09ac09579f6fbdceac3477503e9601 Mon Sep 17 00:00:00 2001 From: Eliot Berriot Date: Tue, 1 Oct 2019 10:57:14 +0200 Subject: [PATCH] Fix #924: in-place imported files not playing under nginx when filename contains ? or % --- api/funkwhale_api/music/views.py | 4 +++- api/tests/music/test_views.py | 25 +++++++++++++++++++++++-- changes/changelog.d/924.bugfix | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 changes/changelog.d/924.bugfix diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index 4783a8d45..c0effbac2 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -1,6 +1,6 @@ import datetime import logging -import urllib +import urllib.parse from django.conf import settings from django.db import transaction @@ -321,6 +321,8 @@ def get_file_path(audio_file): path = "/music" + audio_file.replace(prefix, "", 1) if path.startswith("http://") or path.startswith("https://"): return (settings.PROTECT_FILES_PATH + "/media/" + path).encode("utf-8") + # needed to serve files with % or ? chars + path = urllib.parse.quote(path) return (settings.PROTECT_FILES_PATH + path).encode("utf-8") if t == "apache2": try: diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py index 4a423ddb1..0339437d4 100644 --- a/api/tests/music/test_views.py +++ b/api/tests/music/test_views.py @@ -226,13 +226,34 @@ def test_serve_file_in_place( assert response[headers[proxy]] == expected +def test_serve_file_in_place_nginx_encode_url( + factories, api_client, preferences, settings +): + preferences["common__api_authentication_required"] = False + settings.PROTECT_FILE_PATH = "/_protected/music" + settings.REVERSE_PROXY_TYPE = "nginx" + settings.MUSIC_DIRECTORY_PATH = "/app/music" + settings.MUSIC_DIRECTORY_SERVE_PATH = "/app/music" + upload = factories["music.Upload"]( + in_place=True, + import_status="finished", + source="file:///app/music/hello/world%?.mp3", + library__privacy_level="everyone", + ) + response = api_client.get(upload.track.listen_url) + expected = "/_protected/music/hello/world%25%3F.mp3" + + assert response.status_code == 200 + assert response["X-Accel-Redirect"] == expected + + @pytest.mark.parametrize( "proxy,serve_path,expected", [ ("apache2", "/host/music", "/host/music/hello/worldéà.mp3"), ("apache2", "/app/music", "/app/music/hello/worldéà.mp3"), - ("nginx", "/host/music", "/_protected/music/hello/worldéà.mp3"), - ("nginx", "/app/music", "/_protected/music/hello/worldéà.mp3"), + ("nginx", "/host/music", "/_protected/music/hello/world%C3%A9%C3%A0.mp3"), + ("nginx", "/app/music", "/_protected/music/hello/world%C3%A9%C3%A0.mp3"), ], ) def test_serve_file_in_place_utf8( diff --git a/changes/changelog.d/924.bugfix b/changes/changelog.d/924.bugfix new file mode 100644 index 000000000..c5986581a --- /dev/null +++ b/changes/changelog.d/924.bugfix @@ -0,0 +1 @@ +Fixed in-place imported files not playing under nginx when filename contains ? or % (#924)