add media endpoint for XSendfile
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
cc0bdc0472
commit
d411e6790d
3 changed files with 53 additions and 2 deletions
|
@ -36,5 +36,6 @@ urlpatterns = [
|
|||
path('api/', include('toolshed.api.inventory')),
|
||||
path('api/', include('toolshed.api.info')),
|
||||
path('api/', include('toolshed.api.files')),
|
||||
path('media/', include('files.media_urls')),
|
||||
path('docs/', schema_view.with_ui('swagger', cache_timeout=0), name='api-docs'),
|
||||
]
|
||||
|
|
22
backend/files/media_urls.py
Normal file
22
backend/files/media_urls.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
from django.urls import path
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
|
||||
from files.models import File
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def media_urls(request, id, format=None):
|
||||
try:
|
||||
file = File.objects.get(file=id)
|
||||
return Response(status=status.HTTP_200_OK,
|
||||
headers={'X-Accel-Redirect': f'/redirect_media/{id}'}) # TODO Expires and Cache-Control
|
||||
|
||||
except File.DoesNotExist:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('<path:id>', media_urls),
|
||||
]
|
|
@ -2,7 +2,7 @@ from django.core.files.base import ContentFile
|
|||
from django.core.files.storage import DefaultStorage
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.test import Client
|
||||
from authentication.tests import SignatureAuthClient, ToolshedTestCase
|
||||
from authentication.tests import SignatureAuthClient, ToolshedTestCase, UserTestMixin
|
||||
from nacl.hash import sha256
|
||||
from nacl.encoding import HexEncoder
|
||||
import base64
|
||||
|
@ -95,7 +95,7 @@ class FilesTestCase(FilesTestMixin, ToolshedTestCase):
|
|||
self.assertTrue(created)
|
||||
self.assertEqual(file.file.read(), self.f['test_content4'])
|
||||
self.assertEqual(file.file.name,
|
||||
f"{self.f['hash4'][:2]}/{self.f['hash4'][2:4]}/{self.f['hash4'][4:6]}/{self.f['hash4'][6:]}")
|
||||
f"{self.f['hash4'][:2]}/{self.f['hash4'][2:4]}/{self.f['hash4'][4:6]}/{self.f['hash4'][6:]}")
|
||||
|
||||
def test_file_upload_get_or_create_fail(self):
|
||||
with transaction.atomic():
|
||||
|
@ -103,3 +103,31 @@ class FilesTestCase(FilesTestMixin, ToolshedTestCase):
|
|||
File.objects.get_or_create(hash=self.f['hash3'])
|
||||
self.assertEqual(File.objects.count(), 3)
|
||||
self.assertEqual(countdir(DefaultStorage(), ''), 3)
|
||||
|
||||
|
||||
class MediaUrlTestCase(FilesTestMixin, UserTestMixin, ToolshedTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.prepare_files()
|
||||
self.prepare_users()
|
||||
|
||||
def test_file_url(self):
|
||||
reply = client.get(
|
||||
f"/media/{self.f['hash1'][:2]}/{self.f['hash1'][2:4]}/{self.f['hash1'][4:6]}/{self.f['hash1'][6:]}",
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.headers['X-Accel-Redirect'],
|
||||
f"/redirect_media/{self.f['hash1'][:2]}/{self.f['hash1'][2:4]}/{self.f['hash1'][4:6]}/{self.f['hash1'][6:]}")
|
||||
reply = client.get(
|
||||
f"/media/{self.f['hash2'][:2]}/{self.f['hash2'][2:4]}/{self.f['hash2'][4:6]}/{self.f['hash2'][6:]}",
|
||||
self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 200)
|
||||
self.assertEqual(reply.headers['X-Accel-Redirect'],
|
||||
f"/redirect_media/{self.f['hash2'][:2]}/{self.f['hash2'][2:4]}/{self.f['hash2'][4:6]}/{self.f['hash2'][6:]}")
|
||||
|
||||
def test_file_url_fail(self):
|
||||
reply = client.get('/media/{}/'.format('nonexistent'), self.f['local_user1'])
|
||||
self.assertEqual(reply.status_code, 404)
|
||||
self.assertTrue('X-Accel-Redirect' not in reply.headers)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue