Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Serving Media Behind Custom URL

Tags:

So I of course know that serving static files through Django will send you straight to hell but I am confused on how to use a custom url to mask the true location of the file using Django. Django: Serving a Download in a Generic View but the answer I accepted seems to be the "wrong" way of doing things.

urls.py:

url(r'^song/(?P<song_id>\d+)/download/$', song_download, name='song_download'), 

views.py:

def song_download(request, song_id):     song = Song.objects.get(id=song_id)     fsock = open(os.path.join(song.path, song.filename))      response = HttpResponse(fsock, mimetype='audio/mpeg')     response['Content-Disposition'] = "attachment; filename=%s - %s.mp3" % (song.artist, song.title)      return response 

This solution works perfectly but not perfectly enough it turns out. How can I avoid having a direct link to the mp3 while still serving through nginx/apache?

EDIT 1 - ADDITIONAL INFO

Currently I can get my files by using an address such as: http://www.example.com/music/song/1692/download/ But the above mentioned method is the devil's work.

How can I accomplished what I get above while still making nginx/apache serve the media? Is this something that should be done at the webserver level? Some crazy mod_rewrite?

http://static.example.com/music/Aphex%20Twin%20-%20Richard%20D.%20James%20(V0)/10%20Logon-Rock%20Witch.mp3

EDIT 2 - ADDITIONAL ADDITIONAL INFO

I use nginx for my frontend and reverse proxy back apache/development server so I think if it does require some sort of mod_rewrite work I will have to find something that would work with nginx.

like image 359
TheLizardKing Avatar asked Apr 22 '10 02:04

TheLizardKing


People also ask

How do I serve Django media files in production?

Unfortunately, the Django development server doesn't serve media files by default. Fortunately, there's a very simple workaround: You can add the media root as a static path to the ROOT_URLCONF in your project-level URLs.

How do I serve static files in Django?

Serving the site and your static files from the same serverPush your code up to the deployment server. On the server, run collectstatic to copy all the static files into STATIC_ROOT . Configure your web server to serve the files in STATIC_ROOT under the URL STATIC_URL .

What does Collectstatic do in Django?

collectstatic. Collects the static files into STATIC_ROOT . Duplicate file names are by default resolved in a similar way to how template resolution works: the file that is first found in one of the specified locations will be used. If you're confused, the findstatic command can help show you which files are found.

What is static root in Django?

The STATIC_ROOT variable in settings.py defines the single folder you want to collect all your static files into. Typically, this would be a top-level folder inside your project, eg: STATIC_ROOT = "/home/myusername/myproject/static" # or, eg, STATIC_ROOT = os. path.


2 Answers

To expand on the previous answers you should be able to modify the following code and have nginx directly serve your download files whilst still having the files protected.

First of all add a location such as :

location /files/ {    alias /true/path/to/mp3/files/;    internal; } 

to your nginx.conf file (the internal makes this not directly accessible). Then you need a Django View something like this:

def song_download(request, song_id):     try:         song = Song.objects.get(id=song_id)         response = HttpResponse()         response['Content-Type'] = 'application/mp3'         response['X-Accel-Redirect'] = '/files/' + song.filename         response['Content-Disposition'] = 'attachment;filename=' + song.filename     except Exception:         raise Http404     return response 

which will hand off the file download to nginx.

like image 95
Frozenskys Avatar answered Sep 19 '22 08:09

Frozenskys


The basic idea is to get your Django view to redirect to a secure URL that is served by your media server.

See this list of suggestions by Graham Dumpleton, author of mod_wsgi.

like image 30
Daniel Roseman Avatar answered Sep 21 '22 08:09

Daniel Roseman