From 91cdd46ce6d956233920122962999684d040ffa8 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 28 Aug 2015 10:02:10 -0700 Subject: 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. --- lib/rack/multipart.rb | 14 +++++++++++++- lib/rack/multipart/parser.rb | 33 ++++++++++++++++----------------- 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 -- cgit v1.2.3-24-ge0c7