9

I am serving restricted downloads in rails using X-Accel-Redirect with nginx. To validate my downloads in client app, i am trying to send the checksum in the non standard HTTP header Content-MD5 to the X-Accel-Redirect request. But this is not working.

below the rails snippet used to do the redirection

headers['X-Accel-Redirect'] = '/download_public/uploads/stories/' + params[:story_id] +'/' + params[:story_id] + '.zip'
            headers['X-Accel-Expires'] = 'max'
            checksum = Digest::MD5.file(Rails.root.dirname.to_s+'/public/uploads/stories/' + params[:story_id] +'/' + params[:story_id] + '.zip').hexdigest
            headers['Content-MD5'] = checksum
            request.session_options[:skip] = true
            render :nothing => true, :content_type => MIME::Types.type_for('.zip').first.content_type

This is the nginx section

location /download_public { 
 internal;
 proxy_pass_header Content-MD5;
 add_header Cache-Control "public, max-age=315360000";
 add_header Content-Disposition "inline"; 
 alias /var/www/sss/public; 
}

This is not working apparently. I am not able to get the Content-MD5 header in my responses. Is there any way to pass my Content-MD5 header from rails?

I know there are ways to do that entirely in nginx, like compiling nginx with perl or lua and easily calculate the MD5 on the fly. But i dont want to do that.

Any help is much appreciated.

4
  • try add_header Content-MD5 $upstream_content_md5; Commented Jul 1, 2014 at 9:53
  • @AlexeyTen, i got this error nginx: [emerg] unknown "upstream_content_md5" variable Commented Jul 1, 2014 at 9:57
  • 1
    Oops, it's $upstream_http_content_md5. See nginx.org/r/$upstream_http_ Commented Jul 1, 2014 at 11:29
  • @AlexeyTen, it works.. :) please add this as answer, i ll accept it Commented Jul 1, 2014 at 11:34

2 Answers 2

21

Use add_header Content-MD5 $upstream_http_content_md5;

Since X-Accel-Redirect causes internal redirect nginx will not send returned headers, but it will keep them in $upstream_http_... variables. So you could use them.

Sign up to request clarification or add additional context in comments.

4 Comments

same problem but with the aws s3 redirect. Could you please have a look at the question here stackoverflow.com/questions/24971724/… . any help is much appreciated
If I am doing proxy_pass inside "internal" location - then $upstream_.. variables becomes empty. How to fix that?
@urmurmur ask new question
nginx will not send returned headers - seems Content-Type is an exception, that header will be forwarded even without add_header
9

I've tried accepted answer and it doesn't work for me. But this works:

 set $authorization "$upstream_http_authorization";
 proxy_set_header Authorization $authorization; # Pass on secret from back end

(copy-pasted from this article https://clubhouse.io/developer-how-to/how-to-use-internal-redirects-in-nginx/)

It's interesting that it's important to extract variable. This does not work for me:

 proxy_set_header Authorization "$upstream_http_authorization";

3 Comments

This answer is underrated. I can confirm that without the variable it does not work. Thank you.
Yes, interesting indeed that it behaves this way. I've read and re-read the nginx docs and I'm utterly unable to understand why it should do this. Anyone with answers, please speak up! :-D
For me it only works with: more_set_headers "Content-Security-Policy: $upstream_http_content_security_policy"; (I needed to set the CSP header for a file served via X-Accel-Redirect.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.