static private Method

AbstractRequest.read_multipart(body, boundary, content_length, env)

There's no documentation for this item.

Source Code

# File action_controller/request.rb, line 500
def read_multipart(body, boundary, content_length, env)
  params = Hash.new([])
  boundary = "--" + boundary
  quoted_boundary = Regexp.quote(boundary)
  buf = ""
  bufsize = 10 * 1024
  boundary_end=""

  # start multipart/form-data
  body.binmode if defined? body.binmode
  boundary_size = boundary.size + EOL.size
  content_length -= boundary_size
  status = body.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
    content =
      if 10240 < content_length
        UploadedTempfile.new("CGI")
      else
        UploadedStringIO.new
      end
    content.binmode if defined? content.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 )
        content.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)]
        buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
      end

      c = if bufsize < content_length
            body.read(bufsize)
          else
            body.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
      content.print $1
      if "--" == $2
        content_length = -1
      end
     boundary_end = $2.dup
      ""
    end

    content.rewind

    head =~ /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;]*))/ni
    if filename = $1 || $2
      if /Mac/ni.match(env['HTTP_USER_AGENT']) and
          /Mozilla/ni.match(env['HTTP_USER_AGENT']) and
          (not /MSIE/ni.match(env['HTTP_USER_AGENT']))
        filename = CGI.unescape(filename)
      end
      content.original_path = filename.dup
    end

    head =~ /Content-Type: ([^\r]*)/ni
    content.content_type = $1.dup if $1

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

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

  begin
    body.rewind if body.respond_to?(:rewind)
  rescue Errno::ESPIPE
    # Handles exceptions raised by input streams that cannot be rewound
    # such as when using plain CGI under Apache
  end

  params
end
Comments

Have your say
Please use Textile formatting (click here for a cheat sheet). Use <code/> and <pre/> for code samples.
Click here to login with OpenID to to post comments.