Skip to content

Commit

Permalink
Improve performance of applications using file uploads by not busting…
Browse files Browse the repository at this point in the history
… the method cache on every request containing a file upload.
  • Loading branch information
carllerche committed Sep 23, 2010
1 parent 2db3035 commit 684bb86
Showing 1 changed file with 20 additions and 29 deletions.
49 changes: 20 additions & 29 deletions actionpack/lib/action_dispatch/http/upload.rb
Expand Up @@ -2,49 +2,40 @@

module ActionDispatch
module Http
module UploadedFile
def self.extended(object)
object.class_eval do
attr_accessor :original_path, :content_type
alias_method :local_path, :path if method_defined?(:path)
end
end
class UploadedFile < Tempfile
attr_accessor :original_filename, :content_type, :tempfile, :headers

# Take the basename of the upload's original filename.
# This handles the full Windows paths given by Internet Explorer
# (and perhaps other broken user agents) without affecting
# those which give the lone filename.
# The Windows regexp is adapted from Perl's File::Basename.
def original_filename
unless defined? @original_filename
@original_filename =
unless original_path.blank?
if original_path =~ /^(?:.*[:\\\/])?(.*)/m
$1
else
File.basename original_path
end
end
def initialize(hash)
@original_filename = hash[:filename]
@content_type = hash[:type]
@headers = hash[:head]

# To the untrained eye, this may appear as insanity. Given the alternatives,
# such as busting the method cache on every request or breaking backwards
# compatibility with is_a?(Tempfile), this solution is the best available
# option.
#
# TODO: Deprecate is_a?(Tempfile) and define a real API for this parameter
tempfile = hash[:tempfile]
tempfile.instance_variables.each do |ivar|
instance_variable_set(ivar, tempfile.instance_variable_get(ivar))
end
@original_filename
end

alias local_path path
end

module Upload
# Convert nested Hash to HashWithIndifferentAccess and replace
# file upload hash with UploadedFile objects
def normalize_parameters(value)
if Hash === value && value.has_key?(:tempfile)
upload = value[:tempfile]
upload.extend(UploadedFile)
upload.original_path = value[:filename]
upload.content_type = value[:type]
upload
UploadedFile.new(value)
else
super
end
end
private :normalize_parameters
end
end
end
end

0 comments on commit 684bb86

Please sign in to comment.