src/dropbox.js
function (path, body, contentType, options) {
    var self = this;

    if (!this.connected) {
      throw new Error("not connected (path: " + path + ")");
    }

    //check if file has changed and return 412
    var savedRev = this._revCache.get(path);
    if (options && options.ifMatch &&
        savedRev && (savedRev !== options.ifMatch)) {
      return Promise.resolve({statusCode: 412, revision: savedRev});
    }
    if (options && (options.ifNoneMatch === '*') &&
        savedRev && (savedRev !== 'rev')) {
      return Promise.resolve({statusCode: 412, revision: savedRev});
    }

    if ((!contentType.match(/charset=/)) && isBinaryData(body)) {
      contentType += '; charset=binary';
    }

    if (body.length > 150 * 1024 * 1024) {
      //https://www.dropbox.com/developers/core/docs#chunked-upload
      return Promise.reject(new Error("Cannot upload file larger than 150MB"));
    }

    var result;
    var needsMetadata = options && (options.ifMatch || (options.ifNoneMatch === '*'));
    var uploadParams = {
      body: body,
      contentType: contentType,
      path: path
    };

    if (needsMetadata) {
      result = this._getMetadata(path).then(function (metadata) {
        if (options && (options.ifNoneMatch === '*') && metadata) {
          // if !!metadata === true, the file exists
          return Promise.resolve({
            statusCode: 412,
            revision: metadata.rev
          });
        }

        if (options && options.ifMatch && metadata && (metadata.rev !== options.ifMatch)) {
          return Promise.resolve({
            statusCode: 412,
            revision: metadata.rev
          });
        }

        return self._uploadSimple(uploadParams);
      });
    } else {
      result = self._uploadSimple(uploadParams);
    }

    return result.then(function (ret) {
      self._shareIfNeeded(path);
      return ret;
    });
  }
function (path, body, contentType, options) {
    var self = this;

    if (!this.connected) {
      throw new Error("not connected (path: " + path + ")");
    }

    //check if file has changed and return 412
    var savedRev = this._revCache.get(path);
    if (options && options.ifMatch &&
        savedRev && (savedRev !== options.ifMatch)) {
      return Promise.resolve({statusCode: 412, revision: savedRev});
    }
    if (options && (options.ifNoneMatch === '*') &&
        savedRev && (savedRev !== 'rev')) {
      return Promise.resolve({statusCode: 412, revision: savedRev});
    }

    if ((!contentType.match(/charset=/)) && isBinaryData(body)) {
      contentType += '; charset=binary';
    }

    if (body.length > 150 * 1024 * 1024) {
      //https://www.dropbox.com/developers/core/docs#chunked-upload
      return Promise.reject(new Error("Cannot upload file larger than 150MB"));
    }

    var result;
    var needsMetadata = options && (options.ifMatch || (options.ifNoneMatch === '*'));
    var uploadParams = {
      body: body,
      contentType: contentType,
      path: path
    };

    if (needsMetadata) {
      result = this._getMetadata(path).then(function (metadata) {
        if (options && (options.ifNoneMatch === '*') && metadata) {
          // if !!metadata === true, the file exists
          return Promise.resolve({
            statusCode: 412,
            revision: metadata.rev
          });
        }

        if (options && options.ifMatch && metadata && (metadata.rev !== options.ifMatch)) {
          return Promise.resolve({
            statusCode: 412,
            revision: metadata.rev
          });
        }

        return self._uploadSimple(uploadParams);
      });
    } else {
      result = self._uploadSimple(uploadParams);
    }

    return result.then(function (ret) {
      self._shareIfNeeded(path);
      return ret;
    });
  }
Checks for the path in ``_revCache`` and decides based on that if file
has changed.

Compatible with ``WireClient``

Calls ``Dropbox.share`` afterwards to fill ``_itemRefs``.

@param {string} path - path of the folder to put, with leading slash
@param {Object} options
@param {string} options.ifNoneMatch - Only create of update the file if the
current ETag doesn't match this string
@returns {Promise} Resolves with an object containing the status code,
content-type and revision
@protected