Flowdock
read_multipart(boundary, content_length) private

No documentation

This method has no description. You can help the Ruby community by adding new notes.

Hide source
# File lib/cgi.rb, line 973
    def read_multipart(boundary, content_length)
      params = Hash.new([])
      boundary = "--" + boundary
      quoted_boundary = Regexp.quote(boundary, "n")
      buf = ""
      bufsize = 10 * 1024
      boundary_end=""

      # start multipart/form-data
      stdinput.binmode if defined? stdinput.binmode
      boundary_size = boundary.size + EOL.size
      content_length -= boundary_size
      status = stdinput.read(boundary_size)
      if nil == status
        raise EOFError, "no content body"
      elsif boundary + EOL != status
        raise EOFError, "bad content body"
      end

      loop do
        head = nil
        if 10240 < content_length
          require "tempfile"
          body = Tempfile.new("CGI")
        else
          begin
            require "stringio"
            body = StringIO.new
          rescue LoadError
            require "tempfile"
            body = Tempfile.new("CGI")
          end
        end
        body.binmode if defined? body.binmode

        until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf)

          if (not head) and /#{EOL}#{EOL}/n.match(buf)
            buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
              head = $1.dup
              ""
            end
            next
          end

          if head and ( (EOL + boundary + EOL).size < buf.size )
            body.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
            buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
          end

          c = if bufsize < content_length
                stdinput.read(bufsize)
              else
                stdinput.read(content_length)
              end
          if c.nil? || c.empty?
            raise EOFError, "bad content body"
          end
          buf.concat(c)
          content_length -= c.size
        end

        buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do
          body.print $1
          if "--" == $2
            content_length = -1
          end
          boundary_end = $2.dup
          ""
        end

        body.rewind

        /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;\s]*))/ni.match(head)
        filename = ($1 or $2 or "")
        if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
            /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
            (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
          filename = CGI::unescape(filename)
        end
        
        /Content-Type: ([^\s]*)/ni.match(head)
        content_type = ($1 or "")

        (class << body; self; end).class_eval do
          alias local_path path
          define_method(:original_filename) {filename.dup.taint}
          define_method(:content_type) {content_type.dup.taint}
        end

        /Content-Disposition:.* name="?([^\";\s]*)"?/ni.match(head)
        name = $1.dup

        if params.has_key?(name)
          params[name].push(body)
        else
          params[name] = [body]
        end
        break if buf.size == 0
        break if content_length == -1
      end
      raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/

      params
    end
Register or log in to add new notes.