Nginx X-Accel explained

en in code

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 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 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 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 to use 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!





You may also like