Last active
December 30, 2015 12:39
-
-
Save tf/7830938 to your computer and use it in GitHub Desktop.
Paperclip IOAdapter for nginx_upload Module Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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