xsendfile etc wrapper

Related tags

Djangodjango-sendfile
Overview

Django Sendfile

This is a wrapper around web-server specific methods for sending files to web clients. This is useful when Django needs to check permissions associated files, but does not want to serve the actual bytes of the file itself. i.e. as serving large files is not what Django is made for.

Note this should not be used for regular file serving (e.g. css etc), only for cases where you need Django to do some work before serving the actual file.

The interface is a single function sendfile(request, filename, attachment=False, attachment_filename=None), which returns a HTTPResponse object.

from sendfile import sendfile

# send myfile.pdf to user
return sendfile(request, '/home/john/myfile.pdf')

# send myfile.pdf as an attachment (with name myfile.pdf)
return sendfile(request, '/home/john/myfile.pdf', attachment=True)

# send myfile.pdf as an attachment with a different name
return sendfile(request, '/home/john/myfile.pdf', attachment=True, attachment_filename='full-name.pdf')

Backends are specified using the setting SENDFILE_BACKEND. Currenly available backends are:

  • sendfile.backends.development - for use with django development server only. DO NOT USE IN PRODUCTION
  • sendfile.backends.simple - "simple" backend that uses Django file objects to attempt to stream files from disk (note middleware may cause files to be loaded fully into memory)
  • sendfile.backends.xsendfile - sets X-Sendfile header (as used by mod_xsendfile/apache and lighthttpd)
  • sendfile.backends.mod_wsgi - sets Location with 200 code to trigger internal redirect (daemon mode mod_wsgi only - see below)
  • sendfile.backends.nginx - sets X-Accel-Redirect header to trigger internal redirect to file

If you want to write your own backend simply create a module with a sendfile function matching:

def sendfile(request, filename):
    '''Return HttpResponse object for serving file'''

Then specify the full path to the module in SENDFILE_BACKEND. You only need to implement the sending of the file. Adding the content-disposition headers etc is done elsewhere.

Development backend

The Development backend is only meant for use while writing code. It uses Django's static file serving code to do the job, which is only meant for development. It reads the whole file into memory and the sends it down the wire - not good for big files, but ok when you are just testing things out.

It will work with the Django dev server and anywhere else you can run Django.

Simple backend

This backend is one step up from the development backend. It uses Django's django.core.files.base.File class to try and stream files from disk. However some middleware (e.g. GzipMiddleware) that rewrites content will causes the entire file to be loaded into memory. So only use this backend if you are not using middleware that rewrites content or you only have very small files.

xsendfile backend

Install either mod_xsendfile in Apache or use Lighthttpd. You may need to configure mod_xsendfile, but that should be as simple as:

XSendFile On

In your virtualhost file/conf file.

mod_wsgi backend

The mod_wsgi backend will only work when using mod_wsgi in daemon mode, not in embedded mode. It requires a bit more work to get it to do the same job as xsendfile though. However some may find it easier to setup, as they don't need to compile and install mod_xsendfile.

Firstly there are two more django settings:

  • SENDFILE_ROOT - this is a directoy where all files that will be used with sendfile must be located
  • SENDFILE_URL - internal URL prefix for all files served via sendfile

These settings are needed as this backend makes mod_wsgi send an internal redirect, so we have to convert a file path into a URL. This means that the files are visible via Apache by default too. So we need to get Apache to hide those files from anything that's not an internal redirect. To so this we can use some mod_rewrite_ magic along these lines:

RewriteEngine On
# see if we're on an internal redirect or not
RewriteCond %{THE_REQUEST} ^[\S]+\ /private/
RewriteRule ^/private/ - [F]

Alias /private/ /home/john/Development/myapp/private/
<Directory /home/john/Development/myapp/private/>
    Order deny,allow
    Allow from all
</Directory>

In this case I have also set:

SENDFILE_ROOT = '/home/john/Development/myapp/private/'
SENDFILE_URL = '/private'

All files are stored in a folder called 'private'. We forbid access to this folder (RewriteRule ^/private/ - [F]) if someone tries to access it directly (RewriteCond %{THE_REQUEST} ^[S]+/private/) by checking the original request (THE_REQUEST).

Alledgedly IS_SUBREQ can be used to perform the same job, but I was unable to get this working.

Nginx backend

As with the mod_wsgi backend you need to set two extra settings:

  • SENDFILE_ROOT - this is a directoy where all files that will be used with sendfile must be located
  • SENDFILE_URL - internal URL prefix for all files served via sendfile

You then need to configure nginx to only allow internal access to the files you wish to serve. More details on this are here.

For example though, if I use the django settings:

SENDFILE_ROOT = '/home/john/Development/django-sendfile/examples/protected_downloads/protected'
SENDFILE_URL = '/protected'

