Storage and View to send X-Accel-Redirect (or X-Sendfile) header to nginx (or apache) reverse-proxy
Project description
django-reverse-proxy-send-file
Sumary
This package help writing views which use the X-Accel-Redirect
header to have nginx
serving files but still allow a permission check at django's side
Intro
The storage.ReverseProxySendFileFileSystemStorage
class is a drop-in replacement of django's FileSystemStorage
which make FileField (or ImageField) url to use the REVERSE_PROXY_SENDFILE_MEDIA_URL
settings base url instead of MEDIA_URL
The storage.ReverseProxySendFileStorageMixin
allow you to apply the overriden base_url
on any storage class
The ReverseProxySendFileView
class handle GET request and return an empty response with nginx's X-Accel-Redirect
header to order nginx to return the file at given path. The REVERSE_PROXY_SENDFILE_MEDIA_ROOT
setting must be defined in the nginx context si it can find the file
The ReverseProxySendFileView
can be overrided to implement a custom check_permission
method which verify is the current user is allowed to download the resource.
Installation
Install the django-reverse-proxy-send-file
pypi package.
ex:
poetry add django-reverse-proxy-send-file
pip install django-reverse-proxy-send-file
Usage
See example section bellow
Settings
Name | Default | Description |
---|---|---|
REVERSE_PROXY_SENDFILE_MEDIA_ROOT | MEDIA_ROOT | Base path in django's context where to store media files when uploaded (used by Storage class) |
REVERSE_PROXY_SENDFILE_MEDIA_URL | "smedia/" |
URL that handle the resources that should be served by the reverse proxy. |
REVERSE_PROXY_SENDFILE_REVERSE_PROXY_ROOT | "smedia/" |
Base path in reverse-proxy's context which is sent back to reverse-proxy in header so it can find the file |
REVERSE_PROXY_SENDFILE_MODE | "nginx" |
Possible values: "nginx" or "apache" . nginx mode will use X-Accel-Redirect header.apache mode will use X-Sendfile |
REVERSE_PROXY_SENDFILE_HEADER_NAME | None |
A custom header name. If set this header will be used regardless REVERSE_PROXY_SENDFILE_MODE setting. |
REVERSE_PROXY_SENDFILE_DEBUG_SERVE_RESOURCE | True |
In django's DEBUG mode, the resource is directly served by the dev server. |
Exemple
settings.py
...
REVERSE_PROXY_SENDFILE_MEDIA_URL = "smedia/"
REVERSE_PROXY_SENDFILE_MEDIA_ROOT = "/django_path/to/smedia/"
REVERSE_PROXY_SENDFILE_REVERSE_PROXY_ROOT = "/nginx_path/to/smedia/"
...
models.py
from django.contrib.auth.models import User
from reverse_proxy_send_file.storage import ReverseProxySendFileFileSystemStorage
class MyModel(models.Model):
...
user = models.ForeignKey(User, on_delete=models.CASCADE)
my_file = models.FileField(
"My file",
upload_to="my_files/",
storage=ReverseProxySendFileFileSystemStorage(),
)
...
views.py
from django.http import Http404
from reverse_proxy_send_file.views import ReverseProxySendFileView
class ReverseProxySendFileMyFileView(ReverseProxySendFileView):
def check_permission(self, request, resource_url, *args, **kwargs):
obj_qs = MyModel.objects.filter(my_file=resource_url)
if not obj_qs.exists():
raise Http404()
return obj_qs.filter(user=request.user).exists()
urls.py
from django.conf import settings
from views import ReverseProxySendFileMyFileView
urlpatterns = [
...
re_path(
settings.REVERSE_PROXY_SENDFILE_MEDIA_URL + "(?P<resource_url>my_files/.*)$",
views.ReverseProxySendFileMyFileView.as_view(),
name="reverse_proxy_send_file",
),
...
]
- User upload file. The file is stored in
/django_path/to/smedia/my_files/blop.pdf
- User access
/smedia/my_files/blop.pdf
- A django request is performed and it check file access permission for current user (in check_permission).
-
- If the user is allowed return a HTTP response with header :
X-Accel-Redirect=/nginx_path/to/smedia/my_files/blop.pdf
(Nginx will use it to send the file to the client) - If the file os not found return a
404 note found
. - If the user id forbidden, return a
403 response forbidden
- If the user is allowed return a HTTP response with header :
Setup dev environnement
# install dev dependencies
poetry install --no-root
# install git pre-commit
pre-commit install
Run tests
Use tox
command to run all tests on all supported python versions
Examples:
tox
tox -e py38-django40
tox -f py39
Build package and publish on PyPI
Change version number in pyproject.toml
poetry build
poetry publish
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_reverse_proxy_send_file-1.0.2.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | b6e722ae8d81fabff68448e9f5d27d25ea96e08bafc2cb583aecd9a2d7670fa0 |
|
MD5 | 5a284ab0bc7e940845747a21b0b44652 |
|
BLAKE2b-256 | 81e3d1604d9502dfe2d80aacb4e88910dd0ca867ef87cb7656acac3d194661d0 |
Hashes for django_reverse_proxy_send_file-1.0.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 00051aacb7601937b7fc054373f8292221c0fb34548230659967498a27069dea |
|
MD5 | 1e53d6d9788d58ead2440c479ac12f26 |
|
BLAKE2b-256 | 8894c971f5be19c32dfecd334ec4c7666bbd66a2bdbe69ef6349f1cddf580170 |