1 /**
  2  * @fileOverview AWS Connection.
  3  */
  4 
  5 (function () {
  6   var util = require('util'),
  7     utils = require("../../utils"),
  8     CloudError = require("../../errors").CloudError,
  9     BaseConnection = require("../../base/connection").Connection,
 10     Container = require("./blob/container").Container,
 11     AwsConnection;
 12 
 13   /**
 14    * Connection class.
 15    *
 16    * @param {Authentication} auth Authentication object.
 17    * @extends base.Connection
 18    * @exports AwsConnection as provider.aws.Connection
 19    * @constructor
 20    */
 21   AwsConnection = function (auth) {
 22     var self = this,
 23       invalid;
 24 
 25     BaseConnection.apply(self, arguments);
 26 
 27     // Header prefixes.
 28     self._HEADER_PREFIX = "x-amz-";
 29     self._METADATA_PREFIX = "x-amz-meta-";
 30 
 31     // Update variables.
 32     invalid = self._ERRORS.CONTAINER_INVALID_NAME;
 33     self._ERRORS.CONTAINER_INVALID_NAME = utils.extend(invalid, {
 34       attrs: {
 35         statusCode: 400,
 36         errorCode: "InvalidBucketName"
 37       },
 38       errorMap: {
 39         // Invalid container name with GET is both not found and invalid.
 40         'GET': {
 41           message: self._ERRORS.CONTAINER_INVALID_NAME.error.message,
 42           types: [
 43             CloudError.TYPES.NOT_FOUND,
 44             CloudError.TYPES.INVALID_NAME
 45           ]
 46         }
 47       }
 48     });
 49     self._ERRORS.CONTAINER_NOT_FOUND.attrs = {
 50       statusCode: 404,
 51       errorCode: "NoSuchBucket",
 52       errorHtml: "Not Found"
 53     };
 54     self._ERRORS.CONTAINER_NOT_EMPTY.attrs = {
 55       statusCode: 409,
 56       errorCode: "BucketNotEmpty"
 57     };
 58     self._ERRORS.CONTAINER_OTHER_OWNER.attrs = {
 59       statusCode: 409,
 60       errorCode: "BucketAlreadyExists"
 61     };
 62     self._ERRORS.BLOB_NOT_FOUND.attrs = {
 63       statusCode: 404,
 64       errorCode: "NoSuchKey",
 65       errorHtml: "Not Found"
 66     };
 67   };
 68 
 69   util.inherits(AwsConnection, BaseConnection);
 70 
 71   /**
 72    * Create container object.
 73    * @private
 74    */
 75   AwsConnection.prototype._createContainer = function (name) {
 76     return new Container(this, { name: name });
 77   };
 78 
 79   /**
 80    * Check if known error.
 81    *
 82    * @returns {boolean} True if error.
 83    * @private
 84    */
 85   AwsConnection.prototype._isError = function (errItem, err, response) {
 86     var attrs = errItem.attrs;
 87 
 88     // Test error codes or html
 89     /** @private */
 90     function errorCodeMatches() {
 91       if (!attrs.errorCode) { return false; }
 92       var regex = new RegExp("<Code>" + attrs.errorCode + "</Code>");
 93       return regex.test(err.message);
 94     }
 95 
 96     /** @private */
 97     function errorHtmlMatches() {
 98       if (!attrs.errorHtml) { return false; }
 99       var regex = new RegExp("<TITLE>" + attrs.errorHtml + "</TITLE>");
100       return regex.test(err.message);
101     }
102 
103     return attrs && response && response.statusCode === attrs.statusCode &&
104       (errorCodeMatches() || errorHtmlMatches());
105   };
106 
107   /**
108    * @see base.Connection#getContainers
109    */
110   AwsConnection.prototype.getContainers = function (options) {
111     var self = this,
112       meta = utils.extractMeta(options);
113 
114     options = options || {};
115     return self._auth.createXmlRequest(utils.extend(meta, {
116       encoding: 'utf8',
117       path: "/",
118       headers: {
119         'content-length': 0
120       },
121       resultsFn: function (result) {
122         var buckets = result.Buckets.Bucket || [],
123           containers = [];
124 
125         // Create container objects.
126         buckets.forEach(function (bucket) {
127           containers.push(new Container(self, {
128             name: bucket.Name,
129             created: bucket.CreationDate
130           }));
131         });
132 
133         return { containers: containers };
134       }
135     }));
136   };
137 
138   module.exports.Connection = AwsConnection;
139 }());
140