Nginx & Paperclip & S3 private buckets
First configure Paperclip to treat S3 bucket as private (by default it’s public) somewhere in your initrializers
Paperclip::Attachment.default_options[:s3_permissions] = :private
Then I have simple helper, not to have to repeat the code, as downloads can be triggered on multiple placies through the applications.
def download(url)
ct = Rack::Mime::MIME_TYPES.fetch(File.extname(url), 'application/octet-stream')
response.headers['X-Accel-Redirect'] = '/reproxy'
response.headers['X-Reproxy-URL'] = url
response.headers['Content-Type'] = ct
render plain: ''
end
The helper is called from somwhere in controllers
download(attachment.file.expiring_url(10))
Paperclip will generated unique URL that will be valid for 10s and that nginx can use to “high-jack” the response.
And finally the configuration of Nginx
location /reproxy {
internal;
resolver 8.8.8.8;
set $reproxy $upstream_http_x_reproxy_url;
proxy_pass $reproxy;
proxy_hide_header Content-Type;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
proxy_intercept_errors on;
}
The idea is based on this documentation for LS4, plus compilation of several StackOverflow answers to make the “/reproxy” target work correctly with S3 authorization.