Skip to content

Instantly share code, notes, and snippets.

@tf
Last active December 30, 2015 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tf/7830938 to your computer and use it in GitHub Desktop.
Save tf/7830938 to your computer and use it in GitHub Desktop.
Paperclip IOAdapter for nginx_upload Module Integration
location ~ ^/entries/[0-9]+/files$ {
upload_pass @app;
upload_store /mnt/nginx_uploads 1;
upload_store_access user:rw group:rw all:r;
upload_set_form_field $upload_field_name[original_name] "$upload_file_name";
upload_set_form_field $upload_field_name[content_type] "$upload_content_type";
upload_set_form_field $upload_field_name[tmp_path] "$upload_tmp_path";
upload_pass_form_field "^entry_id$|^authenticity_token$|^format$";
upload_cleanup 400 404 500-505;
# Catch "Method not allowed" raised for non-POST requests and
# delegate to app
error_page 405 = @app;
}
location @app {
passenger_enabled on;
...
}
require 'fileutils'
module Paperclip
class NginxUploadAdapter < AbstractAdapter
def initialize(target)
@target = target
cache_current_values
end
private
def cache_current_values
self.original_filename = @target[:original_name]
@content_type = @target[:content_type]
@size = File.size(@target[:tmp_path])
FileUtils.mv(@target[:tmp_path], destination.path)
@tempfile = destination
# Required to reopen the tempfile that we have overwritten
@tempfile.open
end
end
end
# IMPORTANT: Only register this adapter if all endpoints of your application
# that take paperclip attachments have been configured with the above nginx
# upload location.
#
# Otherwise attackers could pass tmp_path params pointing to arbitrary files on
# your file system and have them moved to a publicly readable position. In the
# above nginx configuration, the upload_pass_from_field directive prevents this
# from happening.
Paperclip.io_adapters.register Paperclip::NginxUploadAdapter do |target|
Hash === target && [:original_name, :content_type, :tmp_path].all? { |key| target.key?(key) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment