diff --git a/lib/controllers.js b/lib/controllers.js index 6ff34da5..558622e7 100644 --- a/lib/controllers.js +++ b/lib/controllers.js @@ -60,9 +60,11 @@ module.exports = function (rootDirectory, logger) { template = templateBuilder.buildError('InvalidBucketName', 'Bucket names can contain lowercase letters, numbers, and hyphens. ' + 'Each label must start and end with a lowercase letter or a number.'); + logger.error('Error creating bucket "%s" because the name is invalid', bucketName); return buildXmlResponse(res, 400, template); } if (bucketName.length < 3 || bucketName.length > 63) { + logger.error('Error creating bucket "%s" because the name is invalid', bucketName); template = templateBuilder.buildError('InvalidBucketName', 'The bucket name must be between 3 and 63 characters.'); return buildXmlResponse(res, 400, template); @@ -106,6 +108,7 @@ module.exports = function (rootDirectory, logger) { fileStore.getObject(req.bucket, keyName, function (err, object, data) { if (err) { var template = templateBuilder.buildKeyNotFound(keyName); + logger.error('Object "%s" in bucket "%s" does not exist', keyName, req.bucket.name); return buildXmlResponse(res, 404, template); } @@ -138,35 +141,49 @@ module.exports = function (rootDirectory, logger) { }); }, putObject: function (req, res) { + var template; var copy = req.headers['x-amz-copy-source']; if (copy) { - var srcObjectParams = copy.split('/'); - var srcBucket = srcObjectParams[1]; - var srcObject = srcObjectParams.slice(2).join('/'); + var srcObjectParams = copy.split('/'), + srcBucket = srcObjectParams[1], + srcObject = srcObjectParams.slice(2).join('/'); fileStore.getBucket(srcBucket, function (err, bucket) { if (err) { logger.error('No bucket found for "%s"', srcBucket); - var template = templateBuilder.buildBucketNotFound(bucketName); + template = templateBuilder.buildBucketNotFound(srcBucket); return buildXmlResponse(res, 404, template); } - fileStore.copyObject(bucket, srcObject, req.bucket, req.params.key, function (err, key) { + fileStore.getObject(bucket, srcObject, function (err) { if (err) { - logger.error('Error copying object %s from bucket %s " into bucket "%s" with key of %s', - srcObject, bucket.name, req.bucket.name, req.params.key); - return res.status(400).json('Error copying file'); + logger.error('Object "%s" in bucket "%s" does not exist', srcObject, bucket.name); + template = templateBuilder.buildKeyNotFound(srcObject); + return buildXmlResponse(res, 404, template); } - logger.info('Copied object %s from bucket %s " into bucket "%s" with key of %s', - srcObject, bucket.name, req.bucket.name, req.params.key); - var template = templateBuilder.buildCopyObject(key); - return buildXmlResponse(res, 200, template); + fileStore.copyObject(bucket, srcObject, req.bucket, req.params.key, function (err, key) { + if (err) { + logger.error('Error copying object "%s" from bucket "%s" into bucket "%s" with key of "%s"', + srcObject, bucket.name, req.bucket.name, req.params.key); + template = templateBuilder.buildError('InternalError', + 'We encountered an internal error. Please try again.'); + return buildXmlResponse(res, 500, template); + } + + logger.info('Copied object "%s" from bucket "%s" into bucket "%s" with key of "%s"', + srcObject, bucket.name, req.bucket.name, req.params.key); + template = templateBuilder.buildCopyObject(key); + return buildXmlResponse(res, 200, template); + }); }); }); - } else { + } + else { fileStore.putObject(req.bucket, req, function (err, key) { if (err) { logger.error('Error uploading object "%s" to bucket "%s"', req.params.key, req.bucket.name, err); - return res.status(400).json('Error uploading file'); + var template = templateBuilder.buildError('InternalError', + 'We encountered an internal error. Please try again.'); + return buildXmlResponse(res, 500, template); } logger.info('Stored object "%s" in bucket "%s" successfully', req.params.key, req.bucket.name); res.header('ETag', key.md5); diff --git a/test/test.js b/test/test.js index c95415df..f4e95a54 100644 --- a/test/test.js +++ b/test/test.js @@ -23,7 +23,7 @@ describe('S3rver Tests', function () { s3rver.setHostname('localhost') .setPort(4569) .setDirectory('/tmp/s3rver_test_directory') - .setSilent(true) + .setSilent(false) .run(function (err, hostname, port, directory) { if (err) { return done('Error starting server', err); @@ -199,28 +199,45 @@ describe('S3rver Tests', function () { }); it('should copy an image object into another bucket', function (done) { - var file = path.join(__dirname, 'resources/image.jpg'); - fs.readFile(file, function (err, data) { + var params = { + Bucket: buckets[3], + Key: 'image/jamie', + CopySource: '/' + buckets[0] + '/image' + }; + s3Client.copyObject(params, function (err, data) { + /[a-fA-F0-9]{32}/.test(data.ETag).should.equal(true); if (err) { return done(err); } - var params = { - Bucket: buckets[3], - Key: 'image/jamie', - CopySource: '/' + buckets[0] + '/image' - }; - s3Client.copyObject(params, function (err, data) { - console.log('---------------------------- DATA ------------------------'); - console.log(data); - /[a-fA-F0-9]{32}/.test(data.ETag).should.equal(true); - if (err) { - return done(err); - } - done(); - }); + done(); }); }); + it('should fail to copy an image object because the object does not exist', function (done) { + var params = { + Bucket: buckets[3], + Key: 'image/jamie', + CopySource: '/' + buckets[0] + '/doesnotexist' + }; + s3Client.copyObject(params, function (err) { + err.code.should.equal('NoSuchKey'); + err.statusCode.should.equal(404); + done(); + }); + }); + + it('should fail to copy an image object because the source bucket does not exist', function (done) { + var params = { + Bucket: buckets[3], + Key: 'image/jamie', + CopySource: '/falsebucket/doesnotexist' + }; + s3Client.copyObject(params, function (err) { + err.code.should.equal('NoSuchBucket'); + err.statusCode.should.equal(404); + done(); + }); + }); it('should store a large buffer in a bucket', function (done) { // 20M