pythondjangoapachex-sendfile

XsendFile with apache and django


I have my django served by apache using Vhost. The conf file is the following

WSGIPythonPath /srv/www/myproject/testproject/


<VirtualHost *:80>
    ServerAdmin admin@betarhombus.com
    ServerName www.betarhombus.com
    WSGIScriptAlias / /srv/www/testproject/testproject/testproject/wsgi.py
    <Directory /srv/www/testproject/testproject/testproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
    Alias /static/ /srv/www/testproject/testproject/static/
    Alias /media/  /srv/www/testproject/testproject/media/

    <Directory /srv/www/testproject/testproject/static>
        Require all granted
    </Directory>
    <Directory /srv/www/testproject/testproject/media>
        Require all granted
    </Directory>

</VirtualHost>

I want to restrict media files to being served only on speicific logged users. So I ran into XsendFile. If I understand it correctly what it does is while you have django do all the checking for the media file you want to serve it is then served by Apache as static file. So the procedure is the follwing if I am guessing right

  1. Activate XsendFile.
  2. Create view that checks for media files permissions etc and serves them
  3. associate with url in urls.py file

Then I can use ` and will work normally like if it was served by using the initial media file url. Do I understand it correctly? My questions are the following:

About 1.activating XSendFile. Should this be done in conf file inside my Vhost tag? Is setting XsendFile on enough? Should I remove the Alias for media directive and also the section for the media files? I want media files only to be served by my view?

Is there anything else that I should be aware of?

Edit: My setup is

 <VirtualHost *:80>
    ServerAdmin admin@betarhombus.com
    ServerName www.betarhombus.com
    WSGIScriptAlias / /srv/www/testproject/testproject/testproject/wsgi.py
    XSendFile On
    XsendFilePath /srv/www/testproject/testproject/media/
    <Directory /srv/www/testproject/testproject/testproject>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
    Alias /static/ /srv/www/testproject/testproject/static/
    <Directory /srv/www/testproject/testproject/static>
        Require all granted
    </Directory>
</VirtualHost>

my urls.py

#for xsendmedia file serving
url(r'^media\/(?P<path>.*)$', 'customer.views.media_xsendfile'),

and my view

def media_xsendfile(request, path):  
    #here will be checked if user can access media
    response = HttpResponse()
    response['Content-Type']=''
    response['X-Sendfile']= smart_str(os.path.join(settings.MEDIA_ROOT, path))
    return response

My problem is that some of the media files are shared normally and some are not, and get an Internal Server Error


Solution

  • Also make sure to set the XSendFilePath in your Apache configuration file like so,

    XSendFile on
    XSendFilePath "//path/to/files/on/disk"
    <Directory "//path/to/files/on/disk">
        Order Deny,Allow
        Allow from all
    </Directory>
    

    and include this in your view while returning the response:

    response['X-Sendfile'] = smart_str(file_path)

    And to answer your questions: