From 86326c5d9361026cc680d0944ff80327fcc2af73 Mon Sep 17 00:00:00 2001 From: Phred Date: Tue, 30 Oct 2012 16:54:57 -0500 Subject: [PATCH 1/2] addFile() should return the response from the server --- test/storage-object-test.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/test/storage-object-test.js b/test/storage-object-test.js index aee0bdf..b6e4b8d 100644 --- a/test/storage-object-test.js +++ b/test/storage-object-test.js @@ -13,7 +13,7 @@ var path = require('path'), cloudfiles = require('../lib/cloudfiles'), helpers = require('./helpers'); -var testData = {}, client = helpers.createClient(), +var testData = {}, client = helpers.createClient(), sampleData = fs.readFileSync(path.join(__dirname, '..', 'test', 'fixtures', 'fillerama.txt')).toString(); vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(client)).addBatch({ @@ -24,7 +24,7 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli remote: 'file1.txt', local: path.join(__dirname, '..', 'test', 'fixtures', 'fillerama.txt') }, function () { }); - + ustream.on('end', this.callback); }, "should raise the `end` event": function () { @@ -40,7 +40,7 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli remote: 'file2.txt', local: path.join(__dirname, '..', 'test', 'fixtures', 'fillerama.txt') }, function () { }); - + ustream.on('end', this.callback) }, "should raise the `end` event": function () { @@ -56,13 +56,13 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli readStream = fs.createReadStream(fileName), headers = { 'content-length': fs.statSync(fileName).size }, ustream; - + ustream = client.addFile('test_container', { remote: 'file3.txt', stream: readStream, headers: headers }, this.callback); - + ustream.on('end', this.callback); }, "should raise the `end` event": function () { @@ -74,12 +74,12 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli var fileName = path.join(__dirname, '..', 'test', 'fixtures', 'fillerama.txt'), readStream = fs.createReadStream(fileName), ustream; - + ustream = client.addFile('test_container', { remote: 'file3.txt', stream: readStream }, this.callback); - + ustream.on('end', this.callback); }, "should raise the `end` event": function () { @@ -87,6 +87,21 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli } } } +}).addBatch({ + "The node-cloudfiles client": { + "the addFile() method": { + topic: function () { + client.addFile('test_container', { + remote: 'file3.txt', + local: path.join(__dirname, '..', 'test', 'fixtures', 'fillerama.txt') + }, this.callback); + }, + "returns the response": function(err, response) { + assert.equal(typeof response, 'object'); + assert.isTrue('headers' in response); + } + } + } }).addBatch({ "The node-cloudfiles client": { "the getFiles() method": { @@ -124,7 +139,7 @@ vows.describe('node-cloudfiles/storage-object').addBatch(helpers.requireAuth(cli if (err) { return self.callback(err); } - + fs.stat(filename, self.callback) }); }, From aaed296d60358a44f36715091bcddf22e6fa5b55 Mon Sep 17 00:00:00 2001 From: Phred Date: Tue, 30 Oct 2012 16:55:09 -0500 Subject: [PATCH 2/2] made addFile() pass the server response to the callback --- lib/cloudfiles/core.js | 92 +++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/cloudfiles/core.js b/lib/cloudfiles/core.js index 524ad3a..2bc0e15 100644 --- a/lib/cloudfiles/core.js +++ b/lib/cloudfiles/core.js @@ -35,7 +35,7 @@ exports.createClient = function (options) { var Cloudfiles = exports.Cloudfiles = function (config) { this.config = config; this.authorized = false; - + // // Create the cache path for this instance immediately. // @@ -45,23 +45,23 @@ var Cloudfiles = exports.Cloudfiles = function (config) { // // ### function setAuth (callback) // #### @callback {function} Continuation to respond to when complete. -// Authenticates node-cloudfiles with the options specified +// Authenticates node-cloudfiles with the options specified // in the Config object for this instance // Cloudfiles.prototype.setAuth = function (callback) { var authOptions = { - uri: 'https://' + this.config.auth.host + '/v1.0', + uri: 'https://' + this.config.auth.host + '/v1.0', headers: { 'HOST': this.config.auth.host, 'X-AUTH-USER': this.config.auth.username, 'X-AUTH-KEY': this.config.auth.apiKey } }; - + var self = this; request(authOptions, function (err, res, body) { if (err) { - return callback(err); + return callback(err); } var statusCode = res.statusCode.toString(); @@ -78,7 +78,7 @@ Cloudfiles.prototype.setAuth = function (callback) { self.config.storageToken = res.headers['x-storage-token'] callback(null, res, self.config); - }); + }); }; // @@ -95,7 +95,7 @@ Cloudfiles.prototype.getContainers = function () { url = isCdn ? this.cdnUrl(true) : this.storageUrl(true); common.rackspace(url, this, callback, function (body) { - var results = [], + var results = [], containers = JSON.parse(body); containers.forEach(function (container) { @@ -132,21 +132,21 @@ Cloudfiles.prototype.getContainer = function () { isCdn = args.length > 0 && (typeof(args[args.length - 1]) === 'boolean') && args.pop(), containerName = args.pop(), containerOptions; - + containerOptions = { method: 'HEAD', uri: isCdn ? this.cdnUrl(containerName) : this.storageUrl(containerName), cdn: isCdn, client: this } - + common.rackspace(containerOptions, callback, function (body, res) { var container = { name: containerName, count: new Number(res.headers['x-container-object-count']), bytes: new Number(res.headers['x-container-bytes-used']) }; - + if (isCdn) { container.cdnUri = res.headers['x-cdn-uri']; container.cdnSslUri = res.headers['x-cdn-ssl-uri']; @@ -157,7 +157,7 @@ Cloudfiles.prototype.getContainer = function () { delete container.count; delete container.bytes; } - + callback(null, new (cloudfiles.Container)(self, container)); }); }; @@ -170,14 +170,14 @@ Cloudfiles.prototype.getContainer = function () { // with this instance. // Cloudfiles.prototype.createContainer = function (container, callback) { - var self = this, + var self = this, containerName = container instanceof cloudfiles.Container ? container.name : container; - + common.rackspace('PUT', this.storageUrl(containerName), this, callback, function (body, res) { if (typeof container.cdnEnabled !== 'undefined' && container.cdnEnabled) { container.ttl = container.ttl || self.config.cdn.ttl; container.logRetention = container.logRetention || self.config.cdn.logRetention; - + var cdnOptions = { uri: self.cdnUrl(containerName), method: 'PUT', @@ -187,7 +187,7 @@ Cloudfiles.prototype.createContainer = function (container, callback) { 'X-LOG-RETENTION': container.logRetention } }; - + common.rackspace(cdnOptions, callback, function (body, res) { container.cdnUri = res.headers['x-cdn-uri']; container.cdnSslUri = res.headers['x-cdn-ssl-uri']; @@ -212,32 +212,32 @@ Cloudfiles.prototype.destroyContainer = function (container, callback) { if (err) { return callback(err); } - + function deleteContainer (err) { if (err) { return callback(err); } - + common.rackspace('DELETE', self.storageUrl(container), self, callback, function (body, res) { callback(null, true); }); } - + function destroyFile (file, next) { file.destroy(next); } - + if (files.length === 0) { return deleteContainer(); } - + async.forEach(files, destroyFile, deleteContainer); }); }; Cloudfiles.prototype.getFiles = function (container, download, callback) { var self = this; - + // // Download is optional argument // And can be only: true, false, [array of files] @@ -252,20 +252,20 @@ Cloudfiles.prototype.getFiles = function (container, download, callback) { common.rackspace(this.storageUrl(container, true), this, callback, function (body) { var files = JSON.parse(body); - + // If download == false or wasn't defined if (!download) { var results = files.map(function (file) { file.container = container; return new (cloudfiles.StorageObject)(self, file); }); - + callback(null, results); return; } - + var batch; - + if (download instanceof RegExp || download == true) { // If download == true // Download all files @@ -274,21 +274,21 @@ Cloudfiles.prototype.getFiles = function (container, download, callback) { return download.test(file.name); }); } - + // Create a batch batch = files.map(function (file) { return function (callback) { self.getFile(container, file.name, callback); } - }); - } + }); + } else if (Array.isArray(download)) { - // Go through all files that we've asked to download + // Go through all files that we've asked to download batch = download.map(function (file) { var exists = files.some(function (item) { return item.name == file }); - + // If file exists - get it // If not report about error return exists ? @@ -299,30 +299,30 @@ Cloudfiles.prototype.getFiles = function (container, download, callback) { callback(Error('File : ' + file + ' doesn\'t exists')); }; }); - } + } else { callback(Error('"download" argument can be only boolean, array or regexp')); } - + // Run batch common.runBatch(batch, callback); }); }; Cloudfiles.prototype.getFile = function (container, filename, callback) { - var self = this, + var self = this, containerPath = path.join(this.config.cache.path, container), cacheFile = path.join(containerPath, filename), options; - + common.statOrMkdirp(containerPath); - + var lstream = fs.createWriteStream(cacheFile), rstream, options; - + options = { - method: 'GET', + method: 'GET', client: self, uri: self.storageUrl(container, filename), download: lstream @@ -371,11 +371,11 @@ Cloudfiles.prototype.addFile = function (container, options, callback) { else if (options.stream) { lstream = options.stream; } - + if (!lstream) { return callback(new Error('.local or .stream is required to addFile.')); } - + addOptions = { method: 'PUT', client: this, @@ -383,13 +383,13 @@ Cloudfiles.prototype.addFile = function (container, options, callback) { uri: this.storageUrl(container, options.remote), headers: options.headers || {} }; - + if (options.headers && !options.headers['content-type']) { options.headers['content-type'] = mime.lookup(options.remote); } - + return common.rackspace(addOptions, callback, function (body, res) { - callback(null, true); + callback(null, res); }); }; @@ -410,12 +410,12 @@ Cloudfiles.prototype.destroyFile = function (container, file, callback) { // ### function storageUrl (arguments) // #### @arguments {Array} Lists of arguments to convert into a storage url. // Helper method that concats the string params into a url to request against -// the authenticated node-cloudfiles storageUrl. +// the authenticated node-cloudfiles storageUrl. // Cloudfiles.prototype.storageUrl = function () { var args = Array.prototype.slice.call(arguments), json = (typeof(args[args.length - 1]) === 'boolean') && args.pop(); - + return [this.config.storageUrl].concat(args).join('/') + (json ? '?format=json' : ''); }; @@ -423,11 +423,11 @@ Cloudfiles.prototype.storageUrl = function () { // ### function cdnUrl (arguments) // #### @arguments {Array} Lists of arguments to convert into a cdn url. // Helper method that concats the string params into a url -// to request against the authenticated node-cloudfiles cdnUrl. +// to request against the authenticated node-cloudfiles cdnUrl. // Cloudfiles.prototype.cdnUrl = function () { var args = Array.prototype.slice.call(arguments), json = (typeof(args[args.length - 1]) === 'boolean') && args.pop(); - + return [this.config.cdnUrl].concat(args).join('/') + (json ? '?format=json' : ''); };