Nginx X-Accel Explained

en in code • 3 min read

My team was working on CMS solution based on Django and we needed to have private files. Those files are also video files which we would like to stream to HTML5 player. Problem was, Django is not nginx or apache. It’s even wrong to want it. We were sad our private files are served slowly without streaming feature and actually not working in every browser.

Because of the last issue, we were forced to look for a solution and we were surprised it has been fixed a long time ago with a very sexy solution! In nginx, it’s called X-Accel, but usually, you can find it as X-Sendfile.

Because I didn’t know about it before and wasn’t able to set it up correctly for the first time, I decided to share it with you. :-)


It’s just new section in nginx and special header in your application. Usually, without this feature, you would set up a handler in your app, check permission and return data directly. With X-Accel, you don’t return data, but the special header.

Let’s say you want to have two URL in your app, /media for public media and /smedia for private media. Then in your nginx you will need a usual section for public media, and two new sections for private ones. /smedia is visible outside and headed to your app and /pmedia is visible only internally thanks to internal configuration.

location /media/ {
    alias /data/media/public/;
}

location /smedia/ {
    include /etc/nginx/uwsgi_params;
    uwsgi_pass unix:/var/run/app/uwsgi.sock;
}

location /pmedia/ {
    internal;
    alias /data/media/private/;
}

Now you need only to update your app to not return actual data, but header with /pmedia location. When nginx finds in the response X-Accel-Redirect header, it will use this new location. Because this new location is returned from the (internal) app, it will allow using also internal locations.

For example, in Python with a Flask it could look like:

@app.route('/<file_id>')
def serve_private_media(file_id):
    # check access to the file
    response = make_response()
    response.headers['X-Accel-Redirect'] = '/pmedia/path/to/file'
    return response

Note that path is starting with /pmedia and then the path is relative to the root of the directory with private data, in our example to /data/media/private/.

And that’s it!



Share on:   Facebook   Twitter   Reddit   Tumblr   Pinterest




You may also like

en What Makes Good Program?, November 20, 2018
en Old Code, October 31, 2018
en Fast JSON Schema for Python, October 1, 2018
en Open Source Responsibilities, September 6, 2018
en Deployment of Python Apps, August 15, 2018


Popular from code

en Makefile with Python, November 6, 2017
en Deployment of Python Apps, August 15, 2018
cs Jasně, umím Git…, August 6, 2014
cs Checklist na zabezpečení webových aplikací, March 1, 2016
cs Pokročilé regulární výrazy, August 17, 2014