diff options
-rw-r--r-- | lib/rack/multipart/parser.rb | 20 | ||||
-rw-r--r-- | test/spec_multipart.rb | 9 |
2 files changed, 21 insertions, 8 deletions
diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb index fa90ca96..faa98c7e 100644 --- a/lib/rack/multipart/parser.rb +++ b/lib/rack/multipart/parser.rb @@ -18,10 +18,13 @@ module Rack content_length = env['CONTENT_LENGTH'] content_length = content_length.to_i if content_length - new($1, io, content_length, env) + tempfile = env['rack.multipart.tempfile_factory'] || lambda { |filename, content_type| Tempfile.new("RackMultipart") } + bufsize = env['rack.multipart.buffer_size'] || BUFSIZE + + new($1, io, content_length, env, tempfile, bufsize) end - def initialize(boundary, io, content_length, env) + def initialize(boundary, io, content_length, env, tempfile, bufsize) @buf = "" if @buf.respond_to? :force_encoding @@ -34,6 +37,8 @@ module Rack @content_length = content_length @boundary_size = Utils.bytesize(@boundary) + EOL.size @env = env + @tempfile = tempfile + @bufsize = bufsize if @content_length @content_length -= @boundary_size @@ -86,7 +91,7 @@ module Rack def fast_forward_to_first_boundary loop do - content = @io.read(BUFSIZE) + content = @io.read(@bufsize) raise EOFError, "bad content body" unless content @buf << content @@ -95,7 +100,7 @@ module Rack return if read_buffer == full_boundary end - raise EOFError, "bad content body" if Utils.bytesize(@buf) >= BUFSIZE + raise EOFError, "bad content body" if Utils.bytesize(@buf) >= @bufsize end end @@ -125,8 +130,7 @@ module Rack end if filename - extname = ::File.extname(filename) - (@env['rack.tempfiles'] ||= []) << body = Tempfile.new(["RackMultipart", extname]) + (@env['rack.tempfiles'] ||= []) << body = @tempfile.call(filename, content_type) body.binmode if body.respond_to?(:binmode) end @@ -138,7 +142,7 @@ module Rack body << @buf.slice!(0, @buf.size - (@boundary_size+4)) end - content = @io.read(@content_length && BUFSIZE >= @content_length ? @content_length : BUFSIZE) + content = @io.read(@content_length && @bufsize >= @content_length ? @content_length : @bufsize) raise EOFError, "bad content body" if content.nil? || content.empty? @buf << content @@ -223,7 +227,7 @@ module Rack # filename is blank which means no file has been selected return elsif filename - body.rewind + body.rewind if body.respond_to?(:rewind) # Take the basename of the upload's original filename. # This handles the full Windows paths given by Internet Explorer diff --git a/test/spec_multipart.rb b/test/spec_multipart.rb index ca733dae..327c6a2a 100644 --- a/test/spec_multipart.rb +++ b/test/spec_multipart.rb @@ -171,6 +171,15 @@ describe Rack::Multipart do params["file1.txt"][:tempfile].read.should.equal "contents" end + should "parse multipart upload file using custom tempfile class" do + env = Rack::MockRequest.env_for("/", multipart_fixture(:text)) + my_tempfile = "" + env['rack.multipart.tempfile_factory'] = lambda { |filename, content_type| my_tempfile } + params = Rack::Multipart.parse_multipart(env) + params["files"][:tempfile].object_id.should.equal my_tempfile.object_id + my_tempfile.should.equal "contents" + end + should "parse multipart upload with nested parameters" do env = Rack::MockRequest.env_for("/", multipart_fixture(:nested)) params = Rack::Multipart.parse_multipart(env) |