From bb5e5460c4ca51cac5b9bb4216a7ddec0cdbf7ef Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Mon, 10 Jun 2019 11:55:09 +0200
Subject: [PATCH] Fix #848: Fixed invalid file extension for transcoded tracks

---
 api/funkwhale_api/music/models.py | 9 ++++++++-
 api/funkwhale_api/music/views.py  | 8 ++++++--
 api/tests/music/test_views.py     | 7 +++++--
 changes/changelog.d/848.bugfix    | 1 +
 4 files changed, 20 insertions(+), 5 deletions(-)
 create mode 100644 changes/changelog.d/848.bugfix

diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 309eb126..cf6a0b7b 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -870,7 +870,14 @@ class UploadVersion(models.Model):
 
     @property
     def filename(self):
-        return self.upload.filename
+        try:
+            return (
+                self.upload.track.full_name
+                + "."
+                + utils.MIMETYPE_TO_EXTENSION[self.mimetype]
+            )
+        except KeyError:
+            return self.upload.filename
 
     @property
     def audio_file_path(self):
diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py
index 391a4b33..4f8f35ce 100644
--- a/api/funkwhale_api/music/views.py
+++ b/api/funkwhale_api/music/views.py
@@ -285,6 +285,11 @@ def should_transcode(upload, format, max_bitrate=None):
     return format_need_transcoding or bitrate_need_transcoding
 
 
+def get_content_disposition(filename):
+    filename = "filename*=UTF-8''{}".format(urllib.parse.quote(filename))
+    return "attachment; {}".format(filename)
+
+
 def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
     f = upload
     # we update the accessed_date
@@ -342,8 +347,7 @@ def handle_serve(upload, user, format=None, max_bitrate=None, proxy_media=True):
     mapping = {"nginx": "X-Accel-Redirect", "apache2": "X-Sendfile"}
     file_header = mapping[settings.REVERSE_PROXY_TYPE]
     response[file_header] = file_path
-    filename = "filename*=UTF-8''{}".format(urllib.parse.quote(filename))
-    response["Content-Disposition"] = "attachment; {}".format(filename)
+    response["Content-Disposition"] = get_content_disposition(filename)
     if mt:
         response["Content-Type"] = mt
 
diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py
index 102b5a79..25845e73 100644
--- a/api/tests/music/test_views.py
+++ b/api/tests/music/test_views.py
@@ -1,6 +1,7 @@
 import io
 import magic
 import os
+import urllib.parse
 
 import pytest
 from django.urls import reverse
@@ -412,7 +413,7 @@ def test_handle_serve_create_mp3_version(factories, now):
     user = factories["users.User"]()
     upload = factories["music.Upload"](bitrate=42)
     response = views.handle_serve(upload, user, format="mp3")
-
+    expected_filename = upload.track.full_name + ".mp3"
     version = upload.versions.latest("id")
 
     assert version.mimetype == "audio/mpeg"
@@ -421,7 +422,9 @@ def test_handle_serve_create_mp3_version(factories, now):
     assert version.audio_file_path.endswith(".mp3")
     assert version.size == version.audio_file.size
     assert magic.from_buffer(version.audio_file.read(), mime=True) == "audio/mpeg"
-
+    assert response["Content-Disposition"] == "attachment; filename*=UTF-8''{}".format(
+        urllib.parse.quote(expected_filename)
+    )
     assert response.status_code == 200
 
 
diff --git a/changes/changelog.d/848.bugfix b/changes/changelog.d/848.bugfix
new file mode 100644
index 00000000..478a8d42
--- /dev/null
+++ b/changes/changelog.d/848.bugfix
@@ -0,0 +1 @@
+Fixed invalid file extension for transcoded tracks (#848)
-- 
GitLab