Comparing version 0.0.9 to 0.0.10
@@ -0,0 +0,0 @@ var Rackit = require('./rackit.js'); |
@@ -84,3 +84,6 @@ /*global require, process, console*/ | ||
} | ||
}, cb); | ||
}, function(err, results) { | ||
// Avoid passing the results parameter on | ||
return cb(err); | ||
}); | ||
@@ -199,3 +202,3 @@ // Set up an interval to refresh the auth token that expires every 23 hours (it expires every 24). | ||
o1._log('request failed'); | ||
return cb(new Error('Error code ' + res.statusCode)); | ||
return cb(new Error('Error code ' + res.statusCode), res); | ||
} | ||
@@ -209,2 +212,27 @@ | ||
/** | ||
* Sends requests to the cloud server. The beginning of the URL is automatically prepended with the base storage url. | ||
* @param {string} method | ||
* @param {string} url | ||
* @param {Object} headers | ||
* @param {function(err)} cb | ||
*/ | ||
Rackit.prototype.storageRequest = function(method, url, headers, cb) { | ||
var o1 = this; | ||
// Normalize parameters | ||
if (typeof headers === 'function') { | ||
cb = headers; | ||
headers = {}; | ||
} | ||
var options = { | ||
method : method.toUpperCase(), | ||
uri : o1.config.storage + '/' + url, | ||
headers : headers | ||
}; | ||
o1._cloudRequest(options, cb); | ||
}; | ||
/** | ||
* Set's the account metadata key used for generating temporary URLs | ||
@@ -454,3 +482,3 @@ */ | ||
* @param {string|ReadableStream} source - Either a string (local path) or ReadableStream representing the file to add | ||
* @param {{type: string, filename: string, meta: Object, headers: Object.<string, string>}} options - Additonal options | ||
* @param {{type: string, filename: string, meta: Object, headers: Object.<string, string>}|function(?Error, string=)} options - Additonal options | ||
* @param {function(?Error, string=)} cb - Callback, returns error or the cloud path | ||
@@ -517,3 +545,3 @@ */ | ||
if (source.headers && source.headers['content-type']) { | ||
cb(); | ||
cb(null, source.headers['content-type']); | ||
} else { | ||
@@ -538,6 +566,11 @@ cb(new Error('Unable to determine content-type. You must specify the type for file streams.')); | ||
// | ||
// Generate the headers to be send to Rackspace | ||
// | ||
var headers = {}; | ||
if (fromFile) { | ||
headers['content-length'] = results.stats.size; | ||
headers['content-length'] = '' + results.stats.size; | ||
} else if (source.headers && source.headers['content-length']) { | ||
headers['content-length'] = source.headers['content-length']; | ||
} else { | ||
@@ -565,2 +598,5 @@ headers['transfer-encoding'] = 'chunked'; | ||
// | ||
// Generate the cloud request options | ||
// | ||
var cloudPath = results.container + '/' + id; | ||
@@ -589,2 +625,6 @@ var reqOptions = { | ||
source = fs.createReadStream(source); | ||
else if (source.headers) { | ||
// We want to remove any headers from the source stream so they don't clobber our own headers. | ||
delete source.headers; | ||
} | ||
@@ -599,11 +639,18 @@ source.resume(); | ||
* NOTE: The order is sorted primarily on container, and secondarily on object name. | ||
* @param {Object} options an optional hash specifing some additional options. Currently 'extended' is supported. | ||
* @param {function(Array)} cb(err, aCloudpaths) | ||
*/ | ||
Rackit.prototype.list = function (cb) { | ||
Rackit.prototype.list = function (options, cb) { | ||
// Get from the 0 container | ||
var o1 = this; | ||
var aCloudpaths = []; | ||
var aObjects = []; | ||
var asContainers = o1._getPrefixedContainers(); | ||
// Normalize the parameters | ||
if (typeof options === 'function') { | ||
cb = options; | ||
options = {}; | ||
} | ||
// List the objects for each container in parallel | ||
@@ -613,3 +660,3 @@ async.forEach( | ||
function (sContainer, cb) { | ||
o1._listContainer(sContainer, function (err, aObjects) { | ||
o1._listContainer(sContainer, function (err, aSomeObjects) { | ||
if (err) { | ||
@@ -619,8 +666,3 @@ return cb(err); | ||
// Append the container name to each result | ||
var i = aObjects.length; | ||
while (i--) { | ||
aObjects[i] = sContainer + '/' + aObjects[i]; | ||
} | ||
aCloudpaths = aCloudpaths.concat(aObjects); | ||
aObjects = aObjects.concat(aSomeObjects); | ||
cb(); | ||
@@ -631,3 +673,13 @@ }); | ||
function (err) { | ||
cb(err, err ? undefined : aCloudpaths); | ||
var i; | ||
// If the extended option is off, just return cloudpaths | ||
if (!options.extended) { | ||
i = aObjects.length; | ||
while (i--) { | ||
aObjects[i] = aObjects[i].cloudpath; | ||
} | ||
} | ||
cb(err, err ? undefined : aObjects); | ||
} | ||
@@ -653,3 +705,3 @@ ); | ||
if (someObjects.length >= o1.options.listLimit) { | ||
o1._listContainerPart(sContainer, someObjects.pop(), receiveSomeResults); | ||
o1._listContainerPart(sContainer, someObjects.pop().name, receiveSomeResults); | ||
return; | ||
@@ -692,7 +744,15 @@ } | ||
// Just get the cloudpaths of the returned objects | ||
var aObjects = JSON.parse(body); | ||
var aObjects; | ||
try { | ||
aObjects = JSON.parse(body); | ||
} catch(e) { | ||
return new Error('Error parsing JSON response'); | ||
} | ||
// Add the cloudpath parameter | ||
var i; | ||
for (i = 0; i < aObjects.length; i++) { | ||
aObjects[i] = aObjects[i].name; | ||
aObjects[i].cloudpath = sContainer + '/' + aObjects[i].name; | ||
} | ||
cb(null, aObjects); | ||
@@ -699,0 +759,0 @@ }); |
@@ -0,0 +0,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"keywords": ["api", "storage", "rackspace", "cloud", "cloudfiles"], | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"author": "Ross Johnson <ross@mazira.com>", | ||
@@ -8,0 +8,0 @@ "contributors": [], |
@@ -0,0 +0,0 @@ # Rackit |
@@ -220,3 +220,4 @@ /*global require, __dirname, describe, it, before, beforeEach, after*/ | ||
.matchHeader('X-Auth-Token', mockOptions.token) | ||
.matchHeader('Content-Type', type); | ||
.matchHeader('Content-Type', type) | ||
.matchHeader('ETag', undefined); | ||
@@ -226,3 +227,3 @@ if (chunked) { | ||
} else { | ||
scope.matchHeader('Content-Length', Buffer.byteLength(data)); | ||
scope.matchHeader('Content-Length', '' + Buffer.byteLength(data)); | ||
} | ||
@@ -617,3 +618,3 @@ | ||
superNock.add(container, testFile.data, testFile.type, true); | ||
rackit.add(fs.createReadStream(testFile.path), {type: testFile.type}, assertAdd(container, count + 1, cb)); | ||
rackit.add(stream, {type: testFile.type}, assertAdd(container, count + 1, cb)); | ||
}); | ||
@@ -644,2 +645,50 @@ | ||
it('should successfuly upload a ServerRequest stream with forwarded length', function (cb) { | ||
var container = 'empty0'; | ||
var count = getFreeContainerCount(container); | ||
superNock.add(container, testFile.data, testFile.type, false); | ||
// Set up the small server that will forward the request to Rackit | ||
var server = http.createServer(function(req, res) { | ||
rackit.add(req, assertAdd(container, count + 1, cb)); | ||
server.close(); | ||
}).listen(7357); | ||
// Create the request to the small server above | ||
var req = request.put({ | ||
uri : 'http://localhost:7357', | ||
headers: { | ||
'content-type': 'text/plain', | ||
'content-length': '' + Buffer.byteLength(testFile.data) | ||
} | ||
}); | ||
fs.createReadStream(testFile.path).pipe(req); | ||
}); | ||
it('should not forward the etag header of a ServerRequest stream', function (cb) { | ||
var container = 'empty0'; | ||
var count = getFreeContainerCount(container); | ||
superNock.add(container, testFile.data, testFile.type, true); | ||
// Set up the small server that will forward the request to Rackit | ||
var server = http.createServer(function(req, res) { | ||
rackit.add(req, assertAdd(container, count + 1, cb)); | ||
server.close(); | ||
}).listen(7357); | ||
// Create the request to the small server above | ||
var req = request.put({ | ||
uri : 'http://localhost:7357', | ||
headers: { | ||
'content-type': 'text/plain', | ||
'etag' : 'somehashvalue234' | ||
} | ||
}); | ||
fs.createReadStream(testFile.path).pipe(req); | ||
}); | ||
it('should successfuly upload a ServerRequest stream with explicit type', function (cb) { | ||
@@ -1004,3 +1053,3 @@ var container = 'empty0'; | ||
function getObjects (containers) { | ||
var i, j, container, objects = []; | ||
var i, j, container, object, objects = []; | ||
@@ -1015,8 +1064,23 @@ // Find the actual container objects to validate | ||
// Iterate each object in this container, adding the cloudpath to the object list | ||
// Iterate each object in this container, adding the container to the object name | ||
for (j = 0; j < container.objects.length; j++) { | ||
objects.push(container.name + '/' + container.objects[j].name); | ||
object = container.objects[j]; | ||
objects.push({ | ||
cloudpath : container.name + '/' + object.name, | ||
name : object.name, | ||
hash : object.hash, | ||
bytes : object.bytes, | ||
content_type : object.content_type, | ||
last_modified : object.last_modified | ||
}); | ||
} | ||
} | ||
return objects; | ||
} | ||
function getObjectCloudpaths (objects) { | ||
var i = objects.length; | ||
while (i--) | ||
objects[i] = objects[i].cloudpath; | ||
return objects; | ||
@@ -1075,3 +1139,3 @@ } | ||
assertList(prefix, listLimit, objects, cb); | ||
assertList(prefix, listLimit, getObjectCloudpaths(objects), cb); | ||
}); | ||
@@ -1093,3 +1157,3 @@ | ||
assertList(prefix, listLimit, objects, cb); | ||
assertList(prefix, listLimit, getObjectCloudpaths(objects), cb); | ||
}); | ||
@@ -1111,7 +1175,43 @@ | ||
assertList(prefix, listLimit, objects, cb); | ||
assertList(prefix, listLimit, getObjectCloudpaths(objects), cb); | ||
}); | ||
it('should return extended item info when specified as option', function (cb) { | ||
var prefix = 'multiple'; | ||
var listLimit = 1; | ||
// Assert the test conditions (at least one container with some objects) | ||
var containers = superNock.getPrefixedContainers(prefix); | ||
containers.length.should.be.above(0); | ||
// Find the actual container objects to validate | ||
var objects = getObjects(containers); | ||
objects.length.should.be.above(0); | ||
// Set the test options to Rackit | ||
rackit.options.prefix = prefix; | ||
rackit.options.listLimit = listLimit; | ||
// Set up the nock to respond to Rackit's requests | ||
superNock.list(prefix, listLimit); | ||
// Call Rackits list method | ||
rackit.list({ extended : true }, function(err, list) { | ||
superNock.allDone(); | ||
should.not.exist(err); | ||
should.exist(list); | ||
// Check the result length | ||
list.should.have.length(objects.length); | ||
// Check the result contents | ||
for (var i = 0; i < objects.length; i++) { | ||
list.should.includeEql(objects[i]); | ||
} | ||
cb(); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
70656
1894
0