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.

An API was build with Django to store and retrieve information about various musical instruments.

The project is meant to be a starting point, an experimentation or a basic example of a way to develop an API with Django. It is an exercise on using Django and various python technologies and design

Kostas Ziovas 2 Dec 25, 2021
E-Commerce Platform

Shuup Shuup is an Open Source E-Commerce Platform based on Django and Python. https://shuup.com/ Copyright Copyright (c) 2012-2021 by Shuup Commerce I

Shuup 2k Jan 07, 2023
Easily share data across your company via SQL queries. From Grove Collab.

SQL Explorer SQL Explorer aims to make the flow of data between people fast, simple, and confusion-free. It is a Django-based application that you can

Grove Collaborative 2.1k Dec 30, 2022
Django Login Api With Python

How to run this project Download and extract this project Create an environment and install all the libraries from requiements.txt pip freeze -r requi

Vikash Kisku 1 Dec 10, 2021
Simple API written in Python using FastAPI to store and retrieve Books and Authors.

Simple API made with Python FastAPI WIP: Deploy in AWS with Terraform Simple API written in Python using FastAPI to store and retrieve Books and Autho

Caio Delgado 9 Oct 26, 2022
Django-Text-to-HTML-converter - The simple Text to HTML Converter using Django framework

Django-Text-to-HTML-converter This is the simple Text to HTML Converter using Dj

Nikit Singh Kanyal 6 Oct 09, 2022
🗂️ 🔍 Geospatial Data Management and Search API - Django Apps

Geospatial Data API in Django Resonant GeoData (RGD) is a series of Django applications well suited for cataloging and searching annotated geospatial

Resonant GeoData 53 Nov 01, 2022
A starter template for building a backend with Django and django-rest-framework using docker with PostgreSQL as the primary DB.

Django-Rest-Template! This is a basic starter template for a backend project with Django as the server and PostgreSQL as the database. About the templ

Akshat Sharma 11 Dec 06, 2022
Basic Form Web Development using Python, Django and CSS

thebookrain Basic Form Web Development using Python, Django and CSS This is a basic project that contains two forms - borrow and donate. The form data

Ananya Dhulipala 1 Nov 27, 2021
Fast / fuzzy PostgreSQL counts for Django

Created by Stephen McDonald Introduction Up until PostgreSQL 9.2, COUNT queries generally required scanning every row in a database table. With millio

stephenmcd 85 Oct 25, 2021
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
PicoStyle - Advance market place website written in django

Advance market place website written in django :) Online fashion store for whole

AminAli Mazarian 26 Sep 10, 2022
A ToDO Rest API using Django, PostgreSQL and Docker

This Rest API uses PostgreSQL, Docker and Django to implements a ToDo application.

Brenno Lima dos Santos 2 Jan 05, 2022
Django Serverless Cron - Run cron jobs easily in a serverless environment

Django Serverless Cron - Run cron jobs easily in a serverless environment

Paul Onteri 41 Dec 16, 2022
Django models and endpoints for working with large images -- tile serving

Django Large Image Models and endpoints for working with large images in Django -- specifically geared towards geospatial tile serving. DISCLAIMER: th

Resonant GeoData 42 Dec 17, 2022
Automatic caching and invalidation for Django models through the ORM.

Cache Machine Cache Machine provides automatic caching and invalidation for Django models through the ORM. For full docs, see https://cache-machine.re

846 Nov 26, 2022
🔃 A simple implementation of STOMP with Django

Django Stomp A simple implementation of STOMP with Django. In theory it can work with any broker which supports STOMP with none or minor adjustments.

Juntos Somos Mais 32 Nov 08, 2022
Bootstrap 3 integration with Django.

django-bootstrap3 Bootstrap 3 integration for Django. Goal The goal of this project is to seamlessly blend Django and Bootstrap 3. Want to use Bootstr

Zostera B.V. 2.3k Jan 03, 2023
scaffold django rest apis like a champion 🚀

dr_scaffold Scaffold django rest apis like a champion ⚡ . said no one before Overview This library will help you to scaffold full Restful API Resource

Abdenasser Elidrissi 133 Jan 05, 2023
Full control of form rendering in the templates.

django-floppyforms Full control of form rendering in the templates. Authors: Gregor Müllegger and many many contributors Original creator: Bruno Renié

Jazzband 811 Dec 01, 2022