I'm trying to get Nginx and Django to play together to serve downloadable protected files. I just cannot get it to work. Here's my Nginx config:
location ~ ^.*/protected-test/ {
alias /<path-to-my-protected-files-on-server>/;
internal;
}
the relevant urls.py for viewing the file(s):
url(r'^static_files/downloads/protected-test/(?P<filename>.+)$', 'download_or_view',
{'download_dir': '%s%s' % (settings.MEDIA_ROOT, 'downloads/protected-test/'),
'content_disposition_type': 'inline',
'protected': 'True'},
name='protected_files')
my view:
def download_or_view(request, content_disposition_type, download_dir, filename=None, protected=False):
'''Allow a file to be downloaded or viewed,based on the request type and
content disposition value.'''
if request.method == 'POST':
full_path = '%s%s' % (download_dir, request.POST['filename'])
short_filename = str(request.POST['filename'])
else:
full_path = '%s%s' % (download_dir, filename)
short_filename = str(filename)
serverfile = open(full_path, 'rb')
contenttype, encoding = mimetypes.guess_type(short_filename)
response = HttpResponse(serverfile, mimetype=contenttype)
if protected:
url = _convert_file_to_url(full_path)
response['X-Accel-Redirect'] = url.encode('utf-8')
response['Content-Disposition'] = '%s; filename="%s"' % (content_disposition_type, smart_str(short_filename))
response['Content-Length'] = os.stat(full_path).st_size
return response
I have 2 values in my settings file:
NGINX_ROOT = (os.path.join(MEDIA_ROOT, 'downloads/protected-test'))
NGINX_URL = '/protected-test'
_convert_file_to_url() takes the full file path and, using the two settings values above, turns it into a url that (I thought) Nginx would allow:
<domain-name>/protected-test/<filename>
So, if I try to access:
<domain-name>/static_files/downloads/protected-test/<filename>
In my browser window, it doesn't allow it (404). Good.
BUT - if I try to access that url from a form download, which I want to allow, I get a redirect in the browser to:
<domain-name>/protected-test/<filename>
and it's a 404 as well.
I've tried so many different configurations my brain now hurts. :-)
Should I not be reading the file with open(), and let Nginx serve it? If I remove that line, it returns a file with the dreaded zero bytes. Why do I still get a 404 on the redirected url??