mirror of
https://github.com/jazzband/django-downloadview.git
synced 2026-03-16 22:40:25 +00:00
Merge pull request #212 from sevdog/xaccel-headers
Allow XResponses to keep original headers provided to base response
This commit is contained in:
commit
1b294f00fa
17 changed files with 130 additions and 10 deletions
|
|
@ -43,3 +43,19 @@ class OptimizedByDecoratorTestCase(django.test.TestCase):
|
|||
basename="hello-world.txt",
|
||||
file_path="/apache-optimized-by-decorator/hello-world.txt",
|
||||
)
|
||||
|
||||
|
||||
class ModifiedHeadersTestCase(django.test.TestCase):
|
||||
def test_response(self):
|
||||
"""'apache:modified_headers' returns X-Sendfile response."""
|
||||
setup_file()
|
||||
url = reverse("apache:modified_headers")
|
||||
response = self.client.get(url)
|
||||
assert_x_sendfile(
|
||||
self,
|
||||
response,
|
||||
content_type="text/plain; charset=utf-8",
|
||||
basename="hello-world.txt",
|
||||
file_path="/apache-modified-headers/hello-world.txt",
|
||||
)
|
||||
self.assertEqual(response['X-Test'], 'header')
|
||||
|
|
|
|||
|
|
@ -15,4 +15,9 @@ urlpatterns = [
|
|||
views.optimized_by_decorator,
|
||||
name="optimized_by_decorator",
|
||||
),
|
||||
path(
|
||||
"modified_headers/",
|
||||
views.modified_headers,
|
||||
name="modified_headers",
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -22,3 +22,17 @@ optimized_by_decorator = x_sendfile(
|
|||
source_url=storage.base_url,
|
||||
destination_dir="/apache-optimized-by-decorator/",
|
||||
)
|
||||
|
||||
|
||||
def _modified_headers(request):
|
||||
view = StorageDownloadView.as_view(storage=storage, path="hello-world.txt")
|
||||
response = view(request)
|
||||
response["X-Test"] = 'header'
|
||||
return response
|
||||
|
||||
|
||||
modified_headers = x_sendfile(
|
||||
_modified_headers,
|
||||
source_url=storage.base_url,
|
||||
destination_dir="/apache-modified-headers/",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -43,3 +43,19 @@ class OptimizedByDecoratorTestCase(django.test.TestCase):
|
|||
basename="hello-world.txt",
|
||||
file_path="/lighttpd-optimized-by-decorator/hello-world.txt",
|
||||
)
|
||||
|
||||
|
||||
class ModifiedHeadersTestCase(django.test.TestCase):
|
||||
def test_response(self):
|
||||
"""'lighttpd:modified_headers' returns X-Sendfile response."""
|
||||
setup_file()
|
||||
url = reverse("lighttpd:modified_headers")
|
||||
response = self.client.get(url)
|
||||
assert_x_sendfile(
|
||||
self,
|
||||
response,
|
||||
content_type="text/plain; charset=utf-8",
|
||||
basename="hello-world.txt",
|
||||
file_path="/lighttpd-modified-headers/hello-world.txt",
|
||||
)
|
||||
self.assertEqual(response['X-Test'], 'header')
|
||||
|
|
|
|||
|
|
@ -15,4 +15,9 @@ urlpatterns = [
|
|||
views.optimized_by_decorator,
|
||||
name="optimized_by_decorator",
|
||||
),
|
||||
path(
|
||||
"modified_headers/",
|
||||
views.modified_headers,
|
||||
name="modified_headers",
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -22,3 +22,17 @@ optimized_by_decorator = x_sendfile(
|
|||
source_url=storage.base_url,
|
||||
destination_dir="/lighttpd-optimized-by-decorator/",
|
||||
)
|
||||
|
||||
|
||||
def _modified_headers(request):
|
||||
view = StorageDownloadView.as_view(storage=storage, path="hello-world.txt")
|
||||
response = view(request)
|
||||
response["X-Test"] = 'header'
|
||||
return response
|
||||
|
||||
|
||||
modified_headers = x_sendfile(
|
||||
_modified_headers,
|
||||
source_url=storage.base_url,
|
||||
destination_dir="/lighttpd-modified-headers/",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -51,3 +51,23 @@ class OptimizedByDecoratorTestCase(django.test.TestCase):
|
|||
with_buffering=None,
|
||||
limit_rate=None,
|
||||
)
|
||||
|
||||
|
||||
class ModifiedHeadersTestCase(django.test.TestCase):
|
||||
def test_response(self):
|
||||
"""'nginx:modified_headers' returns X-Sendfile response."""
|
||||
setup_file()
|
||||
url = reverse("nginx:modified_headers")
|
||||
response = self.client.get(url)
|
||||
assert_x_accel_redirect(
|
||||
self,
|
||||
response,
|
||||
content_type="text/plain; charset=utf-8",
|
||||
charset="utf-8",
|
||||
basename="hello-world.txt",
|
||||
redirect_url="/nginx-modified-headers/hello-world.txt",
|
||||
expires=None,
|
||||
with_buffering=None,
|
||||
limit_rate=None,
|
||||
)
|
||||
self.assertEqual(response['X-Test'], 'header')
|
||||
|
|
|
|||
|
|
@ -16,4 +16,9 @@ urlpatterns = [
|
|||
views.optimized_by_decorator,
|
||||
name="optimized_by_decorator",
|
||||
),
|
||||
path(
|
||||
"modified_headers/",
|
||||
views.modified_headers,
|
||||
name="modified_headers",
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -22,3 +22,17 @@ optimized_by_decorator = x_accel_redirect(
|
|||
source_url=storage.base_url,
|
||||
destination_url="/nginx-optimized-by-decorator/",
|
||||
)
|
||||
|
||||
|
||||
def _modified_headers(request):
|
||||
view = StorageDownloadView.as_view(storage=storage, path="hello-world.txt")
|
||||
response = view(request)
|
||||
response["X-Test"] = 'header'
|
||||
return response
|
||||
|
||||
|
||||
modified_headers = x_accel_redirect(
|
||||
_modified_headers,
|
||||
source_url=storage.base_url,
|
||||
destination_url="/nginx-modified-headers/",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -32,4 +32,5 @@ class XSendfileMiddleware(ProxiedDownloadMiddleware):
|
|||
content_type=response["Content-Type"],
|
||||
basename=response.basename,
|
||||
attachment=response.attachment,
|
||||
headers=response.headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@ from django_downloadview.response import ProxiedDownloadResponse, content_dispos
|
|||
class XSendfileResponse(ProxiedDownloadResponse):
|
||||
"Delegates serving file to Apache via X-Sendfile header."
|
||||
|
||||
def __init__(self, file_path, content_type, basename=None, attachment=True):
|
||||
def __init__(self, file_path, content_type, basename=None, attachment=True, headers=None):
|
||||
"""Return a HttpResponse with headers for Apache X-Sendfile."""
|
||||
super().__init__(content_type=content_type)
|
||||
# content-type must be provided only as keyword argument to response
|
||||
if headers and content_type:
|
||||
headers.pop('Content-Type', None)
|
||||
super().__init__(content_type=content_type, headers=headers)
|
||||
if attachment:
|
||||
self.basename = basename or os.path.basename(file_path)
|
||||
self["Content-Disposition"] = content_disposition(self.basename)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django_downloadview.apache.response import XSendfileResponse
|
||||
|
||||
|
||||
class XSendfileValidator(object):
|
||||
class XSendfileValidator:
|
||||
"""Utility class to validate XSendfileResponse instances.
|
||||
|
||||
See also :py:func:`assert_x_sendfile` shortcut function.
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ class XSendfileMiddleware(ProxiedDownloadMiddleware):
|
|||
self, get_response=None, source_dir=None, source_url=None, destination_dir=None
|
||||
):
|
||||
"""Constructor."""
|
||||
super(XSendfileMiddleware, self).__init__(
|
||||
get_response, source_dir, source_url, destination_dir
|
||||
)
|
||||
super().__init__(get_response, source_dir, source_url, destination_dir)
|
||||
|
||||
def process_download_response(self, request, response):
|
||||
"""Replace DownloadResponse instances by XSendfileResponse ones."""
|
||||
|
|
@ -34,4 +32,5 @@ class XSendfileMiddleware(ProxiedDownloadMiddleware):
|
|||
content_type=response["Content-Type"],
|
||||
basename=response.basename,
|
||||
attachment=response.attachment,
|
||||
headers=response.headers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@ from django_downloadview.response import ProxiedDownloadResponse, content_dispos
|
|||
class XSendfileResponse(ProxiedDownloadResponse):
|
||||
"Delegates serving file to Lighttpd via X-Sendfile header."
|
||||
|
||||
def __init__(self, file_path, content_type, basename=None, attachment=True):
|
||||
def __init__(self, file_path, content_type, basename=None, attachment=True, headers=None):
|
||||
"""Return a HttpResponse with headers for Lighttpd X-Sendfile."""
|
||||
super(XSendfileResponse, self).__init__(content_type=content_type)
|
||||
# content-type must be porvided only as keyword argument to response
|
||||
if headers and content_type:
|
||||
headers.pop('Content-Type', None)
|
||||
super().__init__(content_type=content_type, headers=headers)
|
||||
if attachment:
|
||||
self.basename = basename or os.path.basename(file_path)
|
||||
self["Content-Disposition"] = content_disposition(self.basename)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ class XAccelRedirectMiddleware(ProxiedDownloadMiddleware):
|
|||
with_buffering=self.with_buffering,
|
||||
limit_rate=self.limit_rate,
|
||||
attachment=response.attachment,
|
||||
headers=response.headers,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,13 @@ class XAccelRedirectResponse(ProxiedDownloadResponse):
|
|||
with_buffering=None,
|
||||
limit_rate=None,
|
||||
attachment=True,
|
||||
headers=None,
|
||||
):
|
||||
"""Return a HttpResponse with headers for Nginx X-Accel-Redirect."""
|
||||
super(XAccelRedirectResponse, self).__init__(content_type=content_type)
|
||||
# content-type must be porvided only as keyword argument to response
|
||||
if headers and content_type:
|
||||
headers.pop('Content-Type', None)
|
||||
super().__init__(content_type=content_type, headers=headers)
|
||||
if attachment:
|
||||
self.basename = basename or url_basename(redirect_url, content_type)
|
||||
self["Content-Disposition"] = content_disposition(self.basename)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django_downloadview.nginx.response import XAccelRedirectResponse
|
||||
|
||||
|
||||
class XAccelRedirectValidator(object):
|
||||
class XAccelRedirectValidator:
|
||||
"""Utility class to validate XAccelRedirectResponse instances.
|
||||
|
||||
See also :py:func:`assert_x_accel_redirect` shortcut function.
|
||||
|
|
|
|||
Loading…
Reference in a new issue