I am using Nginx X-Accel-Redirect to serve a large protected file (several GBs) to users. The server application processes the URL and verifies the download token (embedded in URL) and starts or rejects the download. The problem is that the download cannot be resumed if the download fails for any reason. The file is really big, so the chance of this happening cannot be ignored.

For a bit more info, the server is on AWS EC2 and the file is in an S3 bucket. This means that we are paying for the failed download too.

What I want to know is if it is possible to protect a file using download tokens or other means, so that users can't just share the download links with others, but still be resumable in case of network disconnects.

The python server is forwarding the following headers to Nginx.

Content-Disposition='attachment; filename=xxx'

Nginx configuration is as follows.

location ~ ^/protected/(.*) {
    resolver_timeout 60;
    proxy_hide_header Content-Type; # To hide header from S3
    proxy_hide_header x-amz-id-2;
    proxy_hide_header x-amz-request-id;
    proxy_set_header Content-Type 'application/force-download';
    proxy_max_temp_file_size 0;
    proxy_pass https://***.amazonaws.com/***/$1;

It looks like you're proxying requests to S3, rather than serving pre-signed URLs with a normal redirect (e.g. 303), not an X-Accel-Redirect, which is what is usually done to make expiring links.

In your case, I expect that the Range request header is being dropped. You should make sure you pass the request headers from the browser onward to S3 with proxy_pass_request_headers on; in the location. Further, you probably should not have internal defined for that location.

  • Hi, your suggestion looks good. I can generate a pre-signed URL using boto3 and it works well. When you say a pre-signed URL with 303 redirect, are you saying I should send a 303 redirect from my server after validating the token? I did a quick test with that. It is not possible to completely hide the download link with that, but it is not out there in the open. The actual download link which the browser has is a direct link to the server, so a user with enough knowledge can copy it and share to others. Though it doesn't really make any sense to do that as the service is free :) – user2956979 Mar 8 at 16:01
  • If you aren't trying to prevent people downloading your content, then why bother with any of this, you could just link directly to unsigned S3 URLs. – Michael Hampton Mar 8 at 16:03
  • We wanted to limit multiple downloads from the same user and also to log downloads for accounting purposes. The service is free for the user, but we are still paying for the downloads. It is part of an academic research project, so the idea is to make the one-time funding last as long as possible. As the service is open to all interested parties, we can't really limit someone who is doing something on purpose. We could atleast encourage people to be responsible. – user2956979 Mar 8 at 16:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.