开发者

Pinax & Apache: deliver Attachments only to authenticated users

I want that Apache and Pinax only deliver Attachments to authenticated users.

I found this post, but i can't make it work.

My Apache-conf-file:

WSGIPythonPath /usr/local/bin/python

<VirtualHost *:80&开发者_运维百科gt;
    ServerName      www.domain.com
    ServerAlias     domain.com


    WSGIDaemonProcess k-production python-path=/path/to/app/pinax-env/lib/python2.6/site-packages
    WSGIProcessGroup k-production

    Alias /site_media  /path/to/app/cp/site_media    
    <Directory /path/to/app/cp/site_media>
    Order deny,allow
    Allow from all
    </Directory>

    WSGIScriptAlias /site_media/media/attachments /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/site_media/media/attachments>
    Deny from all
    </Directory>

    XSendFile On
    XSendFileAllowAbove On

    WSGIScriptAlias / /path/to/app/cp/deploy/pinax.wsgi
    <Directory /path/to/app/cp/deploy>
        Order deny,allow
        Allow from all
    </Directory>

</VirtualHost>

and my (still rough) view, that should get called:

@login_required 
def sendfile(request, slug): 

    app, content_object_id, img = slug.split('/')
    project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug) 
    response = HttpResponse() 
    response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug) 
    content_type = 'application/octet-stream' 
    response['Content-Type'] = content_type 
    response['Content-Disposition'] = 'attachment; filename="%s"' %  os.path.basename(os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug))
    return response 

Apache throws a 403 no matter if the user is logged in.

Via the develoment-server i can access the view, but no data will get transmitted.

What is wrong?


I was trying to do pretty much exactly the same thing, and the solution turned out to be not using WSGIScriptAlias, and instead using a regular Alias to a directory that defined a wsgi handler. For the view I basically just wrote a wrapper around django.views.static.serve.

My apache conf ended up looking like this:

# myproject
<VirtualHost *:8080>
    #DocumentRoot /var/www/myproject/public
    ServerName myproject
    ErrorLog /var/www/myproject/logs/apache_error_log
    CustomLog /var/www/myproject/logs/apache_access_log common

    AliasMatch ^/(media/uploads/protected/.*) /var/www/myproject/src/myproject-trunk/server/django.wsgi/$1
    Alias /media/ /var/www/myproject/public/media/
    Alias / /var/www/myproject/src/myproject-trunk/server/django.wsgi/

    <Directory /var/www/myproject/src/myproject-trunk/server>
        Options ExecCGI
        AddHandler wsgi-script .wsgi
        # WSGIApplicationGroup %{GLOBAL}
        Order allow,deny
        Allow from all
    </Directory>

    <Directory /var/www/myproject/public/media>
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>


Try to concentrate on the development server first - since it is a simpler setup and thus less error prone.

Perhaps try this:

@login_required  def sendfile(request, slug): 
    ## these are never used    
    # app, content_object_id, img = slug.split('/')
    # project_file = get_object_or_404(Attachment, attachment_file = 'attachments/'+slug)

    response = HttpResponse() 
    response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT,   'attachments/'+slug)

    import pdb; pdb.set_trace() 
    # your development server will stop here
    # you can now inspect the your context, e.g.
    # >> p response['X-Sendfile']
    # this should print the value of response['X-Sendfile']
    # >> c
    # this will continue program execution
    # for more commands see http://www.python.org/doc/2.4/lib/debugger-commands.html

    content_type = 'application/octet-stream' 
    response['Content-Type'] = content_type 
    # Content-Disposition filename is only for suggesting a name for the file
    # when the user tries to download it, e.g.:
    # response['Content-Disposition'] = 'attachment; filename='localfile.txt'
    response['Content-Disposition'] = 'attachment; filename="%s"' %  os.path.basename(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug))
    return response

But by using the dev server you won't get any files served, since Apache will do the file serving. You can just ensure, the data sent to apache is correct. Or use (not recommended for your production server)

f = open(os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug), 'rb')
response = HttpResponse(f.read())

instead of

response = HttpResponse() 
response['X-Sendfile'] =  os.path.join(settings.MEDIA_ROOT, 'attachments/'+slug)

Some Links:

  • Similar topic at stackoverflow
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