def upload(local_file, remote_path, options={})
      if local_file.kind_of?(File) or local_file.kind_of?(Tempfile) then
        file = local_file
        name = local_file.respond_to?(:original_filename) ? local_file.original_filename : File.basename(local_file.path)
        local_path = local_file.path
      elsif local_file.kind_of?(String) then
        file = File.new(local_file)
        name = File.basename(local_file)
        local_path = local_file
      elsif local_file.kind_of?(StringIO) then
        raise(ArgumentError, "Must specify the :as option when uploading from StringIO") unless options[:as]
        file = local_file
        local_path = options[:as]
        
        # hack for bug in UploadIO
        class << file
          attr_accessor :path
        end
        file.path = local_path
      else
        raise ArgumentError, "local_file must be a File, StringIO, or file path"
      end
      
      name = File.basename(options.delete(:as)) if options[:as]

      remote_path = remote_path.sub(/^\//, '')
      remote_path = Dropbox.check_path(remote_path).split('/')

      remote_path << { :ssl => @ssl }
      url = Dropbox.api_url('files', root(options), *remote_path)
      uri = URI.parse(url)

      oauth_request = Net::HTTP::Post.new(uri.path)
      oauth_request.set_form_data 'file' => name

      alternate_host_session = clone_with_host(@ssl ? Dropbox::ALTERNATE_SSL_HOSTS['files'] : Dropbox::ALTERNATE_HOSTS['files'])
      alternate_host_session.instance_variable_get(:@consumer).sign!(oauth_request, @access_token)
      oauth_signature = oauth_request.to_hash['authorization']

      request = Net::HTTP::Post::Multipart.new(uri.path,
                                               'file' => UploadIO.new(
                                                       file,
                                                       'application/octet-stream',
                                                       name))
      request['authorization'] = oauth_signature.join(', ')

      proxy = URI.parse(@proxy || "")
      http = Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port)
      http.use_ssl = @ssl
      http.read_timeout = options[:timeout] if options[:timeout]
      response = http.request(request)

      if response.kind_of?(Net::HTTPSuccess) then
        begin
          return JSON.parse(response.body).symbolize_keys_recursively.to_struct_recursively
        rescue JSON::ParserError
          raise ParseError.new(uri.to_s, response)
        end
      else
        raise UnsuccessfulResponseError.new(uri.to_s, response)
      end
    end
def upload(local_file, remote_path, options={})
      if local_file.kind_of?(File) or local_file.kind_of?(Tempfile) then
        file = local_file
        name = local_file.respond_to?(:original_filename) ? local_file.original_filename : File.basename(local_file.path)
        local_path = local_file.path
      elsif local_file.kind_of?(String) then
        file = File.new(local_file)
        name = File.basename(local_file)
        local_path = local_file
      elsif local_file.kind_of?(StringIO) then
        raise(ArgumentError, "Must specify the :as option when uploading from StringIO") unless options[:as]
        file = local_file
        local_path = options[:as]
        
        # hack for bug in UploadIO
        class << file
          attr_accessor :path
        end
        file.path = local_path
      else
        raise ArgumentError, "local_file must be a File, StringIO, or file path"
      end
      
      name = File.basename(options.delete(:as)) if options[:as]

      remote_path = remote_path.sub(/^\//, '')
      remote_path = Dropbox.check_path(remote_path).split('/')

      remote_path << { :ssl => @ssl }
      url = Dropbox.api_url('files', root(options), *remote_path)
      uri = URI.parse(url)

      oauth_request = Net::HTTP::Post.new(uri.path)
      oauth_request.set_form_data 'file' => name

      alternate_host_session = clone_with_host(@ssl ? Dropbox::ALTERNATE_SSL_HOSTS['files'] : Dropbox::ALTERNATE_HOSTS['files'])
      alternate_host_session.instance_variable_get(:@consumer).sign!(oauth_request, @access_token)
      oauth_signature = oauth_request.to_hash['authorization']

      request = Net::HTTP::Post::Multipart.new(uri.path,
                                               'file' => UploadIO.new(
                                                       file,
                                                       'application/octet-stream',
                                                       name))
      request['authorization'] = oauth_signature.join(', ')

      proxy = URI.parse(@proxy || "")
      http = Net::HTTP::Proxy(proxy.host, proxy.port).new(uri.host, uri.port)
      http.use_ssl = @ssl
      http.read_timeout = options[:timeout] if options[:timeout]
      response = http.request(request)

      if response.kind_of?(Net::HTTPSuccess) then
        begin
          return JSON.parse(response.body).symbolize_keys_recursively.to_struct_recursively
        rescue JSON::ParserError
          raise ParseError.new(uri.to_s, response)
        end
      else
        raise UnsuccessfulResponseError.new(uri.to_s, response)
      end
    end
Uploads a file to a path relative to the configured mode's root. The
 +remote_path+ parameter is taken to be the path portion _only_; the name
 of the remote file will be identical to that of the local file. You can
 provide any of the following for the first parameter:

 * a +File+ object (in which case the name of the local file is used),
 * a path to a file (in which case that file's name is used), or
 * a +StringIO+ (in which case the <tt>:as</tt> option must be specified.

 Options:

 +mode+:: Temporarily changes the API mode. See the MODES array.
 +as+:: Specify a custom name for the uploaded file (required when
        uploading from a +StringIO+ stream).
 +timeout+:: The amount of time to wait for a response from the Dropbox
             server (in seconds). By default it's 60; set this higher when
             uploading large files.

 Examples:

  session.upload 'music.pdf', '/' # upload a file by path to the root directory
  session.upload 'music.pdf, 'music/' # upload a file by path to the music folder
  session.upload File.new('music.pdf'), '/' # same as the first example
  session.upload open('http://www.example.com/index.html'), :as => 'example.html' # upload from a StringIO stream (requires open-uri)