summary refs log tree commit
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2015-08-28 10:02:10 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2015-08-28 10:02:10 -0700
commit91cdd46ce6d956233920122962999684d040ffa8 (patch)
treea493ebd3d44255bbd8ddb3f08483fe7d42abe1af
parent3b510485e3cddaf07bdc54550d3075e8957fe6ad (diff)
downloadrack-91cdd46ce6d956233920122962999684d040ffa8.tar.gz
remove the env from the multipart parser
I want to abstract the multipart parser from `env` so that we can get
the data from some structure other than an env hash.
-rw-r--r--lib/rack/multipart.rb14
-rw-r--r--lib/rack/multipart/parser.rb33
2 files changed, 29 insertions, 18 deletions
diff --git a/lib/rack/multipart.rb b/lib/rack/multipart.rb
index 1c7c4c35..5de265df 100644
--- a/lib/rack/multipart.rb
+++ b/lib/rack/multipart.rb
@@ -37,7 +37,19 @@ module Rack
     class << self
       def parse_multipart(env, params = Rack::Utils.default_query_parser)
         return if env['CONTENT_LENGTH'] == '0'
-        Parser.create(env, params).parse
+
+        io = env[RACK_INPUT]
+        io.rewind
+        content_length = env['CONTENT_LENGTH']
+        content_length = content_length.to_i if content_length
+
+        tempfile = env[RACK_MULTIPART_TEMPFILE_FACTORY] ||
+          lambda { |filename, content_type| Tempfile.new(["RackMultipart", ::File.extname(filename)]) }
+        bufsize = env[RACK_MULTIPART_BUFFER_SIZE] || Parser::BUFSIZE
+
+        info = Parser.parse io, content_length, env['CONTENT_TYPE'], tempfile, bufsize, params
+        env[RACK_TEMPFILES] = info.tmp_files
+        info.params
       end
 
       def build_multipart(params, first = true)
diff --git a/lib/rack/multipart/parser.rb b/lib/rack/multipart/parser.rb
index 7fab856e..cc5d6a63 100644
--- a/lib/rack/multipart/parser.rb
+++ b/lib/rack/multipart/parser.rb
@@ -8,8 +8,6 @@ module Rack
       BUFSIZE = 16384
       TEXT_PLAIN = "text/plain"
 
-      DUMMY = Struct.new(:parse).new
-
       class BoundedIO # :nodoc:
         def initialize(io, content_length)
           @io             = io
@@ -45,24 +43,28 @@ module Rack
         end
       end
 
-      def self.create(env, query_parser)
-        return DUMMY unless env['CONTENT_TYPE'] =~ MULTIPART
+      MultipartInfo = Struct.new :params, :tmp_files
+      EMPTY         = MultipartInfo.new(nil, [])
+
+      def self.parse_boundary(content_type)
+        return unless content_type
+        data = content_type.match(MULTIPART)
+        return unless data
+        data[1]
+      end
 
-        io = env[RACK_INPUT]
-        io.rewind
+      def self.parse(io, content_length, content_type, tmpfile, bufsize, qp)
+        return EMPTY if 0 == content_length
 
-        content_length = env['CONTENT_LENGTH']
-        content_length = content_length.to_i if content_length
+        boundary = parse_boundary content_type
+        return EMPTY unless boundary
 
-        tempfile = env[RACK_MULTIPART_TEMPFILE_FACTORY] ||
-          lambda { |filename, content_type| Tempfile.new(["RackMultipart", ::File.extname(filename)]) }
-        bufsize = env[RACK_MULTIPART_BUFFER_SIZE] || BUFSIZE
         io = BoundedIO.new(io, content_length) if content_length
 
-        new($1, io, env, tempfile, bufsize, query_parser)
+        new(boundary, io, tmpfile, bufsize, qp).parse
       end
 
-      def initialize(boundary, io, env, tempfile, bufsize, query_parser)
+      def initialize(boundary, io, tempfile, bufsize, query_parser)
         @buf            = "".force_encoding(Encoding::ASCII_8BIT)
 
         @query_parser   = query_parser
@@ -70,7 +72,6 @@ module Rack
         @boundary       = "--#{boundary}"
         @io             = io
         @boundary_size  = @boundary.bytesize + EOL.size
-        @env = env
         @tempfile       = tempfile
         @bufsize        = bufsize
 
@@ -115,11 +116,9 @@ module Rack
           break if (@buf.empty? && $1 != EOL) || should_break
         end
 
-        @env[RACK_TEMPFILES] = opened_files
-
         @io.rewind
 
-        @params.to_params_hash
+        MultipartInfo.new @params.to_params_hash, opened_files
       end
 
       private