Then the matching location block in nginx.conf would be:

location /protected/ {
  internal;
  root   /home/john/Development/django-sendfile/examples/protected_downloads;
}

You need to pay attention to whether you have trailing slashes or not on the SENDFILE_URL and root values, otherwise you may not get the right URL being sent to NGINX and you may get 404s. You should be able to see what file NGINX is trying to load in the error.log if this happens. From there it should be fairly easy to work out what the right settings are.

based official code from django channels, replace frontend with reactjs

django_channels_chat_official_tutorial demo project for django channels tutorial code from tutorial page: https://channels.readthedocs.io/en/stable/tu

lightsong 1 Oct 22, 2021
Automatically reload your browser in development.

django-browser-reload Automatically reload your browser in development. Requirements Python 3.6 to 3.10 supported. Django 2.2 to 4.0 supported. Are yo

Adam Johnson 254 Jan 04, 2023
A Django application that provides country choices for use with forms, flag icons static files, and a country field for models.

Django Countries A Django application that provides country choices for use with forms, flag icons static files, and a country field for models. Insta

Chris Beaven 1.2k Dec 31, 2022
TinyApp - A Python (Django) Full Stack Application for shortening URLs

TinyApp A Python (Django) Full Stack Application for shortening URLs. How to sta

Li Deng 1 Jan 23, 2022
Django server-side adapter for Inertia.js

django-inertia Django server-side new adapter for Inertia.js. Getting Started Install the package pip install django-inertia Configure your project A

Samuel Girardin 14 Sep 16, 2022
A visual indicator of what environment/system you're using in django

A visual indicator of what environment/system you're using in django

Mark Walker 4 Nov 26, 2022
Use Database URLs in your Django Application.

DJ-Database-URL This simple Django utility allows you to utilize the 12factor inspired DATABASE_URL environment variable to configure your Django appl

Jacob Kaplan-Moss 1.3k Dec 30, 2022
A feature flipper for Django

README Django Waffle is (yet another) feature flipper for Django. You can define the conditions for which a flag should be active, and use it in a num

950 Dec 26, 2022
Displaying objects on maps in the Django views and administration site.

DjangoAdminGeomap library The free, open-source DjangoAdminGeomap library is designed to display objects on the map in the Django views and admin site

Vitaly Bogomolov 31 Dec 28, 2022
Modular search for Django

Haystack author: Daniel Lindsley date: 2013/07/28 Haystack provides modular search for Django. It features a unified, familiar API that allows you to

Daniel Lindsley 4 Dec 23, 2022
A Django app that allows visitors to interact with your site as a guest user without requiring registration.

django-guest-user A Django app that allows visitors to interact with your site as a guest user without requiring registration. Largely inspired by dja

Julian Wachholz 21 Dec 17, 2022
Thumbnails for Django

Thumbnails for Django. Features at a glance Support for Django 2.2, 3.0 and 3.1 following the Django supported versions policy Python 3 support Storag

Jazzband 1.6k Jan 03, 2023
A better and faster multiple selection widget with suggestions

django-searchable-select A better and faster multiple selection widget with suggestions for Django This project is looking for maintainers! Please ope

Andrew Dunai 105 Oct 22, 2022
Let AngularJS play well with Django

django-angular Let Django play well with AngularJS What does it offer? Add AngularJS directives to Django Forms. This allows to handle client side for

Jacob Rief 1.2k Dec 27, 2022
django-compat-lint

django_compat_lint -- check Django compatibility of your code Django's API stability policy is nice, but there are still things that change from one v

James Bennett 40 Sep 30, 2021
Customize the behavior of django.contrib.auth permissions.

Customizando o comportamento do django.contrib.auth. O que queremos? Não criar as permissões padrões automaticamente (add, delete, view, read). Criar

Henrique Bastos 7 Nov 26, 2022
Django-gmailapi-json-backend - Email backend for Django which sends email via the Gmail API through a JSON credential

django-gmailapi-json-backend Email backend for Django which sends email via the

Innove 1 Sep 09, 2022
django-quill-editor makes Quill.js easy to use on Django Forms and admin sites

django-quill-editor django-quill-editor makes Quill.js easy to use on Django Forms and admin sites No configuration required for static files! The ent

lhy 139 Dec 05, 2022
Indonesia's negative news detection using gaussian naive bayes with Django+Scikir Learn

Introduction Indonesia's negative news detection using gaussian naive bayes build with Django and Scikit Learn. There is also any features, are: Input

Harifzi Ham 1 Dec 30, 2021
this is a simple backend for instagram with python and django

simple_instagram_backend this is a simple backend for instagram with python and django it has simple realations and api in 4 diffrent apps: 1-users: a

2 Oct 20, 2021