Merge branch 'apache-x-sendfile-header' into 'develop'

Ensure we return correct paths when using Apache as a reverse proxy

See merge request funkwhale/funkwhale!157
merge-requests/165/head
Eliot Berriot 2018-04-22 14:49:26 +00:00
commit 48c9a8bd55
3 zmienionych plików z 57 dodań i 13 usunięć

Wyświetl plik

@ -205,6 +205,25 @@ class TrackViewSet(
return Response(serializer.data) return Response(serializer.data)
def get_file_path(audio_file):
t = settings.REVERSE_PROXY_TYPE
if t == 'nginx':
# we have to use the internal locations
try:
path = audio_file.url
except AttributeError:
# a path was given
path = '/music' + audio_file
return settings.PROTECT_FILES_PATH + path
if t == 'apache2':
try:
path = audio_file.path
except AttributeError:
# a path was given
path = audio_file
return path
class TrackFileViewSet(viewsets.ReadOnlyModelViewSet): class TrackFileViewSet(viewsets.ReadOnlyModelViewSet):
queryset = (models.TrackFile.objects.all().order_by('-id')) queryset = (models.TrackFile.objects.all().order_by('-id'))
serializer_class = serializers.TrackFileSerializer serializer_class = serializers.TrackFileSerializer
@ -243,24 +262,20 @@ class TrackFileViewSet(viewsets.ReadOnlyModelViewSet):
library_track = qs.get(pk=library_track.pk) library_track = qs.get(pk=library_track.pk)
library_track.download_audio() library_track.download_audio()
audio_file = library_track.audio_file audio_file = library_track.audio_file
file_path = '{}{}'.format( file_path = get_file_path(audio_file)
settings.PROTECT_FILES_PATH,
audio_file.url)
mt = library_track.audio_mimetype mt = library_track.audio_mimetype
elif audio_file: elif audio_file:
file_path = '{}{}'.format( file_path = get_file_path(audio_file)
settings.PROTECT_FILES_PATH,
audio_file.url)
elif f.source and f.source.startswith('file://'): elif f.source and f.source.startswith('file://'):
file_path = '{}{}'.format( file_path = get_file_path(f.serve_from_source_path)
settings.PROTECT_FILES_PATH + '/music',
f.serve_from_source_path)
response = Response() response = Response()
filename = f.filename filename = f.filename
if settings.REVERSE_PROXY_TYPE == 'apache2': mapping = {
response['X-Sendfile'] = file_path 'nginx': 'X-Accel-Redirect',
elif settings.REVERSE_PROXY_TYPE == 'nginx': 'apache2': 'X-Sendfile',
response['X-Accel-Redirect'] = file_path }
file_header = mapping[settings.REVERSE_PROXY_TYPE]
response[file_header] = file_path
filename = "filename*=UTF-8''{}".format( filename = "filename*=UTF-8''{}".format(
urllib.parse.quote(filename)) urllib.parse.quote(filename))
response["Content-Disposition"] = "attachment; {}".format(filename) response["Content-Disposition"] = "attachment; {}".format(filename)

Wyświetl plik

@ -76,6 +76,31 @@ def test_can_serve_track_file_as_remote_library_deny_not_following(
assert response.status_code == 403 assert response.status_code == 403
def test_serve_file_apache(factories, api_client, settings):
settings.PROTECT_AUDIO_FILES = False
settings.REVERSE_PROXY_TYPE = 'apache2'
tf = factories['music.TrackFile']()
response = api_client.get(tf.path)
assert response.status_code == 200
assert response['X-Sendfile'] == tf.audio_file.path
def test_serve_file_apache_in_place(factories, api_client, settings):
settings.PROTECT_AUDIO_FILES = False
settings.REVERSE_PROXY_TYPE = 'apache2'
settings.MUSIC_DIRECTORY_PATH = '/music'
settings.MUSIC_DIRECTORY_SERVE_PATH = '/host/music'
track_file = factories['music.TrackFile'](
in_place=True,
source='file:///music/test.ogg')
response = api_client.get(track_file.path)
assert response.status_code == 200
assert response['X-Sendfile'] == '/host/music/test.ogg'
def test_can_proxy_remote_track( def test_can_proxy_remote_track(
factories, settings, api_client, r_mock): factories, settings, api_client, r_mock):
settings.PROTECT_AUDIO_FILES = False settings.PROTECT_AUDIO_FILES = False

Wyświetl plik

@ -41,6 +41,10 @@ FUNKWHALE_API_PORT=5000
# your instance # your instance
FUNKWHALE_URL=https://yourdomain.funwhale FUNKWHALE_URL=https://yourdomain.funwhale
# Depending on the reverse proxy used in front of your funkwhale instance,
# the API will use different kind of headers to serve audio files
# Allowed values: nginx, apache2
REVERSE_PROXY_TYPE=nginx
# API/Django configuration # API/Django configuration