3

I have to serve very large static files to multiple clients, but some clients do not have access to all files, so my server has to check for the file permissions for each client, and I cannot use nginx or memcache to serve files directly. What would be the best approach to concurrently serve multiple clients large files (4 to 10Mb) while keeping the flask server responsive ?

Right now my files are stored on S3, is there an easy way to give the client a redirect with a one-time access key to S3 so he can download the file on S3 after I checked the permission?

oulipo
  • 335
  • 6
  • 18
  • Probably by returning the response with [`direct_passthrough=True` set](http://stackoverflow.com/questions/5166129/how-do-i-stream-a-file-using-werkzeug). – Martijn Pieters Dec 08 '13 at 01:43
  • Related: http://flask.pocoo.org/mailinglist/archive/2010/11/5/big-passthrough-download-without-response-object/ – Martijn Pieters Dec 08 '13 at 01:46
  • For S3-hosted content, `boto` can create a 'temporary' URL, one that expires after a set time limit. I believe you'd redirect the browser to such a URL; so Flask just responds with a redirect and S3 takes care of the download. – Martijn Pieters Dec 08 '13 at 01:59
  • I've seen this, but unfortunately when I do the redirect, it changes the URL so then relative links don't work anymore (eg. if my index.html is on s3, doing the redirect will send the browser to https://s3.../index.html, and then it will look for other files that have to be downloaded from the index it won't find them there) – oulipo Dec 08 '13 at 02:06
  • Then state that in your question; perhaps someone solved *that* problem already. – Martijn Pieters Dec 08 '13 at 02:13

1 Answers1

3

You should look into using the X-Accel-Redirect header.

Essentially your flask view will check permissions and if appropriate set a http header that instructs nginx to serve the file.

A quick google found this Gist which describes how to configure Flask + Nginx to work together in the manner you need.

Tom Neyland
  • 6,860
  • 2
  • 36
  • 52
  • Thanks, what I ended up doing though for simplicity is to server small files (.html, .js, .css) by donwloading them and serving them with Flask, and for larger files create a temporary private url with a timestamp using boto `generate_url` – oulipo Dec 08 '13 at 23:04
  • BTW what would be the advantage of using X-Accel-Redirect rather than my solution? Just the fact that the user only sees a file that seems to come from my server rather than downloaded from S3? – oulipo Dec 08 '13 at 23:11