Hi, I’m trying to get Nginx to throttle downloads based on a flag set in the model of Django. When serving large files with the is_archived
flag, I’d like to limit the download rate to 1 MB/s or lower so that downloads for archived files don’t disrupt downloading non-archived files. However, I can’t find a good way to get Django to tell Nginx that a given file has the flag set. What approach can I try here?
If the files to be served are located on the filesystem under a specific folder, so that they can be served by nginx using X-Accel (see X-Accel | NGINX). The response returned by django can then include the X-Accel-Redirect header to specify the file to be returned, and may also include X-Accel-Limit-Rate to limit the download rate.
If the files are served directly by the django app (returning a FileResponse), you may have the initial view serving files redirecting to another URL (whose corresponding view effectively returns the FileResponse) when archive flag is set, and configure that specific location in nginx configuration to limit bandwidth.
Hmm, currently I’m serving files from the media/
directory with this nginx configuration:
Files that are “archived” are mixed with files that aren’t.
The files aren’t served directly by Django, so I guess that rules the latter approach out unless I rework it to go through Django. For the first one, would there be a way to send the X-Accel-Limit-Rate
header with the configuration? That seems like the approach that I’m looking for – sending the rate limit header based on the flag in the model.
The general pattern for this is that the browser requests some url for a file - perhaps something like: /protected-media/file-name.png
.
Your location directive for protected-media
then routes that request to a Django view. That view checks whatever it needs to check to set headers (such as the X-Accel-Limit-Rate
), then returns a redirect with the X-Accel-Redirect
header set to indicate to nginx that this redirect is to be handled by nginx and not returned to the browser. The uri being used for the redirect would be the “real” url for the file.
In addition to the X-Accel docs referenced above, also see the docs for the internal
directive, preventing users from accessing that real url directly.
So in this situation, Django isn’t actually sending the files, but it is processing the request to determine how the file should be handled. It’s still nginx serving the file.
@antoinehumbert @KenWhitesell thank you so much for the responses! I managed to implement it here: feat: throttle download speed for archived builds by ericswpark · Pull Request #289 · shipperstack/shipper · GitHub if anybody who finds this post is interested in an example.