Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 [email protected]
    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 [email protected]
    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

like image 767
Apostolos Avatar asked Jul 08 '14 12:07

Apostolos


2 Answers

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:

  • Activate the XSendFile in the vhost tag
  • I've written above what else needs to be done in the view
  • I'm not sure if you should remove the media alias, the log files should tell you if having them is a problem
like image 56
lurknobserve Avatar answered Nov 02 '22 02:11

lurknobserve


If anyone is facing same issue with a newer version of Apache (2.4), here's how I finally manage to make it worked :

<VirtualHost *:80>
        XSendFile on
        
        Alias /static/ /mnt/mysite/static/
        Alias /media/ /mnt/mysite/media/

        <Directory /mnt/mysite/static>
                Require all granted
        </Directory>

        <Directory /mnt/mysite/media>
                Require all granted
        </Directory>

        <Directory /mnt/mysite/media/protected>
                Require all denied
        </Directory>
        XSendFilePath /mnt/mysite/media/protected

        <Directory /home/benbb96/mysite>
                <Files wsgi.py>
                        Require all granted
                </Files>
        </Directory>

        WSGIDaemonProcess mysite python-home=/home/benbb96/mysite/venv python-path=/home/benbb96/mysite/
        WSGIScriptAlias / /home/benbb96/mysite/config/wsgi.py
</VirtualHost>

I run my site with wsgi in deamon mode (cf. docs) and I wanted to protect some media files which are uploaded in protected/. So I added a <Directory> directive to block access to it and then I use XSendFile in my view, which also verify if user has access to the file, to serve the protected file.

Note that my static and media files are hosted on a mounted folder from the network (/mnt/) but that doesn't cause any issues.

like image 1
Benbb96 Avatar answered Nov 02 '22 01:11

Benbb96