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.ReverseProxySendFileStorageFileSystemStorage
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
REVERSE_PROXY_SENDFILE_MEDIA_ROOT
Default to django's MEDIA_ROOT
Base path in django's context where to store media files when uploaded (used by Storage class)
REVERSE_PROXY_SENDFILE_MEDIA_URL
Default to "smedia/"
URL that handle the resources that should be served by the reverse proxy.
REVERSE_PROXY_SENDFILE_REVERSE_PROXY_ROOT
Default to "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
Default to "nginx"
Possible values: "nginx"
or "apache"
nginx
mode will use X-Accel-Redirect
header whereas apache
mode will use X-Sendfile
REVERSE_PROXY_SENDFILE_HEADER_NAME
Default to None
Enter a custom header name. If set this header will be used regardless REVERSE_PROXY_SENDFILE_MODE
setting.
REVERSE_PROXY_SENDFILE_DEBUG_SERVE_RESOURCE
Default to 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 ReverseProxySendFileStorageFileSystemStorage
class MyModel(models.Model):
...
user = models.ForeignKey(User, on_delete=models.CASCADE)
my_file = models.FileField(
"My file",
upload_to="my_files/",
storage=ReverseProxySendFileStorageFileSystemStorage(),
)
...
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
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
File details
Details for the file django_reverse_proxy_send_file-1.0.0.tar.gz
.
File metadata
- Download URL: django_reverse_proxy_send_file-1.0.0.tar.gz
- Upload date:
- Size: 4.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.2 CPython/3.10.9 Linux/6.1.9-arch1-1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2889a1ff9de449438ef0aab17d55eb7daa00a9691d3299593d9e4a095afef51a |
|
MD5 | b4856a749b2d074ed0be43b86ccd0dc7 |
|
BLAKE2b-256 | b5a5040127fb2cfce87b70ee1e8e885615d1b4836a26ebecbbc291fcd300cccb |
Provenance
File details
Details for the file django_reverse_proxy_send_file-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: django_reverse_proxy_send_file-1.0.0-py3-none-any.whl
- Upload date:
- Size: 4.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.3.2 CPython/3.10.9 Linux/6.1.9-arch1-1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | eb111f82e0c98bc7aac2529716835852e5f4adb4f8948c753940866ad05eb995 |
|
MD5 | 443654294709dac3d5dfbd7947c56d29 |
|
BLAKE2b-256 | 0f9654418ee9daa062ce16b2489392deae62e19d2ae6799ba6150a957ee006f2 |