diff --git a/.jshintrc b/.jshintrc
index 80e742d3b1..46c92c1d51 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -22,5 +22,6 @@
"maxparams": false,
"maxdepth": false,
"maxstatements": 40,
- "maxcomplexity": 5
+ "maxcomplexity": 5,
+ "sub": true
}
diff --git a/doc-src/dynamodb.docs.js b/doc-src/dynamodb.docs.js
index c139d204d7..4598217716 100644
--- a/doc-src/dynamodb.docs.js
+++ b/doc-src/dynamodb.docs.js
@@ -98,7 +98,7 @@ AWS.DynamoDB = inherit({})
* * +ConsistentRead+ - (Boolean)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -156,7 +156,7 @@ AWS.DynamoDB = inherit({})
* binary attributes.
* * +AttributesToGet+ - (Array)
* * +ConsistentRead+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method batchWriteItem(params, callback)
@@ -228,7 +228,7 @@ AWS.DynamoDB = inherit({})
* binary attributes.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -302,7 +302,7 @@ AWS.DynamoDB = inherit({})
* * +NS+ - (Array) A set of numbers.
* * +BS+ - (Array) A set of
* binary attributes.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method createTable(params, callback)
@@ -343,7 +343,7 @@ AWS.DynamoDB = inherit({})
* WriteCapacityUnits.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -383,7 +383,7 @@ AWS.DynamoDB = inherit({})
* * +WriteCapacityUnits+ - (Integer)
* * +TableSizeBytes+ - (Integer)
* * +ItemCount+ - (Integer)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteItem(params, callback)
@@ -450,7 +450,7 @@ AWS.DynamoDB = inherit({})
* * +ReturnValues+ - (String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -475,7 +475,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteTable(params, callback)
@@ -486,7 +486,7 @@ AWS.DynamoDB = inherit({})
* _ (underscore), - (hyphen) and . (period).
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -526,7 +526,7 @@ AWS.DynamoDB = inherit({})
* * +WriteCapacityUnits+ - (Integer)
* * +TableSizeBytes+ - (Integer)
* * +ItemCount+ - (Integer)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method describeTable(params, callback)
@@ -538,7 +538,7 @@ AWS.DynamoDB = inherit({})
* 0-9, _ (underscore), - (hyphen) and . (period).
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -578,7 +578,7 @@ AWS.DynamoDB = inherit({})
* * +WriteCapacityUnits+ - (Integer)
* * +TableSizeBytes+ - (Integer)
* * +ItemCount+ - (Integer)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getItem(params, callback)
@@ -628,7 +628,7 @@ AWS.DynamoDB = inherit({})
* * +ConsistentRead+ - (Boolean)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -651,7 +651,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listTables(params, callback)
@@ -665,7 +665,7 @@ AWS.DynamoDB = inherit({})
* * +Limit+ - (Integer)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -678,7 +678,7 @@ AWS.DynamoDB = inherit({})
* ExclusiveStartTableName in a new request to continue the list
* until all the table names are returned. If this value is null,
* all table names have been returned.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putItem(params, callback)
@@ -724,7 +724,7 @@ AWS.DynamoDB = inherit({})
* * +ReturnValues+ - (String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -748,7 +748,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method query(params, callback)
@@ -853,7 +853,7 @@ AWS.DynamoDB = inherit({})
* attributes.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -904,7 +904,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method scan(params, callback)
@@ -989,7 +989,7 @@ AWS.DynamoDB = inherit({})
* attributes.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1043,7 +1043,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method updateItem(params, callback)
@@ -1126,7 +1126,7 @@ AWS.DynamoDB = inherit({})
* * +ReturnValues+ - (String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1150,7 +1150,7 @@ AWS.DynamoDB = inherit({})
* * +BS+ - (Array) A set of binary
* attributes.
* * +ConsumedCapacityUnits+ - (Float)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method updateTable(params, callback)
@@ -1171,7 +1171,7 @@ AWS.DynamoDB = inherit({})
* WriteCapacityUnits.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1211,7 +1211,7 @@ AWS.DynamoDB = inherit({})
* * +WriteCapacityUnits+ - (Integer)
* * +TableSizeBytes+ - (Integer)
* * +ItemCount+ - (Integer)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
*
diff --git a/doc-src/guide/MakingRequests.md b/doc-src/guide/MakingRequests.md
index 47e35687e3..a531c3aa26 100644
--- a/doc-src/guide/MakingRequests.md
+++ b/doc-src/guide/MakingRequests.md
@@ -27,11 +27,11 @@ The `error` and `data` parameters are described in the "Response Object"
section below.
Note that if you do not specify a callback, the operation will
-return an `AWS.AWSRequest` object that must be manually sent using
+return an `AWS.Request` object that must be manually sent using
the `send()` method:
```js
-// create the AWS.AWSRequest object
+// create the AWS.Request object
var request = new AWS.EC2().client.describeInstances();
// register a callback to report on the data
@@ -43,10 +43,10 @@ request.done(function(resp) {
request.send();
```
-### The Response Object (`AWS.AWSResponse`)
+### The Response Object (`AWS.Response`)
The response object is passed into each callback function so
-that you can access response data. The `AWS.AWSResponse` object that
+that you can access response data. The `AWS.Response` object that
is passed in contains two important properties to get at this data:
When using the standard callback mechanism, the two properties will
@@ -88,7 +88,7 @@ before attempting to access the `response.data` property.
Currently, you can register callbacks for various events by
either using the simplified callback syntax, or by using the callback
-methods on the returned `AWS.AWSRequest` object.
+methods on the returned `AWS.Request` object.
#### Simplified Callback Method
@@ -101,9 +101,9 @@ For example:
```js
s3.client.listBuckets(function(error, data) {
if (err) {
- console.log(error); // error is AWSResponse.error
+ console.log(error); // error is Response.error
} else {
- console.log(data); // data is AWSResponse.data
+ console.log(data); // data is Response.data
}
});
```
@@ -119,7 +119,7 @@ Prints (assuming the request succeeded):
```
The error and data parameters accepted are equivalent to the `error` and
-`data` properties discussed in the `AWS.AWSResponse` response object section
+`data` properties discussed in the `AWS.Response` response object section
above.
If you are passing parameters to the operation, the callback should be placed
@@ -131,10 +131,10 @@ s3.client.getObject({Bucket: 'bucket', Key: 'key'}, function(err, data) {
});
```
-#### AWS.AWSRequest Callbacks
+#### AWS.Request Callbacks
You can alternatively register callbacks on events provided by the
-`AWS.AWSRequest` object returned by each low-level client operation method.
+`AWS.Request` object returned by each low-level client operation method.
This request object exposes the `done`, `fail`, `data`, and `always`
events, each taking a callback that accepts the response object.
@@ -221,7 +221,7 @@ request.always(function(response) {
## Binding Custom Context Data on a Callback
By default, the `this` context of a callback function registered on an
-event will be the `AWS.AWSResponse` object returned from the service.
+event will be the `AWS.Response` object returned from the service.
In some cases, it may be necessary to pass extra custom context to these
functions; in these cases, you can bind a custom value to be used as the
`this` context object when the callbacks are executed. To do so, pass
diff --git a/doc-src/s3.docs.js b/doc-src/s3.docs.js
index ec7201e09c..9835f572fe 100644
--- a/doc-src/s3.docs.js
+++ b/doc-src/s3.docs.js
@@ -58,13 +58,13 @@ AWS.S3 = inherit({})
* * +UploadId+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method completeMultipartUpload(params, callback)
@@ -82,7 +82,7 @@ AWS.S3 = inherit({})
* was uploaded.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -99,7 +99,7 @@ AWS.S3 = inherit({})
* * +ServerSideEncryption+ - (String) The Server-side
* encryption algorithm used when storing this object in S3.
* * +VersionId+ - (String) Version of the object.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method copyObject(params, callback)
@@ -154,7 +154,7 @@ AWS.S3 = inherit({})
* store with the object in S3.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -169,7 +169,7 @@ AWS.S3 = inherit({})
* * +CopySourceVersionId+ - (String)
* * +ServerSideEncryption+ - (String) The Server-side
* encryption algorithm used when storing this object in S3.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method createBucket(params, callback)
@@ -192,7 +192,7 @@ AWS.S3 = inherit({})
* write, read ACP, and write ACP permissions on the bucket.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -200,7 +200,7 @@ AWS.S3 = inherit({})
* the request. Set to +null+ if a request error occurs.
* The +data+ object has the following properties:
* * +Location+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method createMultipartUpload(params, callback)
@@ -241,7 +241,7 @@ AWS.S3 = inherit({})
* store with the object in S3.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -256,7 +256,7 @@ AWS.S3 = inherit({})
* upload.
* * +ServerSideEncryption+ - (String) The Server-side
* encryption algorithm used when storing this object in S3.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucket(params, callback)
@@ -267,13 +267,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucketCors(params, callback)
@@ -282,13 +282,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucketLifecycle(params, callback)
@@ -297,13 +297,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucketPolicy(params, callback)
@@ -312,13 +312,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucketTagging(params, callback)
@@ -327,13 +327,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteBucketWebsite(params, callback)
@@ -342,13 +342,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteObject(params, callback)
@@ -360,7 +360,7 @@ AWS.S3 = inherit({})
* * +Key+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -372,7 +372,7 @@ AWS.S3 = inherit({})
* not (false) a delete marker.
* * +VersionId+ - (String) Returns the version ID of the
* delete marker created as a result of the DELETE operation.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deleteObjects(params, callback)
@@ -394,7 +394,7 @@ AWS.S3 = inherit({})
* that is displayed on your authentication device.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -411,7 +411,7 @@ AWS.S3 = inherit({})
* * +VersionId+ - (String)
* * +Code+ - (String)
* * +Message+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketAcl(params, callback)
@@ -420,7 +420,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -442,7 +442,7 @@ AWS.S3 = inherit({})
* * +URI+ - (String) URI of the grantee group.
* * +Permission+ - (String) Specifies the permission
* given to the grantee.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketCors(params, callback)
@@ -451,7 +451,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -472,7 +472,7 @@ AWS.S3 = inherit({})
* in the response that you want customers to be able to access
* from their applications (for example, from a JavaScript
* XMLHttpRequest object).
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketLifecycle(params, callback)
@@ -481,7 +481,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -510,7 +510,7 @@ AWS.S3 = inherit({})
* be a non-zero positive integer.
* * +Date+ - (Date) Indicates at what date the object
* is to be moved or deleted. Should be in GMT ISO 8601 Format.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketLocation(params, callback)
@@ -519,7 +519,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -527,7 +527,7 @@ AWS.S3 = inherit({})
* the request. Set to +null+ if a request error occurs.
* The +data+ object has the following properties:
* * +LocationConstraint+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketLogging(params, callback)
@@ -538,7 +538,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -568,7 +568,7 @@ AWS.S3 = inherit({})
* grantee.
* * +URI+ - (String) URI of the grantee group.
* * +Permission+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketNotification(params, callback)
@@ -577,7 +577,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -590,7 +590,7 @@ AWS.S3 = inherit({})
* the bucket.
* * +Event+ - (String) Bucket event for which to send
* notifications.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketPolicy(params, callback)
@@ -599,7 +599,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -608,7 +608,7 @@ AWS.S3 = inherit({})
* The +data+ object has the following properties:
* * +Policy+ - (String) The bucket policy as a JSON
* document.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketRequestPayment(params, callback)
@@ -617,7 +617,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -626,7 +626,7 @@ AWS.S3 = inherit({})
* The +data+ object has the following properties:
* * +Payer+ - (String) Specifies who pays for the download
* and request fees.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketTagging(params, callback)
@@ -635,7 +635,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -645,7 +645,7 @@ AWS.S3 = inherit({})
* * +TagSet+ - (Array)
* * +Key+ - (String) Name of the tag.
* * +Value+ - (String) Value of the tag.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketVersioning(params, callback)
@@ -654,7 +654,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -667,7 +667,7 @@ AWS.S3 = inherit({})
* only returned if the bucket has been configured with MFA delete.
* If the bucket has never been so configured, this element is not
* returned.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getBucketWebsite(params, callback)
@@ -676,7 +676,7 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -693,7 +693,7 @@ AWS.S3 = inherit({})
* * +ErrorDocument+ - (Object)
* * +Key+ - (String) The object key name to use when a
* 4XX class error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getObject(params, callback)
@@ -733,7 +733,7 @@ AWS.S3 = inherit({})
* return a 304 (not modified).
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -772,7 +772,7 @@ AWS.S3 = inherit({})
* * +VersionId+ - (String) Version of the object.
* * +Metadata+ - (Object) A map of metadata to
* store with the object in S3.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getObjectAcl(params, callback)
@@ -784,7 +784,7 @@ AWS.S3 = inherit({})
* specific version of the object.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -806,7 +806,7 @@ AWS.S3 = inherit({})
* * +URI+ - (String) URI of the grantee group.
* * +Permission+ - (String) Specifies the permission
* given to the grantee.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getObjectTorrent(params, callback)
@@ -816,7 +816,7 @@ AWS.S3 = inherit({})
* * +Key+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -824,7 +824,7 @@ AWS.S3 = inherit({})
* the request. Set to +null+ if a request error occurs.
* The +data+ object has the following properties:
* * +Body+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method headBucket(params, callback)
@@ -834,13 +834,13 @@ AWS.S3 = inherit({})
* * +Bucket+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method headObject(params, callback)
@@ -871,7 +871,7 @@ AWS.S3 = inherit({})
* return a 304 (not modified).
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -909,7 +909,7 @@ AWS.S3 = inherit({})
* * +VersionId+ - (String) Version of the object.
* * +Metadata+ - (Object) A map of metadata to
* store with the object in S3.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listBuckets(params, callback)
@@ -918,7 +918,7 @@ AWS.S3 = inherit({})
* @param params [Object]
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -931,7 +931,7 @@ AWS.S3 = inherit({})
* * +Owner+ - (Object)
* * +ID+ - (String)
* * +DisplayName+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listMultipartUploads(params, callback)
@@ -954,7 +954,7 @@ AWS.S3 = inherit({})
* is ignored.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -999,7 +999,7 @@ AWS.S3 = inherit({})
* it provides the Canonical User ID. If the principal is an
* IAM User, it provides a user ARN value.
* * +DisplayName+ - (String) Name of the Principal.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listObjectVersions(params, callback)
@@ -1019,7 +1019,7 @@ AWS.S3 = inherit({})
* begin with the specified prefix.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1069,7 +1069,7 @@ AWS.S3 = inherit({})
* results.
* * +CommonPrefixes+ - (Array)
* * +Prefix+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listObjects(params, callback)
@@ -1089,7 +1089,7 @@ AWS.S3 = inherit({})
* begin with the specified prefix.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1119,7 +1119,7 @@ AWS.S3 = inherit({})
* results.
* * +CommonPrefixes+ - (Array)
* * +Prefix+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listParts(params, callback)
@@ -1137,7 +1137,7 @@ AWS.S3 = inherit({})
* will be listed.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1179,7 +1179,7 @@ AWS.S3 = inherit({})
* * +DisplayName+ - (String)
* * +StorageClass+ - (String) The class of storage used to
* store the object.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketAcl(params, callback)
@@ -1215,13 +1215,13 @@ AWS.S3 = inherit({})
* write, read ACP, and write ACP permissions on the bucket.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketCors(params, callback)
@@ -1245,13 +1245,13 @@ AWS.S3 = inherit({})
* JavaScript XMLHttpRequest object).
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketLifecycle(params, callback)
@@ -1286,13 +1286,13 @@ AWS.S3 = inherit({})
* Format.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketLogging(params, callback)
@@ -1327,13 +1327,13 @@ AWS.S3 = inherit({})
* * +Permission+ - (String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketNotification(params, callback)
@@ -1349,13 +1349,13 @@ AWS.S3 = inherit({})
* notifications.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketPolicy(params, callback)
@@ -1367,13 +1367,13 @@ AWS.S3 = inherit({})
* JSON document.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketRequestPayment(params, callback)
@@ -1388,13 +1388,13 @@ AWS.S3 = inherit({})
* the download and request fees.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketTagging(params, callback)
@@ -1407,13 +1407,13 @@ AWS.S3 = inherit({})
* * +Value+ - (*required*, String) Value of the tag.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketVersioning(params, callback)
@@ -1434,13 +1434,13 @@ AWS.S3 = inherit({})
* displayed on your authentication device.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putBucketWebsite(params, callback)
@@ -1461,13 +1461,13 @@ AWS.S3 = inherit({})
* use when a 4XX class error occurs.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putObject(params, callback)
@@ -1509,7 +1509,7 @@ AWS.S3 = inherit({})
* store with the object in S3.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1523,7 +1523,7 @@ AWS.S3 = inherit({})
* encryption algorithm used when storing this object in S3.
* * +ETag+ - (String) Entity tag for the uploaded object.
* * +VersionId+ - (String) Version of the object.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method putObjectAcl(params, callback)
@@ -1561,13 +1561,13 @@ AWS.S3 = inherit({})
* write, read ACP, and write ACP permissions on the bucket.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method restoreObject(params, callback)
@@ -1580,13 +1580,13 @@ AWS.S3 = inherit({})
* copy in days
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method uploadPart(params, callback)
@@ -1601,7 +1601,7 @@ AWS.S3 = inherit({})
* * +Body+ - (String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1611,7 +1611,7 @@ AWS.S3 = inherit({})
* * +ServerSideEncryption+ - (String) The Server-side
* encryption algorithm used when storing this object in S3.
* * +ETag+ - (String) Entity tag for the uploaded object.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method uploadPartCopy(params, callback)
@@ -1643,7 +1643,7 @@ AWS.S3 = inherit({})
* if it has been modified since the specified time.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1659,7 +1659,7 @@ AWS.S3 = inherit({})
* object was uploaded.
* * +ServerSideEncryption+ - (String) The Server-side
* encryption algorithm used when storing this object in S3.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
*
diff --git a/doc-src/simpleworkflow.docs.js b/doc-src/simpleworkflow.docs.js
index aff73aca8b..5dd7368733 100644
--- a/doc-src/simpleworkflow.docs.js
+++ b/doc-src/simpleworkflow.docs.js
@@ -84,7 +84,7 @@ AWS.SimpleWorkflow = inherit({})
* * +status+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -93,7 +93,7 @@ AWS.SimpleWorkflow = inherit({})
* The +data+ object has the following properties:
* * +count+ - (Integer)
* * +truncated+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method countOpenWorkflowExecutions(params, callback)
@@ -120,7 +120,7 @@ AWS.SimpleWorkflow = inherit({})
* * +workflowId+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -129,7 +129,7 @@ AWS.SimpleWorkflow = inherit({})
* The +data+ object has the following properties:
* * +count+ - (Integer)
* * +truncated+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method countPendingActivityTasks(params, callback)
@@ -145,7 +145,7 @@ AWS.SimpleWorkflow = inherit({})
* * +name+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -154,7 +154,7 @@ AWS.SimpleWorkflow = inherit({})
* The +data+ object has the following properties:
* * +count+ - (Integer)
* * +truncated+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method countPendingDecisionTasks(params, callback)
@@ -170,7 +170,7 @@ AWS.SimpleWorkflow = inherit({})
* * +name+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -179,7 +179,7 @@ AWS.SimpleWorkflow = inherit({})
* The +data+ object has the following properties:
* * +count+ - (Integer)
* * +truncated+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deprecateActivityType(params, callback)
@@ -196,13 +196,13 @@ AWS.SimpleWorkflow = inherit({})
* * +version+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deprecateDomain(params, callback)
@@ -217,13 +217,13 @@ AWS.SimpleWorkflow = inherit({})
* deprecate.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method deprecateWorkflowType(params, callback)
@@ -241,13 +241,13 @@ AWS.SimpleWorkflow = inherit({})
* * +version+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method describeActivityType(params, callback)
@@ -263,7 +263,7 @@ AWS.SimpleWorkflow = inherit({})
* * +version+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -285,7 +285,7 @@ AWS.SimpleWorkflow = inherit({})
* * +name+ - (String)
* * +defaultTaskScheduleToStartTimeout+ - (String)
* * +defaultTaskScheduleToCloseTimeout+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method describeDomain(params, callback)
@@ -296,7 +296,7 @@ AWS.SimpleWorkflow = inherit({})
* describe.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -310,7 +310,7 @@ AWS.SimpleWorkflow = inherit({})
* * +configuration+ - (Object)
* * +workflowExecutionRetentionPeriodInDays+ - (*required*,
* String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method describeWorkflowExecution(params, callback)
@@ -325,7 +325,7 @@ AWS.SimpleWorkflow = inherit({})
* * +runId+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -361,7 +361,7 @@ AWS.SimpleWorkflow = inherit({})
* * +openChildWorkflowExecutions+ - (Integer)
* * +latestActivityTaskTimestamp+ - (Date)
* * +latestExecutionContext+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method describeWorkflowType(params, callback)
@@ -377,7 +377,7 @@ AWS.SimpleWorkflow = inherit({})
* * +version+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -398,7 +398,7 @@ AWS.SimpleWorkflow = inherit({})
* * +defaultTaskList+ - (Object)
* * +name+ - (String)
* * +defaultChildPolicy+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method getWorkflowExecutionHistory(params, callback)
@@ -427,7 +427,7 @@ AWS.SimpleWorkflow = inherit({})
* in ascending order of the eventTimeStamp of the events.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -766,7 +766,7 @@ AWS.SimpleWorkflow = inherit({})
* Integer)
* * +control+ - (String)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listActivityTypes(params, callback)
@@ -798,7 +798,7 @@ AWS.SimpleWorkflow = inherit({})
* activity types.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -814,7 +814,7 @@ AWS.SimpleWorkflow = inherit({})
* * +creationDate+ - (Date)
* * +deprecationDate+ - (Date)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listClosedWorkflowExecutions(params, callback)
@@ -869,7 +869,7 @@ AWS.SimpleWorkflow = inherit({})
* the executions.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -893,7 +893,7 @@ AWS.SimpleWorkflow = inherit({})
* * +tagList+ - (Array)
* * +cancelRequested+ - (Boolean)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listDomains(params, callback)
@@ -917,7 +917,7 @@ AWS.SimpleWorkflow = inherit({})
* domains.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -929,7 +929,7 @@ AWS.SimpleWorkflow = inherit({})
* * +status+ - (String)
* * +description+ - (String)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listOpenWorkflowExecutions(params, callback)
@@ -970,7 +970,7 @@ AWS.SimpleWorkflow = inherit({})
* * +workflowId+ - (*required*, String)
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -994,7 +994,7 @@ AWS.SimpleWorkflow = inherit({})
* * +tagList+ - (Array)
* * +cancelRequested+ - (Boolean)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method listWorkflowTypes(params, callback)
@@ -1022,7 +1022,7 @@ AWS.SimpleWorkflow = inherit({})
* workflow types.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1038,7 +1038,7 @@ AWS.SimpleWorkflow = inherit({})
* * +creationDate+ - (Date)
* * +deprecationDate+ - (Date)
* * +nextPageToken+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method pollForActivityTask(params, callback)
@@ -1063,7 +1063,7 @@ AWS.SimpleWorkflow = inherit({})
* problems arise. The form of this identity is user defined.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1080,7 +1080,7 @@ AWS.SimpleWorkflow = inherit({})
* * +name+ - (String)
* * +version+ - (String)
* * +input+ - (String)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method pollForDecisionTask(params, callback)
@@ -1113,7 +1113,7 @@ AWS.SimpleWorkflow = inherit({})
* in ascending order of the eventTimestamp of the events.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1461,7 +1461,7 @@ AWS.SimpleWorkflow = inherit({})
* * +control+ - (String)
* * +nextPageToken+ - (String)
* * +previousStartedEventId+ - (Integer)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method recordActivityTaskHeartbeat(params, callback)
@@ -1480,7 +1480,7 @@ AWS.SimpleWorkflow = inherit({})
* about the progress of the task.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1488,7 +1488,7 @@ AWS.SimpleWorkflow = inherit({})
* the request. Set to +null+ if a request error occurs.
* The +data+ object has the following properties:
* * +cancelRequested+ - (Boolean)
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method registerActivityType(params, callback)
@@ -1536,13 +1536,13 @@ AWS.SimpleWorkflow = inherit({})
* activity task using the ScheduleActivityTask Decision.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method registerDomain(params, callback)
@@ -1562,13 +1562,13 @@ AWS.SimpleWorkflow = inherit({})
* retained at all.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method registerWorkflowType(params, callback)
@@ -1610,13 +1610,13 @@ AWS.SimpleWorkflow = inherit({})
* policies are:
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method requestCancelWorkflowExecution(params, callback)
@@ -1635,13 +1635,13 @@ AWS.SimpleWorkflow = inherit({})
* to cancel.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method respondActivityTaskCanceled(params, callback)
@@ -1655,13 +1655,13 @@ AWS.SimpleWorkflow = inherit({})
* cancellation.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method respondActivityTaskCompleted(params, callback)
@@ -1674,13 +1674,13 @@ AWS.SimpleWorkflow = inherit({})
* is a free form string that is implementation specific.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method respondActivityTaskFailed(params, callback)
@@ -1695,13 +1695,13 @@ AWS.SimpleWorkflow = inherit({})
* about the failure.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method respondDecisionTaskCompleted(params, callback)
@@ -1791,13 +1791,13 @@ AWS.SimpleWorkflow = inherit({})
* add to workflow execution.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method signalWorkflowExecution(params, callback)
@@ -1820,13 +1820,13 @@ AWS.SimpleWorkflow = inherit({})
* execution's history.
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method startWorkflowExecution(params, callback)
@@ -1879,7 +1879,7 @@ AWS.SimpleWorkflow = inherit({})
* RegisterWorkflowType. The supported child policies are:
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
@@ -1889,7 +1889,7 @@ AWS.SimpleWorkflow = inherit({})
* * +runId+ - (String) The runId of a workflow execution.
* This Id is generated by the service and can be used to uniquely
* identify the workflow execution within a domain.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
* @!method terminateWorkflowExecution(params, callback)
@@ -1917,13 +1917,13 @@ AWS.SimpleWorkflow = inherit({})
* are:
* @callback callback function(err, data)
* Called when a response from the service is returned. If a
- * callback is not supplied, you must call {AWS.AWSRequest.send}
+ * callback is not supplied, you must call {AWS.Request.send}
* on the returned request object to initiate the request.
* @param err [Object] the error object returned from the request.
* Set to +null+ if the request is successful.
* @param data [Object] the de-serialized data returned from
* the request. Set to +null+ if a request error occurs.
- * @return [AWS.AWSRequest] a handle to the operation request for
+ * @return [AWS.Request] a handle to the operation request for
* subsequent event callback registration.
*
*
diff --git a/features/support/helpers.js b/features/support/helpers.js
index ad186aa1a2..566d93312f 100644
--- a/features/support/helpers.js
+++ b/features/support/helpers.js
@@ -71,7 +71,7 @@ module.exports = {
* finish execution before moving onto the next step in the scenario.
*/
request: function request(svc, operation, params, next) {
- this[svc][operation](params).always(function (resp) {
+ this[svc][operation](params).on('complete', function (resp) {
if (resp.error) {
this.unexpectedError(resp, next);
} else {
diff --git a/lib/client.js b/lib/client.js
index d57bec2984..fb08257c80 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -14,6 +14,7 @@
*/
var AWS = require('./core');
+require('./event_listeners');
var inherit = AWS.util.inherit;
/**
@@ -39,65 +40,37 @@ AWS.Client = inherit({
callback = params;
params = {};
}
- var request = new AWS.AWSRequest(this, operation, params);
+
+ var request = new AWS.Request(this, operation, params);
+ this.addAllRequestListeners(request);
+
if (callback) {
- request.always(function (resp) {
+ request.on('complete', function (resp) {
callback.call(resp, resp.error, resp.data);
});
request.send();
}
- return request;
- },
- parseResponse: function parseResponse(httpResponse, method, callback) {
- var error = null, data = null;
- try {
- if (this.successfulResponse(httpResponse, method)) {
- data = this.extractData(httpResponse, method);
- } else {
- error = this.extractError(httpResponse, method);
- error.statusCode = httpResponse.statusCode;
- error.retryable = this.retryableError(error, method);
- }
- } catch (err) {
- // unrecoverable error trying to parse the response data/error
- error = err;
- }
- callback.call(this, error, data);
+ return request;
},
- successfulResponse: function successfulResponse(httpResponse) {
- return httpResponse.statusCode < 300;
+ addAllRequestListeners: function addAllRequestListeners(request) {
+ request.addListeners(AWS.EventListeners.Core);
+ request.addListeners(AWS.EventListeners.Http);
+ this.setupRequestListeners(request);
},
- newHttpRequest: function newHttpRequest() {
-
- var serviceName = this.serviceName;
- var credentials = AWS.util.copy(this.config.credentials);
- var signatureVersion = this.signatureVersion;
-
- var httpRequest = new AWS.HttpRequest();
- httpRequest.endpoint = AWS.util.copy(this.endpoint);
- httpRequest.region = this.config.region;
- httpRequest.sign = function sign() {
- /*jshint newcap:false*/
- var signer = new signatureVersion(httpRequest, serviceName);
- signer.addAuthorization(credentials);
- };
-
- return httpRequest;
-
+ setupRequestListeners: function setupRequestListeners() {
},
- retryableError: function retryableError(error) {
- if (this.expiredCredentialsError(error)) return true;
- if (this.throttledError(error)) return true;
- if (error.statusCode >= 500) return true;
- return false;
+ successfulResponse: function successfulResponse(resp) {
+ return resp.httpResponse.statusCode < 300;
},
- // How many times a failed request should be retried before giving up.
- // the defaultRetryCount can be overriden by client classes.
+ /**
+ * How many times a failed request should be retried before giving up.
+ * the defaultRetryCount can be overriden by client classes.
+ */
numRetries: function numRetries() {
if (this.config.maxRetries !== undefined) {
return this.config.maxRetries;
@@ -115,6 +88,18 @@ AWS.Client = inherit({
return delays;
},
+ retryableError: function retryableError(error) {
+ if (this.networkingError(error)) return true;
+ if (this.expiredCredentialsError(error)) return true;
+ if (this.throttledError(error)) return true;
+ if (error.statusCode >= 500) return true;
+ return false;
+ },
+
+ networkingError: function networkingError(error) {
+ return error.code == 'NetworkingError';
+ },
+
expiredCredentialsError: function expiredCredentialsError(error) {
// TODO : this only handles *one* of the expired credential codes
return (error.code === 'ExpiredTokenException');
diff --git a/lib/core.js b/lib/core.js
index ba4af8c21d..2d650ad1fb 100644
--- a/lib/core.js
+++ b/lib/core.js
@@ -36,6 +36,11 @@ AWS.util.update(AWS, {
}
}),
+ /**
+ * @api private
+ */
+ ServiceInterface: {},
+
/**
* @api private
*/
@@ -45,6 +50,8 @@ AWS.util.update(AWS, {
require('./config');
require('./http');
-require('./promise');
+require('./event_emitter');
+require('./event_listeners');
+require('./request');
require('./client');
require('./service');
diff --git a/lib/event_emitter.js b/lib/event_emitter.js
new file mode 100644
index 0000000000..492a43136a
--- /dev/null
+++ b/lib/event_emitter.js
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
+ * may not use this file except in compliance with the License. A copy of
+ * the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+var AWS = require('./core');
+var EventEmitter = require('events').EventEmitter;
+
+AWS.EventEmitter = AWS.util.inherit(EventEmitter, {
+ constructor: function AWSEventEmitter() {
+ EventEmitter.call(this);
+ },
+
+ addListeners: function addListeners(listeners) {
+ var self = this;
+
+ // extract listeners if parameter is an EventEmitter object
+ if (listeners._events) listeners = listeners._events;
+
+ AWS.util.each(listeners, function(event, callbacks) {
+ if (callbacks instanceof Function) callbacks = [callbacks];
+ AWS.util.arrayEach(callbacks, function(callback) {
+ self.on(event, callback);
+ });
+ });
+ },
+
+ addNamedListener: function addNamedListener(name, eventName, callback) {
+ this[name] = callback;
+ this.addListener(eventName, callback);
+ return this;
+ },
+
+ addNamedListeners: function addNamedListeners(callback) {
+ var self = this;
+ callback(function() {
+ self.addNamedListener.apply(self, arguments);
+ });
+ return this;
+ }
+});
diff --git a/lib/event_listeners.js b/lib/event_listeners.js
new file mode 100644
index 0000000000..6d7c3c8f88
--- /dev/null
+++ b/lib/event_listeners.js
@@ -0,0 +1,179 @@
+/**
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
+ * may not use this file except in compliance with the License. A copy of
+ * the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+var AWS = require('./core');
+require('./event_emitter');
+require('./service_interface/json');
+require('./service_interface/query');
+require('./service_interface/rest');
+require('./service_interface/rest_xml');
+
+/**
+ * @api private
+ */
+AWS.EventListeners = {
+ Core: new AWS.EventEmitter().addNamedListeners(function(add) {
+ add('VALIDATE_CREDENTIALS', 'validate', function VALIDATE_CREDENTIALS() {
+ if (!this.client.config.credentials.accessKeyId ||
+ !this.client.config.credentials.secretAccessKey) {
+ throw AWS.util.error(new Error(),
+ {code: 'SigningError', message: 'Missing credentials in config'});
+ }
+ });
+
+ add('VALIDATE_REGION', 'validate', function VALIDATE_REGION() {
+ if (!this.client.config.region) {
+ throw AWS.util.error(new Error(),
+ {code: 'SigningError', message: 'Missing region in config'});
+ }
+ });
+
+ add('SIGN', 'sign', function SIGN() {
+ var date = AWS.util.date.getDate();
+ var credentials = AWS.util.copy(this.client.config.credentials);
+ var SignerClass = this.client.signatureVersion;
+ var signer = new SignerClass(this.httpRequest, this.client.serviceName);
+
+ // clear old authorization headers
+ delete this.httpRequest.headers['Authorization'];
+ delete this.httpRequest.headers['Date'];
+ delete this.httpRequest.headers['X-Amz-Date'];
+
+ // add new authorization
+ signer.addAuthorization(credentials, date);
+ });
+
+ add('SETUP_ERROR', 'extractError', function SETUP_ERROR(resp) {
+ if (this.client.successfulResponse(resp, this)) {
+ // throwing null will stop the error extraction chain
+ // but will not set an error for data extraction
+ throw null;
+ }
+
+ resp.error = AWS.util.error(new Error(),
+ {code: 'UnknownError', message: 'An unknown error occurred.'});
+ resp.data = null;
+ });
+
+ add('SETUP_DATA', 'extractData', function SETUP_DATA(resp) {
+ resp.data = {};
+ resp.error = null;
+ });
+ }),
+
+ Http: new AWS.EventEmitter().addNamedListeners(function(add) {
+ add('SEND', 'send', function SEND(resp) {
+ AWS.HttpClient.getInstance().handleRequest(this, resp);
+ });
+
+ add('HTTP_HEADERS', 'httpHeaders',
+ function HTTP_HEADERS(statusCode, headers, resp) {
+ resp.httpResponse.statusCode = statusCode;
+ resp.httpResponse.headers = headers;
+ resp.httpResponse.body = '';
+ });
+
+ add('HTTP_DATA', 'httpData', function HTTP_DONE(chunk, resp) {
+ resp.httpResponse.body += chunk;
+ });
+
+ add('HTTP_DONE', 'httpDone', function HTTP_DONE(resp) {
+ this.completeRequest(resp);
+ });
+
+ add('HTTP_ERROR', 'httpError', function HTTP_ERROR(error, resp) {
+ resp.error = error;
+ this.completeRequest(resp);
+ });
+
+ add('FINALIZE_ERROR', 'retry', function FINALIZE_ERROR(resp) {
+ resp.error.statusCode = resp.httpResponse.statusCode;
+ if (resp.error.retryable === undefined) {
+ resp.error.retryable = this.client.retryableError(resp.error, this);
+ }
+ });
+
+ add('REDIRECT', 'retry', function REDIRECT(resp) {
+ if (resp.error && resp.error.statusCode == 307) {
+ this.httpRequest.endpoint =
+ new AWS.Endpoint(resp.httpResponse.headers['location']);
+ resp.error.retryable = true;
+ }
+ });
+
+ add('RETRY_CHECK', 'retry', function RETRY_CHECK(resp) {
+ if (resp.error) {
+ if (!resp.error.retryable)
+ throw resp.error;
+ if (resp.retryCount >= this.client.numRetries())
+ throw resp.error;
+
+ resp.retryCount++;
+ }
+ });
+
+ add('RETRY_SIGN', 'retry', function RETRY_SIGN(resp) {
+ this.emitEvents(resp, 'sign');
+ });
+
+ add('RETRY_DELAY_SEND', 'retry', function RETRY_DELAY_SEND(resp) {
+ var delay = 0;
+ if (resp.error) {
+ delay = this.client.retryDelays()[resp.retryCount-1] || 0;
+ }
+
+ resp.error = null;
+ resp.data = null;
+
+ setTimeout(function() { resp.request.emitEvents(resp, 'send'); }, delay);
+ });
+
+ // Allow streaming by disabling HTTP_DATA callback if
+ // any httpData event is added
+ add('DISABLE_HTTP_DATA', 'newListener', function DISABLE_HTTP_DATA(event) {
+ if (event === 'httpData') {
+ this.removeListener('httpData', AWS.EventListeners.Http.HTTP_DATA);
+ }
+ });
+ }),
+
+ Json: new AWS.EventEmitter().addNamedListeners(function(add) {
+ var svc = AWS.ServiceInterface.Json;
+ add('BUILD', 'build', svc.buildRequest);
+ add('EXTRACT_DATA', 'extractData', svc.extractData);
+ add('EXTRACT_ERROR', 'extractError', svc.extractError);
+ }),
+
+ Rest: new AWS.EventEmitter().addNamedListeners(function(add) {
+ var svc = AWS.ServiceInterface.Rest;
+ add('BUILD', 'build', svc.buildRequest);
+ add('EXTRACT_DATA', 'extractData', svc.extractData);
+ add('EXTRACT_ERROR', 'extractError', svc.extractError);
+ }),
+
+ RestXml: new AWS.EventEmitter().addNamedListeners(function(add) {
+ var svc = AWS.ServiceInterface.RestXml;
+ add('BUILD', 'build', svc.buildRequest);
+ add('EXTRACT_DATA', 'extractData', svc.extractData);
+ add('EXTRACT_ERROR', 'extractError', svc.extractError);
+ }),
+
+ Query: new AWS.EventEmitter().addNamedListeners(function(add) {
+ var svc = AWS.ServiceInterface.Query;
+ add('BUILD', 'build', svc.buildRequest);
+ add('EXTRACT_DATA', 'extractData', svc.extractData);
+ add('EXTRACT_ERROR', 'extractError', svc.extractError);
+ })
+};
diff --git a/lib/http.js b/lib/http.js
index 3b598a4942..d9634d7284 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -97,14 +97,14 @@ AWS.HttpRequest = inherit({
/**
* @api private
*/
- constructor: function HttpRequest() {
+ constructor: function HttpRequest(endpoint, region) {
this.method = 'POST';
this.path = '/';
this.headers = {};
this.headers['User-Agent'] = AWS.util.userAgent();
- this.body = undefined;
- this.endpoint = undefined;
- this.region = undefined;
+ this.body = '';
+ this.endpoint = AWS.util.copy(endpoint);
+ this.region = region;
},
/**
@@ -142,140 +142,9 @@ AWS.HttpResponse = inherit({
* @api private
*/
constructor: function HttpResponse() {
- this.statusCode = null;
+ this.statusCode = undefined;
this.headers = {};
- this.body = null;
- }
-});
-
-/**
- * @api private
- */
-AWS.RequestHandler = inherit({
-
- constructor: function RequestHandler(awsRequest) {
- this.awsRequest = awsRequest;
- this.awsResponse = awsRequest.awsResponse;
- this.client = awsRequest.client;
- this.operation = awsRequest.operation;
- this.params = awsRequest.params;
- },
-
- makeRequest: function makeRequest() {
- if (!this.client.config.credentials.accessKeyId ||
- !this.client.config.credentials.secretAccessKey) {
- return this.handleError(AWS.util.error(new Error(), {
- code: 'SigningError', message: 'Missing credentials in config'
- }));
- }
- else if (!this.client.config.region) {
- return this.handleError(AWS.util.error(new Error(), {
- code: 'SigningError', message: 'Missing region in config'
- }));
- }
-
- var httpRequest = this.client.buildRequest(this.operation, this.params);
- httpRequest.sign();
- this.sendRequest(httpRequest);
- },
-
- sendRequest: function sendRequest(httpRequest) {
-
- var httpResponse = new AWS.HttpResponse();
-
- this.awsResponse.httpResponse = httpResponse;
- this.awsResponse.httpRequest = httpRequest;
-
- var self = this;
- AWS.HttpClient.getInstance().handleRequest(httpRequest, {
-
- onHeaders: function onHeaders(statusCode, headers) {
- httpResponse.statusCode = statusCode;
- httpResponse.headers = headers;
- },
-
- onData: function onData(data) {
- if (httpResponse.body === null) {
- httpResponse.body = data;
- } else {
- httpResponse.body += data;
- }
- self.handleHttpData(httpResponse);
- },
-
- onEnd: function onEnd() {
-
- if (httpResponse.body) {
- httpResponse.body = httpResponse.body.toString();
- }
-
- if (httpResponse.statusCode == 307) {
- self.redirect(httpRequest, httpResponse);
- } else {
- self.handleHttpResponse(httpResponse);
- }
-
- },
-
- onError: function onError(error) {
- self.retryRequest(error);
- }
-
- });
-
- },
-
- handleHttpData: function handleHttpData(httpResponse) {
- if (this.awsRequest.callbacks.data.length === 0) return;
- this.awsRequest.notifyData(httpResponse.body);
- httpResponse.body = null;
- },
-
- // Called when the http client returns a response. Successfull http requests
- // may still contain an error (e.g. 400, 500, etc)
- redirect: function redirect(httpRequest, httpResponse) {
- /*jshint sub:true */
- httpRequest.endpoint = new AWS.Endpoint(httpResponse.headers['location']);
- this.sendRequest(httpRequest);
- },
-
- handleHttpResponse: function handleHttpResponse(httpResponse) {
- var self = this;
- this.client.parseResponse(httpResponse, this.operation, function (error, data) {
- if (error)
- self.handleError(error);
- else
- self.awsRequest.notifyDone(data);
- });
- },
-
- handleError: function handleError(error) {
- if (error.retryable) {
- this.retryRequest(error);
- } else {
- this.awsRequest.notifyFail(error);
- }
- },
-
- retryRequest: function retryRequest(error) {
-
- var delays = this.client.retryDelays();
- var delay = delays[this.awsResponse.retryCount];
-
- this.awsResponse.retryCount += 1;
-
- if (delay !== undefined) {
-
- var self = this;
- setTimeout(function delayRetry() {
- self.makeRequest();
- }, delay);
-
- } else {
-
- this.awsRequest.notifyFail(error); // retried too many times
-
- }
+ this.body = undefined;
}
});
@@ -286,15 +155,15 @@ AWS.NodeHttpClient = inherit({
constructor: function NodeHttpClient() {},
- handleRequest: function handleRequest(request, callbacks) {
+ handleRequest: function handleRequest(request, response) {
var options = {
- host: request.endpoint.hostname,
- port: request.endpoint.port,
- method: request.method,
- headers: request.headers,
- path: request.path
+ host: request.httpRequest.endpoint.hostname,
+ port: request.httpRequest.endpoint.port,
+ method: request.httpRequest.method,
+ headers: request.httpRequest.headers,
+ path: request.httpRequest.path
};
- var useSSL = request.endpoint.protocol === 'https:';
+ var useSSL = request.httpRequest.endpoint.protocol === 'https:';
var client = useSSL ? require('https') : require('http');
if (useSSL) {
@@ -303,21 +172,34 @@ AWS.NodeHttpClient = inherit({
options.agent = new client.Agent(options);
}
- var req = client.request(options, function onResponse(resp) {
- callbacks.onHeaders(resp.statusCode, resp.headers);
- resp.on('data', callbacks.onData);
- resp.on('end', callbacks.onEnd);
- });
+ var req = this.setupEvents(client, options, request, response);
+ if (request.httpRequest.body) {
+ req.write(request.httpRequest.body);
+ }
+ req.end();
+ },
- if (request.body) req.write(request.body);
+ setupEvents: function setupEvents(client, options, request, response) {
+ var req = client.request(options, function onResponse(httpResponse) {
+ request.emit('httpHeaders', httpResponse.statusCode,
+ httpResponse.headers, response, request);
- req.end();
- req.on('error', function (e) {
- callbacks.onError(AWS.util.error(
- new Error(e.message), {code: 'NetworkingError'}));
+ httpResponse.on('data', function onData(data) {
+ request.emit('httpData', data, response, request);
+ });
+
+ httpResponse.on('end', function onEnd() {
+ request.emitEvents(response, 'httpDone');
+ });
});
- }
+ req.on('error', function (err) {
+ request.emit('httpError', AWS.util.error(err,
+ {code: 'NetworkingError', retryable: true}));
+ });
+
+ return req;
+ }
});
/**
diff --git a/lib/promise.js b/lib/promise.js
deleted file mode 100644
index 9c9b5e43c6..0000000000
--- a/lib/promise.js
+++ /dev/null
@@ -1,422 +0,0 @@
-/**
- * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You
- * may not use this file except in compliance with the License. A copy of
- * the License is located at
- *
- * http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
- * ANY KIND, either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- */
-
-var AWS = require('./core');
-var inherit = AWS.util.inherit;
-
-/**
- * == Asynchronous Requests
- *
- * All requests made through the SDK are asynchronous and use a
- * callback interface. Each service method that kicks off a request
- * returns an +AWS.AWSRequest+ object that you can use to register
- * callbacks.
- *
- * For example, the following service method returns the request
- * object as "request", which can be used to register callbacks:
- *
- * // request is an AWS.AWSRequest object
- * var request = ec2.client.describeInstances();
- *
- * // register callbacks on request to retrieve response data
- * request.done(function(response) {
- * console.log(response.data);
- * });
- *
- * When a request is ready to be sent, the {send} method should
- * be called:
- *
- * request.send();
- *
- * == Multiple Callbacks and Chaining
- *
- * You can register multiple callbacks on any request object. The
- * callbacks can be registered for different events, or all for the
- * same event. In addition, you can chain callback registration, for
- * example:
- *
- * request.
- * done(function(response) {
- * console.log("Success!");
- * }).
- * fail(function(response) {
- * console.log("Error!");
- * }).
- * always(function(response) {
- * console.log("Always!");
- * }).
- * send();
- *
- * The above example will print either "Success! Always!", or "Error! Always!",
- * depending on whether the request succeeded or not.
- *
- * == Binding Custom Context Data on a Callback
- *
- * By default, the +this+ context of a callback function registered on an
- * event will be the {AWS.AWSResponse} object returned from the service.
- * In some cases, it may be necessary to pass extra custom context to these
- * functions; in these cases, you can bind a custom value to be used as the
- * +this+ context object when the callbacks are executed. To do so, pass
- * the +bind+ option to the asynchronous registration method:
- *
- * var myContext = new Object();
- * request.always(function(response) {
- * console.log(this === myContext);
- * }, {bind: myContext}).send();
- *
- * The above callback will print +true+ when the callback function is executed.
- *
- * @see AWS.AWSResponse
- */
-AWS.AWSRequest = inherit({
-
- /**
- * @api private
- */
- constructor: function AWSRequest(client, operation, params) {
- this.client = client;
- this.operation = operation;
- this.params = params;
- this.awsResponse = new AWS.AWSResponse(this);
- this.state = null;
- this.callbacks = { data: [], done: [], fail: [], always: [] };
- },
-
- /**
- * @!group Sending a Request
- */
-
- /**
- * Initiates sending of the given request object.
- *
- * @example Sending a request
- * request = s3.client.putObject({Bucket: 'bucket', Key: 'key'});
- * request.done(function(resp) { ... }); // register a callback
- * request.send();
- */
- send: function send() {
- new AWS.RequestHandler(this).makeRequest();
- },
-
- /**
- * @!group Registering Callbacks
- */
-
- /**
- * This event is used to stream response data from the
- * service packet-by-packet. This event is mostly used for large responses,
- * when it is inefficient (or impossible) to load the entire response into
- * memory.
- *
- * === Example: Registering a +data+ callback
- *
- * s3.client.getObject({Bucket: b, Key: k}).data(function(resp) {
- * console.log(resp.data);
- * }).send();
- *
- * Prints:
- *
- *
- *
- * ...
- *
- * @note If you register a +data+ callback,
- * +response.data+ will not contain serialized output
- * for the entire request. Instead, it will be your responsibility
- * to stream the output and de-serialize the result on your own.
- * @callback callback function(response)
- * @param response [AWS.AWSResponse] the response object containing the
- * current packet in the +data+ property.
- * @option options bind [Object] (response object) an object to bind
- * the callback function to. Defaults to the response object.
- * @return [AWS.AWSRequest] The same object, for chaining.
- */
- data: function data(callback, options) {
- if (this.awsResponse.data !== null) {
- this.call(callback, options);
- }
- this.callbacks.data.push([callback, options]);
- return this;
- },
-
- /**
- * This event registers a callback to be called when a successful response
- * from the server is returned. The response contains a
- * {AWS.AWSResponse.data data} field with the serialized response data
- * from the service.
- *
- * === Example: Registering a +done+ callback
- *
- * s3.client.listBuckets().done(function(response) {
- * console.log(response.data);
- * }).send();
- *
- * Prints:
- *
- * { Owner: { ID: '...', DisplayName: '...' },
- * Buckets:
- * [ { Name: 'someBucketName', CreationDate: someCreationDate },
- * { Name: 'otherBucketName', CreationDate: otherCreationDate } ],
- * RequestId: '...' }
- *
- * @option options bind [Object] (response object) an object to bind
- * the callback function to. Defaults to the response object.
- * @callback callback function(response)
- * @param response [AWS.AWSResponse] the response object containing the
- * de-serialized response contents in the +data+ property.
- * @note The +response.error+ property will be +null+ when this callback
- * is called.
- * @return [AWS.AWSRequest] The same object, for chaining.
- */
- done: function done(callback, options) {
- if (this.state === 'done') {
- this.call(callback, options);
- } else if (this.state === null) {
- this.callbacks.done.push([callback, options]);
- }
- return this;
- },
-
- /**
- * This event registers a callback to be called when a failure response
- * from the server is returned, or if a networking error occurs.
- * The response contains a {AWS.AWSResponse.error data} field with the
- * error data from the service.
- *
- * === Example: Registering a +fail+ callback
- *
- * s3.config.credentials.accessKeyId = 'invalid';
- * s3.client.listBuckets().fail(function(response) {
- * console.log(response.error);
- * }).send();
- *
- * Prints:
- *
- * { code: 'Forbidden', message: null }
- *
- * @option options bind [Object] (response object) an object to bind
- * the callback function to. Defaults to the response object.
- * @callback callback function(response)
- * @param response [AWS.AWSResponse] the response object containing the
- * service error details in the +error+ property.
- * @note The +response.data+ property will be +null+ when this callback
- * is called.
- * @return [AWS.AWSRequest] The same object, for chaining.
- */
- fail: function fail(callback, options) {
- if (this.state === 'fail') {
- this.call(callback, options);
- } else if (this.state === null) {
- this.callbacks.fail.push([callback, options]);
- }
- return this;
- },
-
- /**
- * This event registers a callback to be called in any final state of a
- * request, i.e., both {done} and {fail}. Use this callback to handle any
- * request cleanup that must be executed regardless of the success state.
- *
- * Note that if you do intend to use response data inside of this callback,
- * you must check for the presence of +response.data+ or +response.error+
- * before attempting to access either property. For example:
- *
- * request.always(function(response) {
- * if (response.error) {
- * // an error occurred, handle it
- * } else {
- * // we can use response.data here
- * }
- * }).send();
- *
- * @option options bind [Object] (response object) an object to bind
- * the callback function to. Defaults to the response object.
- * @callback callback function(response)
- * @param response [AWS.AWSResponse] the response object containing the
- * de-serialized response contents in the +data+ property or the
- * error information in the +error+ property, depending on the result.
- * @return [AWS.AWSRequest] The same object, for chaining.
- */
- always: function always(callback, options) {
- if (this.state) {
- this.call(callback, options);
- } else {
- this.callbacks.always.push([callback, options]);
- }
- return this;
- },
-
- /**
- * @api private
- */
- notifyData: function notifyData(data) {
- this.awsResponse.data = data;
- this.notify('data', this.callbacks.data);
- },
-
- /**
- * @api private
- */
- notifyDone: function notifyDone(data) {
- this.awsResponse.data = data;
- this.notify('done', this.callbacks.done.concat(this.callbacks.always));
- },
-
- /**
- * @api private
- */
- notifyFail: function notifyFail(error) {
- this.awsResponse.error = error;
- this.notify('fail', this.callbacks.fail.concat(this.callbacks.always));
- },
-
- /**
- * @api private
- */
- notify: function notify(state, callbacks) {
- AWS.util.arrayEach.call(this, callbacks, function iterator(cb) {
- this.call(cb[0], cb[1]);
- });
- this.state = state;
- },
-
- /**
- * @api private
- */
- call: function call(callback, options) {
- var binding = this.awsResponse;
- if (options && options.bind) {
- binding = options.bind;
- }
- callback.call(binding, this.awsResponse);
- }
-
-});
-
-/**
- * This class encapsulates the the response information
- * from a service request operation sent through {AWS.AWSRequest}.
- * The response object has two main properties for getting information
- * back from a request:
- *
- * == The +data+ property
- *
- * The +response.data+ property contains the serialized object data
- * retrieved from the service request. For instance, for an
- * Amazon DynamoDB +listTables+ method call, the response data might
- * look like:
- *
- * > resp.data
- * { TableNames:
- * [ 'table1', 'table2', ... ] }
- *
- * The +data+ property can be null if an error occurs (see below).
- *
- * == The +error+ property
- *
- * In the event of a service error (or transfer error), the
- * +response.error+ property will be filled with the given
- * error data in the form:
- *
- * { code: 'SHORT_UNIQUE_ERROR_CODE',
- * message: 'Some human readable error message' }
- *
- * In the case of an error, the +data+ property will be +null+.
- * Note that if you handle events that can be in a failure state,
- * you should always check whether +response.error+ is set
- * before attempting to access the +response.data+ property.
- *
- * @!attribute data
- * @readonly
- * @group Data Properties
- * @note Inside of a {AWS.AWSRequest.data} event, this
- * property contains a single raw packet instead of the
- * full de-serialized service response.
- * @return [Object] the de-serialized response data
- * from the service.
- *
- * @!attribute error
- * An structure containing information about a service
- * or networking error.
- * @readonly
- * @group Data Properties
- * @note This attribute is only filled if a service or
- * networking error occurs.
- * @return [Object]
- * * code [String] a unique short code representing the
- * error that was emitted.
- * * message [String] a longer human readable error message
- * * retryable [Boolean] whether the error message is
- * retryable.
- *
- * @!attribute client
- * @readonly
- * @group Operation Properties
- * @return [AWS.Client] The low-level service client object
- * that initiated the request.
- *
- * @!attribute operation
- * @readonly
- * @group Operation Properties
- * @return [String] the name of the operation executed on
- * the service.
- *
- * @!attribute params
- * @readonly
- * @group Operation Properties
- * @return [Object] the parameters sent in the request to
- * the service.
- *
- * @!attribute retryCount
- * @readonly
- * @group Operation Properties
- * @return [Integer] the number of retries that have were
- * attempted before the request was completed.
- *
- * @!attribute httpRequest
- * @readonly
- * @group HTTP Properties
- * @return [AWS.HttpRequest] the raw HTTP request object
- * containing request headers and body information
- * sent by the client.
- *
- * @!attribute httpResponse
- * @readonly
- * @group HTTP Properties
- * @return [AWS.HttpResponse] the raw HTTP response object
- * containing the response headers and body information
- * from the server.
- *
- * @see AWS.AWSRequest
- */
-AWS.AWSResponse = inherit({
-
- /**
- * @api private
- */
- constructor: function AWSResponse(request) {
-
- this.request = request;
-
- this.data = null;
- this.error = null;
- this.retryCount = 0;
-
- this.httpRequest = null;
- this.httpResponse = null;
-
- }
-
-});
diff --git a/lib/request.js b/lib/request.js
new file mode 100644
index 0000000000..fa7f00d1e9
--- /dev/null
+++ b/lib/request.js
@@ -0,0 +1,291 @@
+/**
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
+ * may not use this file except in compliance with the License. A copy of
+ * the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+var AWS = require('./core');
+var inherit = AWS.util.inherit;
+
+/**
+ * == Asynchronous Requests
+ *
+ * All requests made through the SDK are asynchronous and use a
+ * callback interface. Each service method that kicks off a request
+ * returns an +AWS.Request+ object that you can use to register
+ * callbacks.
+ *
+ * For example, the following service method returns the request
+ * object as "request", which can be used to register callbacks:
+ *
+ * // request is an AWS.Request object
+ * var request = ec2.client.describeInstances();
+ *
+ * // register callbacks on request to retrieve response data
+ * request.on('success', function(response) {
+ * console.log(response.data);
+ * });
+ *
+ * When a request is ready to be sent, the {send} method should
+ * be called:
+ *
+ * request.send();
+ *
+ * == Multiple Callbacks and Chaining
+ *
+ * You can register multiple callbacks on any request object. The
+ * callbacks can be registered for different events, or all for the
+ * same event. In addition, you can chain callback registration, for
+ * example:
+ *
+ * request.
+ * on('success', function(response) {
+ * console.log("Success!");
+ * }).
+ * on('error', function(response) {
+ * console.log("Error!");
+ * }).
+ * on('complete', function(response) {
+ * console.log("Always!");
+ * }).
+ * send();
+ *
+ * The above example will print either "Success! Always!", or "Error! Always!",
+ * depending on whether the request succeeded or not.
+ *
+ * == Binding Custom Context Data on a Callback
+ *
+ * By default, the +this+ context of a callback function registered on an
+ * event will be the {AWS.Response} object returned from the service.
+ * In some cases, it may be necessary to pass extra custom context to these
+ * functions; in these cases, you can bind a custom value to be used as the
+ * +this+ context object when the callbacks are executed. To do so, pass
+ * the +bind+ option to the asynchronous registration method:
+ *
+ * var myContext = new Object();
+ * request.always(function(response) {
+ * console.log(this === myContext);
+ * }, {bind: myContext}).send();
+ *
+ * The above callback will print +true+ when the callback function is executed.
+ *
+ * @see AWS.Response
+ */
+AWS.Request = inherit({
+
+ /**
+ * @api private
+ */
+ constructor: function Request(client, operation, params) {
+ var endpoint = client.endpoint;
+ var region = client.config.region;
+
+ this.client = client;
+ this.operation = operation;
+ this.params = params || {};
+ this.httpRequest = new AWS.HttpRequest(endpoint, region);
+ },
+
+ /**
+ * @!group Sending a Request
+ */
+
+ /**
+ * @overload send()
+ * Initiates sending of the given request object.
+ *
+ * @example Sending a request
+ * request = s3.client.putObject({Bucket: 'bucket', Key: 'key'});
+ * request.on('complete', function(req, resp) { ... }); // register a callback
+ * request.send();
+ */
+ send: function send(response) {
+ response = response || new AWS.Response(this);
+ this.emitEvents(response, 'validate', 'build', 'sign', 'send');
+ if (response.error) this.completeRequest(response);
+ return response;
+ },
+
+ /**
+ * @api private
+ */
+ completeRequest: function completeRequest(response) {
+ this.emitEvents(response, 'extractError', 'extractData');
+
+ if (response.error) {
+ this.emitEventsAlways(response, 'retry');
+ if (!response.error) return;
+ this.emitEventsAlways(response, 'error');
+ } else {
+ this.emitEvents(response, 'success');
+ }
+ this.emitEventsAlways(response, 'complete');
+ },
+
+ /**
+ * @api private
+ */
+ emitEventsAlways: function emitEventsAlways() {
+ var response = arguments[0];
+ for (var i = 1; i < arguments.length; i++) {
+ var eventName = arguments[i];
+ if (this.listeners(eventName).length > 0) {
+ this.emitEvent(eventName, response);
+ }
+ }
+ },
+
+ /**
+ * @api private
+ */
+ emitEvents: function emitEvents() {
+ var response = arguments[0];
+ if (response.error) return;
+ for (var i = 1; i < arguments.length; i++) {
+ var eventName = arguments[i];
+ if (response.error) return AWS.util.abort;
+ if (this.listeners(eventName).length > 0) {
+ this.emitEvent(eventName, response);
+ }
+ }
+ },
+
+ /**
+ * @api private
+ */
+ emitEvent: function emitEvent(eventName, response) {
+ try {
+ this.emit(eventName, eventName == 'build' ? this : response);
+ } catch (err) {
+ response.error = err;
+ }
+ }
+});
+
+/*jshint forin:false*/
+for (var prop in AWS.EventEmitter.prototype) {
+ var fn = AWS.EventEmitter.prototype[prop];
+ if (fn instanceof Function && prop != 'constructor') {
+ AWS.Request.prototype[prop] = fn;
+ }
+}
+
+/**
+ * This class encapsulates the the response information
+ * from a service request operation sent through {AWS.Request}.
+ * The response object has two main properties for getting information
+ * back from a request:
+ *
+ * == The +data+ property
+ *
+ * The +response.data+ property contains the serialized object data
+ * retrieved from the service request. For instance, for an
+ * Amazon DynamoDB +listTables+ method call, the response data might
+ * look like:
+ *
+ * > resp.data
+ * { TableNames:
+ * [ 'table1', 'table2', ... ] }
+ *
+ * The +data+ property can be null if an error occurs (see below).
+ *
+ * == The +error+ property
+ *
+ * In the event of a service error (or transfer error), the
+ * +response.error+ property will be filled with the given
+ * error data in the form:
+ *
+ * { code: 'SHORT_UNIQUE_ERROR_CODE',
+ * message: 'Some human readable error message' }
+ *
+ * In the case of an error, the +data+ property will be +null+.
+ * Note that if you handle events that can be in a failure state,
+ * you should always check whether +response.error+ is set
+ * before attempting to access the +response.data+ property.
+ *
+ * @!attribute data
+ * @readonly
+ * @group Data Properties
+ * @note Inside of a {AWS.Request.data} event, this
+ * property contains a single raw packet instead of the
+ * full de-serialized service response.
+ * @return [Object] the de-serialized response data
+ * from the service.
+ *
+ * @!attribute error
+ * An structure containing information about a service
+ * or networking error.
+ * @readonly
+ * @group Data Properties
+ * @note This attribute is only filled if a service or
+ * networking error occurs.
+ * @return [Object]
+ * * code [String] a unique short code representing the
+ * error that was emitted.
+ * * message [String] a longer human readable error message
+ * * retryable [Boolean] whether the error message is
+ * retryable.
+ *
+ * @!attribute client
+ * @readonly
+ * @group Operation Properties
+ * @return [AWS.Client] The low-level service client object
+ * that initiated the request.
+ *
+ * @!attribute operation
+ * @readonly
+ * @group Operation Properties
+ * @return [String] the name of the operation executed on
+ * the service.
+ *
+ * @!attribute params
+ * @readonly
+ * @group Operation Properties
+ * @return [Object] the parameters sent in the request to
+ * the service.
+ *
+ * @!attribute retryCount
+ * @readonly
+ * @group Operation Properties
+ * @return [Integer] the number of retries that have were
+ * attempted before the request was completed.
+ *
+ * @!attribute httpRequest
+ * @readonly
+ * @group HTTP Properties
+ * @return [AWS.HttpRequest] the raw HTTP request object
+ * containing request headers and body information
+ * sent by the client.
+ *
+ * @!attribute httpResponse
+ * @readonly
+ * @group HTTP Properties
+ * @return [AWS.HttpResponse] the raw HTTP response object
+ * containing the response headers and body information
+ * from the server.
+ *
+ * @see AWS.Request
+ */
+AWS.Response = inherit({
+
+ /**
+ * @api private
+ */
+ constructor: function Response(request) {
+ this.request = request;
+ this.data = null;
+ this.error = null;
+ this.retryCount = 0;
+ this.httpResponse = new AWS.HttpResponse();
+ }
+
+});
diff --git a/lib/rest_xml_client.js b/lib/rest_xml_client.js
deleted file mode 100644
index 0387e5a0cd..0000000000
--- a/lib/rest_xml_client.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You
- * may not use this file except in compliance with the License. A copy of
- * the License is located at
- *
- * http://aws.amazon.com/apache2.0/
- *
- * or in the "license" file accompanying this file. This file is
- * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
- * ANY KIND, either express or implied. See the License for the specific
- * language governing permissions and limitations under the License.
- */
-
-var AWS = require('./core');
-require('./rest_client');
-require('./xml/builder');
-require('./xml/parser');
-var inherit = AWS.util.inherit;
-
-/**
- * @api private
- */
-AWS.RESTXMLClient = inherit(AWS.RESTClient, {
-
- constructor: function RESTXMLClient(config) {
- AWS.RESTClient.call(this, config);
- },
-
- buildRequest: function buildRequest(method, params) {
-
- var _super = AWS.RESTClient.prototype.buildRequest;
- var req = _super.call(this, method, params);
- this.populateBody(req, this.api.operations[method], params || {});
- return req;
-
- },
-
- populateBody: function populateBody(req, operation, params) {
-
- var input = operation.i || {};
- var xmlWrapper = input.n;
- var rules = input.m || {};
- var body = null;
-
- if (xmlWrapper) {
-
- // filter the params to only those that belong in the body
- var xmlParams = {};
- AWS.util.each(rules, function (name, rule) {
- if (!rule.l && params[name] !== undefined) {
- xmlParams[name] = params[name];
- }
- });
-
- if (!AWS.util.isEmpty(xmlParams)) {
- var builder = new AWS.XML.Builder(xmlWrapper, rules, this.api);
- body = builder.toXML(xmlParams);
- }
-
- } else {
- AWS.util.each.call(this, rules, function (name, rule) {
- if (rule.l == 'body')
- body = params[name];
- });
- }
-
- req.body = body;
- req.headers['Content-Length'] = body ? body.length : 0;
- },
-
- extractData: function extractData(httpResponse, method) {
-
- /*jshint sub:true */
-
- var _super = AWS.RESTClient.prototype.extractData;
- var data = _super.call(this, httpResponse, method);
-
- var rules = this.api.operations[method].o || {};
-
- if (rules['Body'] && rules['Body']['t'] === 'bl') {
- data['Body'] = httpResponse.body || '';
- } else if (httpResponse.body) {
- var parser = new AWS.XML.Parser(rules);
- AWS.util.update(data, parser.parse(httpResponse.body));
- }
-
- // extract request id
- data['RequestId'] = httpResponse.headers['x-amz-request-id'];
-
- return data;
-
- },
-
- extractError: function extractError(httpResponse) {
- var data = new AWS.XML.Parser({}).parse(httpResponse.body);
- if (data.Code) {
- return AWS.util.error(new Error(), {
- code: data.Code,
- message: data.Message
- });
- } else {
- return AWS.util.error(new Error(), {
- code: httpResponse.statusCode,
- message: null
- });
- }
- }
-
-});
diff --git a/lib/json_client.js b/lib/service_interface/json.js
similarity index 64%
rename from lib/json_client.js
rename to lib/service_interface/json.js
index fa49e47a41..ec7d385328 100644
--- a/lib/json_client.js
+++ b/lib/service_interface/json.js
@@ -13,39 +13,24 @@
* language governing permissions and limitations under the License.
*/
-var AWS = require('./core');
-var inherit = AWS.util.inherit;
+var AWS = require('../core');
-/**
- * @api private
- */
-AWS.JSONClient = inherit(AWS.Client, {
-
- constructor: function JSONClient(config) {
- AWS.Client.call(this, config);
- },
+AWS.ServiceInterface.Json = {
+ buildRequest: function buildRequest(req) {
+ var httpRequest = req.httpRequest;
+ var api = req.client.api;
+ var target = api.targetPrefix + api.operations[req.operation].n;
- buildRequest: function buildRequest(operation, params) {
-
- var httpRequest = this.newHttpRequest();
-
- httpRequest.body = JSON.stringify(params || {});
-
- var target = this.api.targetPrefix + this.api.operations[operation].n;
+ httpRequest.body = JSON.stringify(req.params || {});
httpRequest.headers['Content-Type'] = 'application/x-amz-json-1.0';
httpRequest.headers['Content-Length'] = httpRequest.body.length;
httpRequest.headers['X-Amz-Target'] = target;
-
- return httpRequest;
-
- },
-
- extractData: function extractData(httpResponse) {
- return JSON.parse(httpResponse.body || '{}');
},
- extractError: function extractError(httpResponse) {
+ extractError: function extractError(resp) {
var error = {};
+ var httpResponse = resp.httpResponse;
+
if (httpResponse.body) {
var e = JSON.parse(httpResponse.body);
error.code = e.__type.split('#').pop();
@@ -58,7 +43,11 @@ AWS.JSONClient = inherit(AWS.Client, {
error.code = httpResponse.statusCode;
error.message = null;
}
- return AWS.util.error(new Error(), error);
- }
-});
+ resp.error = AWS.util.error(new Error(), error);
+ },
+
+ extractData: function extractData(resp) {
+ resp.data = JSON.parse(resp.httpResponse.body || '{}');
+ }
+};
diff --git a/lib/query_client.js b/lib/service_interface/query.js
similarity index 79%
rename from lib/query_client.js
rename to lib/service_interface/query.js
index fb2a506f5c..a7b0ed1934 100644
--- a/lib/query_client.js
+++ b/lib/service_interface/query.js
@@ -13,65 +13,53 @@
* language governing permissions and limitations under the License.
*/
-var AWS = require('./core');
-require('./xml/parser.js');
+var AWS = require('../core');
var inherit = AWS.util.inherit;
-/**
- * @api private
- */
-AWS.QueryClient = inherit(AWS.Client, {
-
- constructor: function QueryClient(config) {
- AWS.Client.call(this, config);
- },
-
- buildRequest: function buildRequest(method, requestParams) {
-
- var httpRequest = this.newHttpRequest();
+require('../xml/parser');
+AWS.ServiceInterface.Query = {
+ buildRequest: function buildRequest(req) {
+ var operation = req.client.api.operations[req.operation];
+ var httpRequest = req.httpRequest;
httpRequest.headers['Content-Type'] =
'application/x-www-form-urlencoded; charset=utf-8';
-
httpRequest.params = new AWS.QueryParamList();
- httpRequest.params.add('Version', this.api.apiVersion);
- httpRequest.params.add('Action', this.api.operations[method].n);
-
+ httpRequest.params.add('Version', req.client.api.apiVersion);
+ httpRequest.params.add('Action', operation.n);
// convert the request parameters into a list of query params,
// e.g. Deeply.NestedParam.0.Name=value
- var rules = this.api.operations[method].i;
+ var rules = operation.i;
if (rules) rules = rules.m;
var builder = new AWS.QueryParamSerializer(rules);
- builder.serialize(requestParams, function (name, value) {
+ builder.serialize(req.params, function(name, value) {
httpRequest.params.add(name, value);
});
-
- return httpRequest;
-
- },
-
- extractData: function extractData(httpResponse, method) {
- var parser = new AWS.XML.Parser(this.api.operations[method].o);
- return parser.parse(httpResponse.body);
},
- extractError: function extractError(httpResponse) {
- var data = new AWS.XML.Parser({}).parse(httpResponse.body);
+ extractError: function extractError(resp) {
+ var data = new AWS.XML.Parser({}).parse(resp.httpResponse.body);
if (data.Code) {
- return AWS.util.error(new Error(), {
+ resp.error = AWS.util.error(new Error(), {
code: data.Code,
message: data.Message
});
} else {
- return AWS.util.error(new Error(), {
- code: httpResponse.statusCode,
+ resp.error = AWS.util.error(new Error(), {
+ code: resp.httpResponse.statusCode,
message: null
});
}
- }
+ },
-});
+ extractData: function extractData(resp) {
+ var req = resp.request;
+ var operation = req.client.api.operations[req.operation];
+ var parser = new AWS.XML.Parser(operation.o);
+ resp.data = parser.parse(resp.httpResponse.body);
+ }
+};
/**
* @api private
diff --git a/lib/rest_client.js b/lib/service_interface/rest.js
similarity index 63%
rename from lib/rest_client.js
rename to lib/service_interface/rest.js
index 782d516a9d..4777b2703d 100644
--- a/lib/rest_client.js
+++ b/lib/service_interface/rest.js
@@ -13,60 +13,72 @@
* language governing permissions and limitations under the License.
*/
-var AWS = require('./core');
-var inherit = AWS.util.inherit;
+var AWS = require('../core');
-/**
- * @api private
- */
-AWS.RESTClient = inherit(AWS.Client, {
-
- constructor: function RESTClient(config) {
- AWS.Client.call(this, config);
+AWS.ServiceInterface.Rest = {
+ buildRequest: function buildRequest(req) {
+ AWS.ServiceInterface.Rest.populateMethod(req);
+ AWS.ServiceInterface.Rest.populateURI(req);
+ AWS.ServiceInterface.Rest.populateHeaders(req);
},
- buildRequest: function buildRequest(method, params) {
-
- if (!params) params = {};
-
- var operation = this.api.operations[method];
+ extractError: function extractError() {
+ },
- var req = this.newHttpRequest();
+ extractData: function extractData(resp) {
+ var req = resp.request;
+ var data = {};
+ var r = resp.httpResponse;
+ var operation = req.client.api.operations[req.operation];
+ var rules = operation.o || {};
- this.populateMethod(req, operation);
- this.populateURI(req, operation, params);
- this.populateHeaders(req, operation, params);
+ // normalize headers names to lower-cased keys for matching
+ var headers = {};
+ AWS.util.each(r.headers, function (k, v) {
+ headers[k.toLowerCase()] = v;
+ });
- return req;
+ AWS.util.each(rules, function (name, rule) {
+ if (rule.l === 'header') {
+ var header = (rule.n || name).toLowerCase();
+ if (headers[header] !== undefined) {
+ data[name] = headers[header];
+ }
+ }
+ if (rule.l === 'status') {
+ data[name] = parseInt(r.statusCode, 10);
+ }
+ });
+ resp.data = data;
},
- populateMethod: function populateMethod(req, operation) {
- req.method = operation.m;
+ populateMethod: function populateMethod(req) {
+ req.httpRequest.method = req.client.api.operations[req.operation].m;
},
- populateURI: function populateURI(req, operation, params) {
-
+ populateURI: function populateURI(req) {
+ var operation = req.client.api.operations[req.operation];
var uri = operation.u;
var pathPattern = uri.split(/\?/)[0];
-
var rules = (operation.i || {}).m || {};
- AWS.util.each.call(this, rules, function (name, rule) {
-
- if (rule.l == 'uri' && params[name]) {
+ var escapePathParam = req.client.escapePathParam ||
+ AWS.ServiceInterface.Rest.escapePathParam;
+ var escapeQuerystringParam = req.client.escapeQuerystringParam ||
+ AWS.ServiceInterface.Rest.escapeQuerystringParam;
+ AWS.util.each.call(this, rules, function (name, rule) {
+ if (rule.l == 'uri' && req.params[name]) {
// if the value is being inserted into the path portion of the
// URI, then we need to use a different (potentially) escaping
// pattern, this is especially true for S3 path params like Key.
var value = pathPattern.match('{' + name + '}') ?
- this.escapePathParam(params[name]) :
- this.escapeQuerystringParam(params[name]);
+ escapePathParam(req.params[name]) :
+ escapeQuerystringParam(req.params[name]);
uri = uri.replace('{' + name + '}', value);
-
}
-
});
var path = uri.split('?')[0];
@@ -82,8 +94,7 @@ AWS.RESTClient = inherit(AWS.Client, {
uri = path;
}
- req.path = uri;
-
+ req.httpRequest.path = uri;
},
escapePathParam: function escapePathParam(value) {
@@ -94,52 +105,21 @@ AWS.RESTClient = inherit(AWS.Client, {
return AWS.util.uriEscape(String(value));
},
- populateHeaders: function populateHeaders(req, operation, params) {
-
+ populateHeaders: function populateHeaders(req) {
+ var operation = req.client.api.operations[req.operation];
var rules = (operation.i || {}).m || {};
AWS.util.each.call(this, rules, function (name, rule) {
- if (rule.l === 'header' && params[name]) {
+ if (rule.l === 'header' && req.params[name]) {
if (rule.t === 'm') { // header map
- AWS.util.each(params[name], function (key, value) {
- req.headers[rule.n + key] = value;
+ AWS.util.each(req.params[name], function (key, value) {
+ req.httpRequest.headers[rule.n + key] = value;
});
} else {
- req.headers[rule.n] = params[name];
+ req.httpRequest.headers[rule.n] = req.params[name];
}
}
});
- },
-
- extractData: function extractData(httpResponse, method) {
-
- var data = {};
-
- var r = httpResponse;
-
- var rules = this.api.operations[method].o || {};
-
- // normalize headers names to lower-cased keys for matching
- var headers = {};
- AWS.util.each(r.headers, function (k, v) {
- headers[k.toLowerCase()] = v;
- });
-
- AWS.util.each(rules, function (name, rule) {
- if (rule.l === 'header') {
- var header = (rule.n || name).toLowerCase();
- if (headers[header] !== undefined) {
- data[name] = headers[header];
- }
- }
- if (rule.l === 'status') {
- data[name] = parseInt(r.statusCode, 10);
- }
- });
-
- return data;
-
}
-
-});
+};
diff --git a/lib/service_interface/rest_xml.js b/lib/service_interface/rest_xml.js
new file mode 100644
index 0000000000..8c558a0558
--- /dev/null
+++ b/lib/service_interface/rest_xml.js
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
+ * may not use this file except in compliance with the License. A copy of
+ * the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+var AWS = require('../core');
+require('../xml/builder');
+require('./rest');
+
+AWS.ServiceInterface.RestXml = {
+ buildRequest: function buildRequest(req) {
+ AWS.ServiceInterface.Rest.buildRequest(req);
+ AWS.ServiceInterface.RestXml.populateBody(req);
+ },
+
+ extractError: function extractError(resp) {
+ AWS.ServiceInterface.Rest.extractError(resp);
+
+ var data = new AWS.XML.Parser({}).parse(resp.httpResponse.body);
+ if (data.Code) {
+ resp.error = AWS.util.error(new Error(), {
+ code: data.Code,
+ message: data.Message
+ });
+ } else {
+ resp.error = AWS.util.error(new Error(), {
+ code: resp.httpResponse.statusCode,
+ message: null
+ });
+ }
+ },
+
+ extractData: function extractData(resp) {
+ AWS.ServiceInterface.Rest.extractData(resp);
+
+ var req = resp.request;
+ var httpResponse = resp.httpResponse;
+ var operation = req.client.api.operations[req.operation];
+ var rules = operation.o || {};
+
+ if (rules['Body'] && rules['Body']['t'] === 'bl') {
+ resp.data['Body'] = httpResponse.body;
+ } else if (httpResponse.body !== '') {
+ var parser = new AWS.XML.Parser(rules);
+ AWS.util.update(resp.data, parser.parse(httpResponse.body));
+ }
+
+ // extract request id
+ resp.data['RequestId'] = httpResponse.headers['x-amz-request-id'];
+ },
+
+ populateBody: function populateBody(req) {
+ var operation = req.client.api.operations[req.operation];
+ var input = operation.i || {};
+ var xmlWrapper = input.n;
+ var rules = input.m || {};
+ var body = null;
+
+ if (xmlWrapper) {
+ // filter the params to only those that belong in the body
+ var xmlParams = {};
+ AWS.util.each(rules, function(name, rule) {
+ if (!rule.l && req.params[name] !== undefined) {
+ xmlParams[name] = req.params[name];
+ }
+ });
+
+ if (!AWS.util.isEmpty(xmlParams)) {
+ var builder = new AWS.XML.Builder(xmlWrapper, rules, req.client.api);
+ body = builder.toXML(xmlParams);
+ }
+
+ } else {
+ AWS.util.each.call(this, rules, function(name, rule) {
+ if (rule.l == 'body')
+ body = req.params[name];
+ });
+ }
+
+ req.httpRequest.body = body;
+ req.httpRequest.headers['Content-Length'] = body ? body.length : 0;
+ }
+};
diff --git a/lib/services/dynamodb.js b/lib/services/dynamodb.js
index 85add55a0b..ca1e12801e 100644
--- a/lib/services/dynamodb.js
+++ b/lib/services/dynamodb.js
@@ -16,7 +16,6 @@
var AWS = require('../core');
var inherit = AWS.util.inherit;
-require('../json_client');
require('../sigv4');
AWS.DynamoDB = inherit({
@@ -27,14 +26,18 @@ AWS.DynamoDB = inherit({
});
-AWS.DynamoDB.Client = inherit(AWS.JSONClient, {
+AWS.DynamoDB.Client = inherit(AWS.Client, {
/**
* @api private
*/
constructor: function DynamoDBClient(options) {
this.serviceName = 'dynamodb';
- AWS.JSONClient.call(this, options);
+ AWS.Client.call(this, options);
+ },
+
+ setupRequestListeners: function setupRequestListeners(request) {
+ request.addListeners(AWS.EventListeners.Json);
},
/**
diff --git a/lib/services/ec2.js b/lib/services/ec2.js
index 98e5f190c1..dd01423de5 100644
--- a/lib/services/ec2.js
+++ b/lib/services/ec2.js
@@ -16,7 +16,6 @@
var AWS = require('../core');
var inherit = AWS.util.inherit;
-require('../query_client');
require('../sigv2');
AWS.EC2 = inherit({
@@ -27,11 +26,17 @@ AWS.EC2 = inherit({
});
-AWS.EC2.Client = inherit(AWS.QueryClient, {
+AWS.EC2.Client = inherit(AWS.Client, {
constructor: function EC2Client(options) {
this.serviceName = 'ec2';
- AWS.QueryClient.call(this, options);
+ AWS.Client.call(this, options);
+ },
+
+ setupRequestListeners: function setupRequestListeners(request) {
+ request.addListeners(AWS.EventListeners.Query);
+ request.removeListener('extractError', AWS.EventListeners.Query.EXTRACT_ERROR);
+ request.addListener('extractError', this.extractError);
},
/**
@@ -42,16 +47,17 @@ AWS.EC2.Client = inherit(AWS.QueryClient, {
/**
* @api private
*/
- extractError: function extractError(httpResponse) {
+ extractError: function extractError(resp) {
// EC2 nests the error code and message deeper than other AWS Query services.
- var data = new AWS.XML.Parser({}).parse(httpResponse.body);
+ var httpResponse = resp.httpResponse;
+ var data = new AWS.XML.Parser({}).parse(httpResponse.body || '');
if (data.Errors)
- return AWS.util.error(new Error(), {
+ resp.error = AWS.util.error(new Error(), {
code: data.Errors.Error.Code,
message: data.Errors.Error.Message
});
else
- return AWS.util.error(new Error(), {
+ resp.error = AWS.util.error(new Error(), {
code: httpResponse.statusCode,
message: null
});
diff --git a/lib/services/s3.js b/lib/services/s3.js
index b1a5fb7781..fdd9950d68 100644
--- a/lib/services/s3.js
+++ b/lib/services/s3.js
@@ -16,7 +16,6 @@
var AWS = require('../core');
var inherit = AWS.util.inherit;
-require('../rest_xml_client');
require('../sigvs3');
AWS.S3 = inherit({
@@ -27,14 +26,14 @@ AWS.S3 = inherit({
});
-AWS.S3.Client = inherit(AWS.RESTXMLClient, {
+AWS.S3.Client = inherit(AWS.Client, {
/**
* @api private
*/
constructor: function S3Client(options) {
this.serviceName = 's3';
- AWS.RESTXMLClient.call(this, options);
+ AWS.Client.call(this, options);
this.setEndpoint((options || {}).endpoint, options);
},
@@ -43,31 +42,39 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
*/
signatureVersion: AWS.SigVS3,
+ setupRequestListeners: function setupRequestListeners(request) {
+ request.addListeners(AWS.EventListeners.RestXml);
+ request.addListener('build', this.populateURI);
+ request.removeListener('validate',
+ AWS.EventListeners.Core.VALIDATE_REGION);
+ request.addListener('extractError', this.extractError);
+ request.addListener('extractData', this.extractData);
+ },
+
/**
* S3 prefers dns-compatible bucket names to be moved from the uri path
* to the hostname as a sub-domain. This is not possible, even for dns-compat
* buckets when using SSL and the bucket name contains a dot ('.'). The
- * ssl wildcart certificate is only 1-level deep.
+ * ssl wildcard certificate is only 1-level deep.
*
* @api private
*/
- populateURI: function populateURI(req, operation, params) {
-
- AWS.RESTClient.prototype.populateURI.call(this, req, operation, params);
+ populateURI: function populateURI(req) {
+ var httpRequest = req.httpRequest;
+ var b = req.params.Bucket;
- var b = params.Bucket;
if (b) {
- if (!this.pathStyleBucketName(b)) {
-
- req.virtualHostedBucket = b; // needed for signing the request
-
- req.path = req.path.replace(new RegExp('^/' + b), '');
- if (req.path[0] !== '/') req.path = '/' + req.path;
- req.endpoint.hostname = b + '.' + req.endpoint.hostname;
-
+ if (!req.client.pathStyleBucketName(b)) {
+ httpRequest.endpoint.hostname = b + '.' +
+ httpRequest.endpoint.hostname;
+
+ httpRequest.virtualHostedBucket = b; // needed for signing the request
+ httpRequest.path = httpRequest.path.replace(new RegExp('^/' + b), '');
+ if (httpRequest.path[0] !== '/') {
+ httpRequest.path = '/' + httpRequest.path;
+ }
}
}
-
},
/**
@@ -78,7 +85,6 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
* @api private
*/
pathStyleBucketName: function pathStyleBucketName(bucketName) {
-
// user can force path style requests via the configuration
if (this.config.s3ForcePathStyle) return true;
@@ -87,7 +93,6 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
} else {
return true; // not dns compatible names must always use path style
}
-
},
/**
@@ -117,8 +122,11 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
* @return [Boolean] whether response contains an error
* @api private
*/
- successfulResponse: function successfulResponse(httpResponse, method) {
- if (method === 'completeMultipartUpload' && httpResponse.body && httpResponse.body.match(''))
+ successfulResponse: function successfulResponse(resp) {
+ var req = resp.request;
+ var httpResponse = resp.httpResponse;
+ if (req.operation === 'completeMultipartUpload' &&
+ httpResponse.body.match(''))
return false;
else
return httpResponse.statusCode < 300;
@@ -128,12 +136,13 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
* @return [Boolean] whether the error can be retried
* @api private
*/
- retryableError: function retryableError(error, method) {
- if (method == 'completeMultipartUpload' && error.statusCode === 200) {
+ retryableError: function retryableError(error, request) {
+ if (request.operation == 'completeMultipartUpload' &&
+ error.statusCode === 200) {
return true;
} else {
var _super = AWS.Client.prototype.retryableError;
- return _super.call(this, error, method);
+ return _super.call(this, error, request);
}
},
@@ -143,24 +152,16 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
*
* @api private
*/
- extractData: function extractData(httpResponse, method) {
-
- var _super = AWS.RESTXMLClient.prototype.extractData;
- var data = _super.call(this, httpResponse, method);
-
- if (method === 'getBucketLocation') {
-
+ extractData: function extractData(resp) {
+ var req = resp.request;
+ if (req.operation === 'getBucketLocation') {
/*jshint regexp:false*/
- var match = httpResponse.body.match(/>(.+)<\/Location/);
+ var match = resp.httpResponse.body.match(/>(.+)<\/Location/);
if (match) {
- /*jshint sub:true */
- delete data['_'];
- data.LocationConstraint = match[1];
+ delete resp.data['_'];
+ resp.data.LocationConstraint = match[1];
}
-
}
-
- return data;
},
/**
@@ -168,30 +169,25 @@ AWS.S3.Client = inherit(AWS.RESTXMLClient, {
*
* @api private
*/
- extractError: function extractError(httpResponse) {
-
+ extractError: function extractError(resp) {
var codes = {
304: 'NotModified',
403: 'Forbidden',
404: 'NotFound'
};
- if (codes[httpResponse.statusCode]) {
-
- return AWS.util.error(new Error(), {
- code: codes[httpResponse.statusCode],
+ if (codes[resp.httpResponse.statusCode]) {
+ resp.error = AWS.util.error(new Error(), {
+ code: codes[resp.httpResponse.statusCode],
message: null
});
-
} else {
+ var data = new AWS.XML.Parser({}).parse(resp.httpResponse.body);
- var data = new AWS.XML.Parser({}).parse(httpResponse.body || '');
-
- return AWS.util.error(new Error(), {
- code: data.Code || httpResponse.statusCode,
+ resp.error = AWS.util.error(new Error(), {
+ code: data.Code || resp.httpResponse.statusCode,
message: data.Message || null
});
-
}
},
diff --git a/lib/services/simpleworkflow.js b/lib/services/simpleworkflow.js
index 011ca6de7a..aa7fda6129 100644
--- a/lib/services/simpleworkflow.js
+++ b/lib/services/simpleworkflow.js
@@ -16,7 +16,6 @@
var AWS = require('../core');
var inherit = AWS.util.inherit;
-require('../json_client');
require('../sigv3');
AWS.SimpleWorkflow = inherit({
@@ -27,14 +26,18 @@ AWS.SimpleWorkflow = inherit({
});
-AWS.SimpleWorkflow.Client = inherit(AWS.JSONClient, {
+AWS.SimpleWorkflow.Client = inherit(AWS.Client, {
/**
* @api private
*/
constructor: function SimpleWorkflowClient(options) {
this.serviceName = 'swf';
- AWS.JSONClient.call(this, options);
+ AWS.Client.call(this, options);
+ },
+
+ setupRequestListeners: function setupRequestListeners(request) {
+ request.addListeners(AWS.EventListeners.Json);
},
/**
diff --git a/lib/sigv3.js b/lib/sigv3.js
index 70f859f350..ff6e795aa2 100644
--- a/lib/sigv3.js
+++ b/lib/sigv3.js
@@ -29,7 +29,6 @@ AWS.SigV3 = inherit(AWS.RequestSigner, {
var datetime = AWS.util.date.rfc822(date);
- /*jshint sub:true */
this.request.headers['Date'] = datetime;
this.request.headers['X-Amz-Date'] = datetime;
this.request.headers['Host'] = this.request.endpoint.hostname;
diff --git a/lib/sigv4.js b/lib/sigv4.js
index 9897f87974..729ee52b55 100644
--- a/lib/sigv4.js
+++ b/lib/sigv4.js
@@ -29,13 +29,11 @@ AWS.SigV4 = inherit(AWS.RequestSigner, {
addAuthorization: function addAuthorization(credentials, date) {
var datetime = AWS.util.date.iso8601(date).replace(/[:\-]|\.\d{3}/g, '');
this.addHeaders(credentials, datetime);
- /*jshint sub:true */
this.request.headers['Authorization'] =
this.authorization(credentials, datetime);
},
addHeaders: function addHeaders(credentials, datetime) {
- /*jshint sub:true */
this.request.headers['Host'] = this.request.endpoint.hostname;
this.request.headers['Date'] = datetime;
this.request.headers['X-Amz-Date'] = datetime;
@@ -79,7 +77,7 @@ AWS.SigV4 = inherit(AWS.RequestSigner, {
parts.push(this.request.search());
parts.push(this.canonicalHeaders() + '\n');
parts.push(this.signedHeaders());
- parts.push(this.hexEncodedHash(this.request.body || ''));
+ parts.push(this.hexEncodedHash(this.request.body));
return parts.join('\n');
},
diff --git a/lib/sigvs3.js b/lib/sigvs3.js
index 9af9117714..8fa86842d9 100644
--- a/lib/sigvs3.js
+++ b/lib/sigvs3.js
@@ -58,8 +58,7 @@ AWS.SigVS3 = inherit(AWS.RequestSigner, {
},
addAuthorization: function addAuthorization(credentials, date) {
-
- this.setDate(date);
+ this.request.headers['Date'] = AWS.util.date.rfc822(date);
if (credentials.sessionToken)
this.request.headers['X-Amz-Security-Token'] = credentials.sessionToken;
@@ -67,14 +66,10 @@ AWS.SigVS3 = inherit(AWS.RequestSigner, {
var signature = this.sign(credentials.secretAccessKey, this.stringToSign());
var auth = 'AWS ' + credentials.accessKeyId + ':' + signature;
- /*jshint sub:true */
this.request.headers['Authorization'] = auth;
-
},
stringToSign: function stringToSign() {
- /*jshint sub:true */
-
var r = this.request;
var parts = [];
@@ -172,18 +167,7 @@ AWS.SigVS3 = inherit(AWS.RequestSigner, {
sign: function sign(secret, string) {
return AWS.util.crypto.hmac(secret, string, 'base64', 'sha1');
- },
-
- setDate: function setDate(date) {
- /*jshint sub:true */
- var r = this.request;
- if (date) {
- r.headers['Date'] = date;
- } else if (!r.headers['X-Amz-Date'] && !r.headers['Date']) {
- r.headers['Date'] = AWS.util.date.rfc822();
- }
}
-
});
module.exports = AWS.SigVS3;
diff --git a/lib/util.js b/lib/util.js
index f9e874618c..afd8be89a2 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -165,6 +165,7 @@ AWS.util = {
},
copy: function copy(object) {
+ if (object === null || object === undefined) return object;
var dupe = {};
/*jshint forin:false */
for (var key in object) {
@@ -184,7 +185,6 @@ AWS.util = {
error: function error(err, options) {
err.message = err.message || null;
- err.retryable = err.retryable || false;
if (typeof options === 'string') {
err.message = options;
@@ -203,6 +203,7 @@ AWS.util = {
var newObject = null;
if (features === undefined) {
features = klass;
+ klass = Object;
newObject = {};
} else {
/*jshint newcap:false camelcase:false */
@@ -210,6 +211,14 @@ AWS.util = {
ctor.prototype = klass.prototype;
newObject = new ctor();
}
+
+ // constructor not supplied, create pass-through ctor
+ if (features.constructor === Object) {
+ features.constructor = function() {
+ klass.apply(this, arguments);
+ };
+ }
+
features.constructor.prototype = newObject;
AWS.util.update(features.constructor.prototype, features);
features.constructor.__super__ = klass;
diff --git a/test/helpers.coffee b/test/helpers.coffee
index e5c8f0b4b1..2fb0c91373 100644
--- a/test/helpers.coffee
+++ b/test/helpers.coffee
@@ -12,12 +12,21 @@
# language governing permissions and limitations under the License.
AWS = require('../lib/aws')
+fs = require('fs')
+configFile = __dirname + '/../configuration'
+
+if fs.existsSync(configFile)
+ AWS.config.loadFromPath(configFile)
+else
+ AWS.config.update credentials:
+ accessKeyId: 'akid'
+ secretAccessKey: 'secret'
integration = (reqBuilder, respCallback) ->
req = reqBuilder()
resp = null
runs ->
- req.always (respObject) -> resp = respObject
+ req.on('complete', (respObject) -> resp = respObject)
req.send()
waitsFor -> resp != null
runs -> respCallback(resp)
@@ -37,14 +46,13 @@ MockClient = AWS.util.inherit AWS.Client,
AWS.Client.call(this, config)
@config.credentials = accessKeyId: 'akid', secretAccessKey: 'secret'
@config.region = 'mock-region'
- buildRequest: ->
- req = this.newHttpRequest()
- req.sign = ->
- req
- extractData: (httpResponse) ->
- return httpResponse.body
- extractError: (httpResponse) ->
- return { code: httpResponse.statusCode, message: null, retryable: false }
+ setupRequestListeners: (request) ->
+ request.on 'extractData', (resp) ->
+ resp.data = resp.httpResponse.body
+ request.on 'extractError', (resp) ->
+ resp.error =
+ code: resp.httpResponse.statusCode
+ message: null
serviceName: 'mockservice'
signatureVersion: require('../lib/sigv4')
@@ -55,15 +63,15 @@ MockService.Client = MockClient
mockHttpResponse = (status, headers, data) ->
spyOn(AWS.HttpClient, 'getInstance')
- if typeof status == 'number'
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(status, headers)
+ AWS.HttpClient.getInstance.andReturn handleRequest: (req, resp) ->
+ if typeof status == 'number'
+ req.emit('httpHeaders', status, headers, resp)
+ str = str instanceof Array ? str : [str]
AWS.util.arrayEach data, (str) ->
- cb.onData(str)
- cb.onEnd()
- else
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onError(status)
+ req.emit('httpData', str, resp)
+ req.emit('httpDone', resp)
+ else
+ req.emit('httpError', status, resp)
module.exports =
AWS: AWS
diff --git a/test/integration/dynamodb.spec.coffee b/test/integration/dynamodb.spec.coffee
index 2e43f6ef21..ffaec4908b 100644
--- a/test/integration/dynamodb.spec.coffee
+++ b/test/integration/dynamodb.spec.coffee
@@ -11,7 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
-helpers = require('./helpers'); AWS = helpers.AWS
+helpers = require('../helpers'); AWS = helpers.AWS
describe 'AWS.DynamoDB', ->
client = new AWS.DynamoDB.Client()
@@ -21,7 +21,7 @@ describe 'AWS.DynamoDB', ->
helpers.integration (-> client.listTables(Limit: 3)), (resp) ->
expect(resp.error).toEqual(null)
expect(JSON.stringify(resp.data)).toMatch(/\{.*"TableNames":.*\}/)
- expect(resp.httpRequest.body).toEqual('{"Limit":3}')
+ expect(resp.request.httpRequest.body).toEqual('{"Limit":3}')
describe 'deleteItem', ->
it 'should fail if TableName not provided', ->
diff --git a/test/integration/ec2.spec.coffee b/test/integration/ec2.spec.coffee
index 9d29531703..4adb9c19a3 100644
--- a/test/integration/ec2.spec.coffee
+++ b/test/integration/ec2.spec.coffee
@@ -11,7 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
-helpers = require('./helpers'); AWS = helpers.AWS
+helpers = require('../helpers'); AWS = helpers.AWS
describe 'AWS.EC2', ->
diff --git a/test/integration/helpers.coffee b/test/integration/helpers.coffee
deleted file mode 100644
index 9cda9cac71..0000000000
--- a/test/integration/helpers.coffee
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-helpers = require('../helpers');
-
-AWS = helpers.AWS
-AWS.config.loadFromPath(__dirname + '/../../configuration');
-
-module.exports = helpers
diff --git a/test/integration/s3.spec.coffee b/test/integration/s3.spec.coffee
index 0fbcb004c9..a3ab27b757 100644
--- a/test/integration/s3.spec.coffee
+++ b/test/integration/s3.spec.coffee
@@ -11,7 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
-helpers = require('./helpers'); AWS = helpers.AWS
+helpers = require('../helpers'); AWS = helpers.AWS
describe 'AWS.S3', ->
diff --git a/test/integration/simpleworkflow.spec.coffee b/test/integration/simpleworkflow.spec.coffee
index 9b3bdab65a..c97ba43911 100644
--- a/test/integration/simpleworkflow.spec.coffee
+++ b/test/integration/simpleworkflow.spec.coffee
@@ -11,7 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
-helpers = require('./helpers'); AWS = helpers.AWS
+helpers = require('../helpers'); AWS = helpers.AWS
describe 'AWS.SimpleWorkflow', ->
client = new AWS.SimpleWorkflow.Client()
@@ -21,7 +21,7 @@ describe 'AWS.SimpleWorkflow', ->
helpers.integration (-> client.listDomains(registrationStatus: "REGISTERED")), (resp) ->
expect(resp.error).toEqual(null)
expect(JSON.stringify(resp.data)).toMatch(/\{"domainInfos":.*\}/)
- expect(resp.httpRequest.body).toEqual('{"registrationStatus":"REGISTERED"}')
+ expect(resp.request.httpRequest.body).toEqual('{"registrationStatus":"REGISTERED"}')
describe 'getWorkflowExecutionHistory', ->
it 'should fail if TableName not provided', ->
diff --git a/test/unit/aws_request.spec.coffee b/test/unit/aws_request.spec.coffee
deleted file mode 100644
index 47e57c8cf0..0000000000
--- a/test/unit/aws_request.spec.coffee
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-helpers = require('../helpers')
-AWS = helpers.AWS
-
-describe 'AWS.AWSRequest', ->
- request = null
- response = null
- beforeEach ->
- request = new AWS.AWSRequest(null, 'operation', {})
- response = request.awsResponse
-
- sharedBehaviour = (cbMethod, notifyMethod, data) ->
-
- it 'can register callback', ->
- spy = jasmine.createSpy(cbMethod + '_register')
- request[cbMethod](spy)
- request[notifyMethod](data)
- expect(spy).toHaveBeenCalled()
-
- it 'will trigger even if registered after notification', ->
- spy = jasmine.createSpy(cbMethod + '_trigger_after_notification')
- request[notifyMethod](data)
- request[cbMethod](spy)
- expect(spy).toHaveBeenCalled()
-
- it 'can register multiple callbacks', ->
- spies = [jasmine.createSpy(cbMethod + '_multiple_cb'),
- jasmine.createSpy(cbMethod + '_multiple_cb')]
- request[notifyMethod](data)
- for index of spies
- request[cbMethod](spies[index])
- expect(spies[index]).toHaveBeenCalled()
-
- it 'can chain callbacks', ->
- spy1 = jasmine.createSpy(cbMethod + '_chain')
- spy2 = jasmine.createSpy(cbMethod + '_chain')
- retVal = request[cbMethod](spy1)[cbMethod](spy2)
- request[notifyMethod](data)
- expect(retVal).toBe(request)
- expect(spy1).toHaveBeenCalled()
- expect(spy2).toHaveBeenCalled()
-
- it 'should be triggered in default binding of response object', ->
- request[cbMethod] ->
- expect(this).toBe(response)
- request[notifyMethod](data)
-
- it 'should be triggered with response object as param', ->
- request[cbMethod] (context) ->
- expect(context).toBe(response)
- request[notifyMethod](data)
-
- it 'should allow overriding of binding', ->
- request[cbMethod]((-> expect(this).toEqual('foo')), bind: 'foo')
- request[notifyMethod](data)
-
- describe 'data', ->
- sharedBehaviour('data', 'notifyData', 'FOO')
-
- describe 'done', ->
- sharedBehaviour('done', 'notifyDone')
-
- describe 'fail', ->
- sharedBehaviour('fail', 'notifyFail')
-
- describe 'always', ->
- describe 'with notifyDone', ->
- sharedBehaviour('always', 'notifyDone')
-
- describe 'with notifyFail', ->
- sharedBehaviour('always', 'notifyFail')
diff --git a/test/unit/client.spec.coffee b/test/unit/client.spec.coffee
index 11308030df..865e999ba5 100644
--- a/test/unit/client.spec.coffee
+++ b/test/unit/client.spec.coffee
@@ -49,44 +49,30 @@ describe 'AWS.Client', ->
it 'it treats params as an optinal parameter', ->
helpers.mockHttpResponse(200, {}, ['FOO', 'BAR'])
client = new MockClient()
- client.buildRequest = (operation, params) ->
- expect(operation).toEqual('operationName')
- expect(params).toEqual({})
- req = this.newHttpRequest()
- req.sign = ->
- req
client.makeRequest 'operationName', (err, data) ->
+ expect(data).toEqual('FOOBAR')
it 'yields data to the callback', ->
helpers.mockHttpResponse(200, {}, ['FOO', 'BAR'])
- err = null; data = null
client = new MockClient()
- req = client.makeRequest 'operation', {}, (e, d) ->
- err = e
- data = d
- expect(err).toEqual(null)
- expect(data).toEqual('FOOBAR')
+ req = client.makeRequest 'operation', (err, data) ->
+ expect(err).toEqual(null)
+ expect(data).toEqual('FOOBAR')
it 'yields service errors to the callback', ->
helpers.mockHttpResponse(500, {}, ['service error'])
- err = null; data = null
client = new MockClient(maxRetries: 0)
- req = client.makeRequest 'operation', {}, (e, d) ->
- err = e
- data = d
- expect(err).toEqual({code:500, message:null, retryable:true, statusCode:500})
- expect(data).toEqual(null)
+ req = client.makeRequest 'operation', {}, (err, data) ->
+ expect(err).toEqual({code:500, message:null, retryable:true, statusCode:500})
+ expect(data).toEqual(null)
it 'yields network errors to the callback', ->
error = { code: 'NetworkingError' }
helpers.mockHttpResponse(error)
- err = null; data = null
client = new MockClient(maxRetries: 0)
- req = client.makeRequest 'operation', {}, (e, d) ->
- err = e
- data = d
- expect(err).toEqual(error)
- expect(data).toEqual(null)
+ req = client.makeRequest 'operation', {}, (err, data) ->
+ expect(err).toEqual(error)
+ expect(data).toEqual(null)
it 'does not send the request if a callback function is omitted', ->
httpClient = AWS.HttpClient.getInstance()
diff --git a/test/unit/event_emitter.spec.coffee b/test/unit/event_emitter.spec.coffee
new file mode 100644
index 0000000000..a9a80e173a
--- /dev/null
+++ b/test/unit/event_emitter.spec.coffee
@@ -0,0 +1,86 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+AWS = require('../../lib/core')
+
+describe 'AWS.EventEmitter', ->
+ beforeEach -> @emitter = new AWS.EventEmitter()
+
+ describe 'addListeners', ->
+ it 'accepts a hash of events and functions', ->
+ triggers = [0, 0, 0]
+ listeners =
+ eventName:
+ ConstantName1: -> triggers[0] = 1
+ ConstantName2: -> triggers[1] = 1
+ otherEventName:
+ ConstantName3: -> triggers[2] = 1
+
+ @emitter.addListeners(listeners)
+ expect(triggers).toEqual([0, 0, 0])
+
+ @emitter.emit('eventName')
+ expect(triggers).toEqual([1, 1, 0])
+
+ @emitter.emit('otherEventName')
+ expect(triggers).toEqual([1, 1, 1])
+
+ it 'accepts an EventEmitter object', ->
+ triggers = [0, 0, 0]
+ listeners = new AWS.EventEmitter()
+ listeners.on 'eventName', -> triggers[0] = 1
+ listeners.on 'eventName', -> triggers[1] = 1
+ listeners.on 'otherEventName', -> triggers[2] = 1
+
+ @emitter.addListeners(listeners)
+ expect(triggers).toEqual([0, 0, 0])
+
+ @emitter.emit('eventName')
+ expect(triggers).toEqual([1, 1, 0])
+
+ @emitter.emit('otherEventName')
+ expect(triggers).toEqual([1, 1, 1])
+
+ describe 'addNamedListener', ->
+ it 'defines a constant with the callback', ->
+ spy = createSpy()
+ @emitter.addNamedListener('CONSTNAME', 'eventName', spy)
+ expect(@emitter.CONSTNAME).toBe(spy)
+
+ # also verify that event is hooked up like normal
+ @emitter.emit('eventName', 'argument')
+ expect(spy).toHaveBeenCalledWith('argument')
+
+ it 'is chainable', ->
+ r = @emitter.addNamedListener('CONSTNAME', 'eventName', ->)
+ expect(r).toBe(@emitter)
+
+ describe 'addNamedListeners', ->
+ it 'is chainable', ->
+ r = @emitter.addNamedListeners(->)
+ expect(r).toBe(@emitter)
+
+ it 'provides an add function in callback to call addNamedListener', ->
+ spy1 = createSpy(); spy2 = createSpy()
+ @emitter.addNamedListeners (add) ->
+ add('CONST1', 'event1', spy1)
+ add('CONST2', 'event2', spy2)
+
+ expect(@emitter.CONST1).toBe(spy1)
+ expect(@emitter.CONST2).toBe(spy2)
+
+ @emitter.emit('event1', 'arg1')
+ @emitter.emit('event2', 'arg2')
+
+ expect(spy1).toHaveBeenCalledWith('arg1')
+ expect(spy2).toHaveBeenCalledWith('arg2')
diff --git a/test/unit/event_listeners.spec.coffee b/test/unit/event_listeners.spec.coffee
new file mode 100644
index 0000000000..35f54acca6
--- /dev/null
+++ b/test/unit/event_listeners.spec.coffee
@@ -0,0 +1,205 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+helpers = require('../helpers')
+AWS = helpers.AWS
+MockClient = helpers.MockClient
+
+describe 'AWS.EventListeners', ->
+
+ oldSetTimeout = setTimeout
+ config = null; client = null; totalWaited = null; delays = []
+ successHandler = null; errorHandler = null; completeHandler = null
+ retryHandler = null
+
+ beforeEach ->
+ # Mock the timer manually (jasmine.Clock does not work in node)
+ `setTimeout = jasmine.createSpy('setTimeout');`
+ setTimeout.andCallFake (callback, delay) ->
+ totalWaited += delay
+ delays.push(delay)
+ callback()
+
+ totalWaited = 0
+ delays = []
+ client = new MockClient(maxRetries: 3)
+ client.config.credentials = AWS.util.copy(client.config.credentials)
+
+ # Helpful handlers
+ successHandler = createSpy('success')
+ errorHandler = createSpy('error')
+ completeHandler = createSpy('complete')
+ retryHandler = createSpy('retry')
+
+ # Safely tear down setTimeout hack
+ afterEach -> `setTimeout = oldSetTimeout`
+
+ makeRequest = (callback) ->
+ request = client.makeRequest('mockMethod', foo: 'bar')
+ request.on('retry', retryHandler)
+ request.on('error', errorHandler)
+ request.on('success', successHandler)
+ request.on('complete', completeHandler)
+ if callback
+ request.on 'complete', (resp) ->
+ callback.call(resp, resp.error, resp.data)
+ request.send()
+ else
+ request
+
+ describe 'validate', ->
+ it 'sends error event if credentials are not set', ->
+ errorHandler = createSpy()
+ request = makeRequest()
+ request.on('error', errorHandler)
+
+ client.config.credentials.accessKeyId = null
+ request.send()
+
+ client.config.credentials.accessKeyId = 'akid'
+ client.config.credentials.secretAccessKey = null
+ request.send()
+
+ expect(errorHandler).toHaveBeenCalled()
+ AWS.util.arrayEach errorHandler.calls, (call) ->
+ expect(call.args[0].error instanceof Error).toBeTruthy()
+ expect(call.args[0].error.code).toEqual('SigningError')
+ expect(call.args[0].error.message).toMatch(/Missing credentials in config/)
+
+ it 'sends error event if region is not set', ->
+ client.config.region = null
+ request = makeRequest(->)
+
+ call = errorHandler.calls[0]
+ expect(errorHandler).toHaveBeenCalled()
+ expect(call.args[0].error instanceof Error).toBeTruthy()
+ expect(call.args[0].error.code).toEqual('SigningError')
+ expect(call.args[0].error.message).toMatch(/Missing region in config/)
+
+ describe 'httpData', ->
+ beforeEach ->
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
+
+ it 'emits httpData event on each chunk', ->
+ calls = []
+
+ # register httpData event
+ request = makeRequest()
+ request.on('httpData', (chunk) -> calls.push(chunk))
+ request.send()
+
+ expect(calls).toEqual(['FOO', 'BAR', 'BAZ', 'QUX'])
+
+ it 'clears default httpData event if another is added (allow streaming)', ->
+ request = makeRequest()
+ request.on('httpData', ->)
+ response = request.send()
+
+ expect(response.httpResponse.body).toEqual('')
+
+ describe 'retry', ->
+ it 'retries a request with a set maximum retries', ->
+ sendHandler = createSpy('send')
+ client.config.maxRetries = 10
+
+ # fail every request with a fake networking error
+ helpers.mockHttpResponse
+ code: 'NetworkingError', message: 'Cannot connect'
+
+ request = makeRequest()
+ request.on('send', sendHandler)
+ response = request.send()
+
+ expect(retryHandler).toHaveBeenCalled()
+ expect(errorHandler).toHaveBeenCalled()
+ expect(completeHandler).toHaveBeenCalled()
+ expect(successHandler).not.toHaveBeenCalled()
+ expect(response.retryCount).toEqual(client.config.maxRetries);
+ expect(sendHandler.calls.length).toEqual(client.config.maxRetries + 1)
+
+ it 'retries with falloff', ->
+ helpers.mockHttpResponse
+ code: 'NetworkingError', message: 'Cannot connect'
+ makeRequest(->)
+ expect(delays).toEqual([30, 60, 120])
+
+ it 'retries if status code is >= 500', ->
+ helpers.mockHttpResponse 500, {}, ''
+
+ makeRequest (err) ->
+ expect(err).toEqual
+ code: 500,
+ message: null,
+ statusCode: 500
+ retryable: true
+ expect(@retryCount).
+ toEqual(client.config.maxRetries)
+
+ it 'should not emit error if retried fewer than maxRetries', ->
+ spyOn(AWS.HttpClient, 'getInstance').andReturn handleRequest: (req, resp) ->
+ if resp.retryCount < 2
+ req.emit('httpError', {code: 'NetworkingError', message: "FAIL!"}, resp)
+ else
+ req.emit('httpHeaders', resp.retryCount < 2 ? 500 : 200, {}, resp)
+ req.emit('httpData', 'foo', resp)
+ req.emit('httpDone', resp)
+
+ response = makeRequest(->)
+
+ expect(totalWaited).toEqual(90)
+ expect(response.retryCount).toBeLessThan(client.config.maxRetries)
+ expect(response.data).toEqual('foo')
+ expect(errorHandler).not.toHaveBeenCalled()
+
+ describe 'success', ->
+ it 'emits success on a successful response', ->
+ # fail every request with a fake networking error
+ helpers.mockHttpResponse 200, {}, 'Success!'
+
+ response = makeRequest(->)
+
+ expect(retryHandler).not.toHaveBeenCalled()
+ expect(errorHandler).not.toHaveBeenCalled()
+ expect(completeHandler).toHaveBeenCalled()
+ expect(successHandler).toHaveBeenCalled()
+ expect(response.retryCount).toEqual(0);
+
+ describe 'error', ->
+ it 'emits error if error found and should not be retrying', ->
+ # fail every request with a fake networking error
+ helpers.mockHttpResponse 400, {}, ''
+
+ response = makeRequest(->)
+
+ expect(retryHandler).not.toHaveBeenCalled()
+ expect(errorHandler).toHaveBeenCalled()
+ expect(completeHandler).toHaveBeenCalled()
+ expect(successHandler).not.toHaveBeenCalled()
+ expect(response.retryCount).toEqual(0);
+
+ it 'emits error if an error is set in extractError', ->
+ error = code: 'ParseError', message: 'error message'
+ extractDataHandler = createSpy('extractData')
+
+ helpers.mockHttpResponse 400, {}, ''
+
+ request = makeRequest()
+ request.on('extractData', extractDataHandler)
+ request.on('extractError', (resp) -> resp.error = error)
+ response = request.send()
+
+ expect(response.error).toBe(error)
+ expect(extractDataHandler).not.toHaveBeenCalled()
+ expect(retryHandler).not.toHaveBeenCalled()
+ expect(errorHandler).toHaveBeenCalled()
+ expect(completeHandler).toHaveBeenCalled()
diff --git a/test/unit/http_request.spec.coffee b/test/unit/http_request.spec.coffee
index d377de33e0..846d2eedb6 100644
--- a/test/unit/http_request.spec.coffee
+++ b/test/unit/http_request.spec.coffee
@@ -30,8 +30,8 @@ describe 'AWS.HttpRequest', ->
it 'provides headers with a default user agent', ->
expect(request.headers).toEqual({ 'User-Agent': AWS.util.userAgent() })
- it 'defaults body to undefined', ->
- expect(request.body).toEqual(undefined)
+ it 'defaults body to empty string', ->
+ expect(request.body).toEqual('')
it 'defaults endpoint to undefined', ->
expect(request.endpoint).toEqual(undefined)
diff --git a/test/unit/json_client.spec.coffee b/test/unit/json_client.spec.coffee
deleted file mode 100644
index 5d8281eb35..0000000000
--- a/test/unit/json_client.spec.coffee
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-AWS = require('../../lib/core')
-require('../../lib/json_client')
-
-describe 'AWS.JSONClient', ->
-
- MockJSONClient = AWS.util.inherit AWS.JSONClient,
- constructor: (config) ->
- this.serviceName = 'mockservice'
- AWS.JSONClient.call(this, config)
-
- MockJSONClient.prototype.api =
- targetPrefix: 'prefix-'
- operations:
- operationName:
- n: 'OperationName'
-
- AWS.Client.defineMethods(MockJSONClient)
-
- svc = new MockJSONClient()
-
- it 'defines a method for each api operation', ->
- expect(typeof svc.operationName).toEqual('function')
-
- describe 'buildRequest', ->
-
- req = svc.buildRequest('operationName', {})
-
- it 'should use POST method requests', ->
- expect(req.method).toEqual('POST')
-
- it 'should perform all operations on root (/)', ->
- expect(req.path).toEqual('/')
-
- it 'should set Content-Type header', ->
- expect(req.headers['Content-Type']).toEqual('application/x-amz-json-1.0')
-
- it 'should set X-Amz-Target header', ->
- expect(req.headers['X-Amz-Target']).toEqual('prefix-OperationName')
-
- it 'should set Content-Length to body length', ->
- expect(req.body).toEqual('{}')
- expect(req.headers['Content-Length']).toEqual(2)
-
- it 'should set the body to JSON serialized params', ->
- req = svc.buildRequest('operationName', { foo: 'bar' })
- expect(req.body).toEqual('{"foo":"bar"}')
-
- it 'should preserve numeric types', ->
- req = svc.buildRequest('operationName', { count: 3 })
- expect(req.body).toEqual('{"count":3}')
-
- describe 'parseResponse', ->
-
- parse = (callback) ->
- svc.parseResponse resp, 'operationName', (error,data) ->
- callback.call(this, error, data)
-
- resp = new AWS.HttpResponse()
- resp.headers = {}
-
- describe 'with data', ->
-
- beforeEach ->
- resp.statusCode = 200
-
- it 'JSON parses http response bodies', ->
- resp.body = '{"a":1, "b":"xyz"}'
- parse (error, data) ->
- expect(error).toEqual(null)
- expect(data).toEqual({a:1, b:'xyz'})
-
- it 'returns an empty object when the body is an empty string', ->
- resp.body = ''
- parse (error, data) ->
- expect(error).toEqual(null)
- expect(data).toEqual({})
-
- it 'returns an empty object when the body is null', ->
- resp.body = null
- parse (error, data) ->
- expect(error).toEqual(null)
- expect(data).toEqual({})
-
- describe 'with error', ->
-
- beforeEach ->
- resp.statusCode = 500
-
- it 'removes prefixes from the error code', ->
- resp.body = '{"__type":"com.amazon.coral.service#ErrorCode" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.code).toEqual('ErrorCode')
- expect(data).toEqual(null)
-
- it 'returns the full code when a # is not present', ->
- resp.body = '{"__type":"ErrorCode" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.code).toEqual('ErrorCode')
- expect(data).toEqual(null)
-
- it 'returns the status code when the body is blank', ->
- resp.body = null
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.code).toEqual(500)
- expect(error.message).toEqual(null)
- expect(data).toEqual(null)
-
- it 'returns null for the message when not present', ->
- resp.body = '{"__type":"ErrorCode" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.message).toEqual(null)
- expect(data).toEqual(null)
-
- it 'returns the message when present', ->
- resp.body = '{"__type":"ErrorCode", "message":"Error Message" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.message).toEqual('Error Message')
- expect(data).toEqual(null)
-
- # DynamoDB and SWF return error message properties with different case
- it 'returns the message when the message property is upper-cased', ->
- resp.body = '{"__type":"ErrorCode", "Message":"Error Message" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.message).toEqual('Error Message')
- expect(data).toEqual(null)
-
- it 'returns a special message for RequestEntityToLarge errors', ->
- resp.body = '{"__type":"RequestEntityTooLarge" }'
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.message).toEqual('Request body must be less than 1 MB')
- expect(data).toEqual(null)
-
diff --git a/test/unit/query_client.spec.coffee b/test/unit/query_client.spec.coffee
deleted file mode 100644
index 14fb98b7b1..0000000000
--- a/test/unit/query_client.spec.coffee
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-AWS = require('../../lib/core')
-require('../../lib/query_client')
-
-describe 'AWS.QueryClient', ->
-
- MockQueryClient = AWS.util.inherit AWS.QueryClient,
- constructor: (config) ->
- this.serviceName = 'mockservice'
- AWS.QueryClient.call(this, config)
-
- MockQueryClient.prototype.api =
- apiVersion: '2012-01-01'
- operations:
- operationName:
- n: 'OperationName'
- i: {m:{Input:{m:{}}}}
- o: {Data:{t:'o',m:{Name:{t:'s'},Count:{t:'i'}}}}
-
- AWS.Client.defineMethods(MockQueryClient)
-
- svc = new MockQueryClient()
-
- it 'defines a method for each api operation', ->
- expect(typeof svc.operationName).toEqual('function')
-
- describe 'buildRequest', ->
-
- req = svc.buildRequest('operationName', { Input:'foo+bar: yuck/baz=~' })
-
- it 'should use POST method requests', ->
- expect(req.method).toEqual('POST')
-
- it 'should perform all operations on root (/)', ->
- expect(req.path).toEqual('/')
-
- it 'should set Content-Type header', ->
- expect(req.headers['Content-Type']).
- toEqual('application/x-www-form-urlencoded; charset=utf-8')
-
- it 'should add the api version param', ->
- expect(req.params.toString()).toMatch(/Version=2012-01-01/)
-
- it 'should add the operation name as Action', ->
- expect(req.params.toString()).toMatch(/Action=OperationName/)
-
- it 'should uri encode params properly', ->
- expect(req.params.toString()).toMatch(/foo%2Bbar%3A%20yuck%2Fbaz%3D~/);
-
- describe 'parseResponse', ->
-
- resp = new AWS.HttpResponse()
-
- parse = (callback) ->
- svc.parseResponse resp, 'operationName', (error,data) ->
- callback.call(this, error, data)
-
- describe 'with data', ->
-
- beforeEach ->
- resp.statusCode = 200
- resp.body = """
-
-
- abc
- 123
-
-
- """
-
- it 'parses the response using the operation output rules', ->
- parse (error, data) ->
- expect(error).toEqual(null)
- expect(data).toEqual({Data:{Name:'abc',Count:123}})
-
- describe 'with error', ->
-
- beforeEach ->
- resp.statusCode = 400
- resp.body = """
-
- InvalidArgument
- Provided param is bad
-
- """
-
- it 'extracts the error code', ->
- parse (error, data) ->
- expect(error.code).toEqual('InvalidArgument')
- expect(data).toEqual(null)
-
- it 'extracts the error message', ->
- parse (error, data) ->
- expect(error.message).toEqual('Provided param is bad')
- expect(data).toEqual(null)
-
- it 'returns an empty error when the body is blank', ->
- resp.body = ''
- parse (error, data) ->
- expect(error.code).toEqual(400)
- expect(error.message).toEqual(null)
- expect(data).toEqual(null)
-
diff --git a/test/unit/request_handler.spec.coffee b/test/unit/request_handler.spec.coffee
deleted file mode 100644
index 4cafbc18d8..0000000000
--- a/test/unit/request_handler.spec.coffee
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-helpers = require('../helpers')
-AWS = helpers.AWS
-MockClient = helpers.MockClient
-
-describe 'AWS.RequestHandler', ->
-
- oldSetTimeout = setTimeout
- config = null; client = null; totalWaited = null; delays = []
- response = null; request = null; handler = null
-
- beforeEach ->
- # Mock the timer manually (jasmine.Clock does not work in node)
- `setTimeout = jasmine.createSpy('setTimeout');`
- setTimeout.andCallFake (callback, delay) ->
- totalWaited += delay
- delays.push(delay)
- callback()
-
- totalWaited = 0
- delays = []
- client = new MockClient(maxRetries: 3)
- client.config.credentials = AWS.util.copy(client.config.credentials)
- request = new AWS.AWSRequest(client, 'mockMethod', {foo:'bar'})
- response = request.awsResponse
- handler = new AWS.RequestHandler(request)
-
- # Useful spies
- spyOn(request, 'notifyFail')
- spyOn(request, 'notifyDone')
- spyOn(AWS.HttpClient, 'getInstance')
-
- # Safely tear down setTimeout hack
- afterEach -> `setTimeout = oldSetTimeout`
-
- describe 'makeRequest', ->
- it 'sends fail event if credentials are not set', ->
- client.config.credentials.accessKeyId = null
- handler.makeRequest()
-
- client.config.credentials.accessKeyId = 'akid'
- client.config.credentials.secretAccessKey = null
- handler.makeRequest()
-
- expect(request.notifyFail).toHaveBeenCalled()
- AWS.util.arrayEach request.notifyFail.calls, (call) ->
- expect(call.args[0] instanceof Error).toBeTruthy()
- expect(call.args[0].code).toEqual('SigningError')
- expect(call.args[0].message).toMatch(/Missing credentials in config/)
-
- it 'sends fail event if region is not set', ->
- handler.client.config.region = null
- handler.makeRequest()
-
- call = request.notifyFail.calls[0]
- expect(request.notifyFail).toHaveBeenCalled()
- expect(call.args[0] instanceof Error).toBeTruthy()
- expect(call.args[0].code).toEqual('SigningError')
- expect(call.args[0].message).toMatch(/Missing region in config/)
-
- describe 'handleHttpData', ->
-
- beforeEach ->
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(200, {})
- cb.onData("FOO")
- cb.onData("BAR")
- cb.onData("BAZ")
- cb.onData("QUX")
- cb.onEnd()
-
- it 'notifies data if there are promise callbacks', ->
-
- calls = []
-
- # Add a promise callback
- request.data((resp) -> calls.push(resp.data))
-
- handler.makeRequest()
-
- expect(request.awsResponse.httpResponse.body).toEqual(null)
- expect(calls).toEqual(['FOO', 'BAR', 'BAZ', 'QUX'])
-
- it 'does not notify if there are no callbacks registered', ->
-
- spyOn(request, 'notifyData')
- handler.makeRequest()
- expect(request.notifyData).not.toHaveBeenCalled()
-
- describe 'handleHttpResponse', ->
-
- it 'should retry a request with a set maximum retries', ->
-
- client.config.maxRetries = 10
-
- # fail every request with a fake networking error
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onError(code: 'NetworkingError', message: "FAIL!")
-
- handler.makeRequest()
-
- expect(response.retryCount).toEqual(client.config.maxRetries + 1);
- expect(request.notifyFail).toHaveBeenCalled()
- expect(request.notifyDone).not.toHaveBeenCalled()
-
- it 'should retry with falloff', ->
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onError(code: 'NetworkingError', message: "FAIL!")
-
- handler.makeRequest()
-
- expect(delays).toEqual([30, 60, 120])
-
- it 'should retry if status code is >= 500', ->
-
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(500, {})
- cb.onEnd()
-
- handler.makeRequest()
-
- expect(request.notifyFail).toHaveBeenCalledWith(
- code: 500,
- message: null,
- statusCode: 500
- retryable: true)
-
- expect(request.notifyDone).not.toHaveBeenCalled()
- expect(response.retryCount).toEqual(client.config.maxRetries + 1);
-
- it 'should not call notifyFail if retried fewer than maxRetries', ->
-
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- if response.retryCount < 2
- cb.onError(code: 'NetworkingError', message: "FAIL!")
- else
- cb.onHeaders(response.retryCount < 2 ? 500 : 200, {})
- cb.onData('{"data":"BAR"}')
- cb.onEnd()
-
- handler.makeRequest()
-
- expect(totalWaited).toEqual(90)
- expect(response.retryCount).toBeLessThan(client.config.maxRetries);
-
- it 'notifies done on a successful response', ->
-
- spyOn(handler, 'retryRequest')
-
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(200, {})
- cb.onData("Success!")
- cb.onEnd()
-
- handler.makeRequest()
-
- expect(handler.retryRequest).not.toHaveBeenCalled()
- expect(request.notifyFail).not.toHaveBeenCalled()
- expect(request.notifyDone).toHaveBeenCalledWith("Success!")
-
- it 'should notifyFail if error found and should not be retrying', ->
-
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(400, {})
- cb.onEnd()
-
- handler.makeRequest()
-
- expect(request.notifyFail).toHaveBeenCalled()
- expect(request.notifyDone).not.toHaveBeenCalled()
-
- it 'notifies fail if an error is thrown', ->
-
- # throw by the client while parsing a response
- error = { error: 'ParseError', message: 'error message' }
-
- AWS.HttpClient.getInstance.andReturn handleRequest: (req, cb) ->
- cb.onHeaders(200, {})
- cb.onData("Success!")
- cb.onEnd()
-
- spyOn(client, 'parseResponse').andThrow(error)
- spyOn(handler, 'retryRequest')
-
- try
- handler.makeRequest({})
- catch e
- expect(e).toBe(error)
-
- expect(handler.retryRequest).not.toHaveBeenCalled()
- expect(request.notifyDone).not.toHaveBeenCalled()
diff --git a/test/unit/rest_client.spec.coffee b/test/unit/rest_client.spec.coffee
deleted file mode 100644
index 003b89e17f..0000000000
--- a/test/unit/rest_client.spec.coffee
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-AWS = require('../../lib/core')
-require('../../lib/rest_xml_client')
-
-describe 'AWS.RESTClient', ->
-
- operation = null
-
- MockRESTClient = AWS.util.inherit AWS.RESTClient,
- constructor: (config) ->
- this.serviceName = 'mockservice'
- AWS.RESTClient.call(this, config)
-
- beforeEach ->
-
- MockRESTClient.prototype.api =
- operations:
- sampleOperation:
- m: 'POST' # http method
- u: '/' # uri
- i: null # no params
- o: null # no ouputs
-
- AWS.Client.defineMethods(MockRESTClient)
-
- operation = MockRESTClient.prototype.api.operations.sampleOperation
-
- svc = new MockRESTClient()
-
- it 'defines a method for each api operation', ->
- expect(typeof svc.sampleOperation).toEqual('function')
-
- describe 'buildRequest', ->
-
- buildRequest = (params) ->
- svc.buildRequest('sampleOperation', params)
-
- it 'returns an http request', ->
- req = svc.buildRequest('sampleOperation', {})
- expect(req.constructor).toBe(AWS.HttpRequest)
-
- describe 'method', ->
-
- it 'populates method from the operation', ->
- operation.m = 'GET'
- expect(buildRequest().method).toEqual('GET')
-
- describe 'uri', ->
-
- it 'populates uri from the operation', ->
- operation.u = '/path'
- expect(buildRequest().path).toEqual('/path')
-
- it 'replaces param placeholders', ->
- operation.u = '/Owner/{Id}'
- operation.i = {m:{Id:{l:'uri'}}}
- expect(buildRequest({'Id': 'abc'}).path).toEqual('/Owner/abc')
-
- it 'can replace multiple path placeholders', ->
- operation.u = '/{Id}/{Count}'
- operation.i = {m:{Id:{l:'uri'},Count:{t:'i',l:'uri'}}}
- expect(buildRequest({Id:'abc',Count:123}).path).toEqual('/abc/123')
-
- it 'performs querystring param replacements', ->
- operation.u = '/path?id-param={Id}'
- operation.i = {m:{Id:{l:'uri'}}}
- expect(buildRequest({Id:'abc'}).path).toEqual('/path?id-param=abc')
-
- it 'omits querystring when param is not provided', ->
- operation.u = '/path?id-param={Id}'
- operation.i = {m:{Id:{l:'uri'}}}
- expect(buildRequest().path).toEqual('/path')
-
- it 'accpets multiple query params with uri params', ->
- operation.u = '/{Abc}/{Xyz}?foo={Foo}&bar={Bar}'
- operation.i = {m:{Abc:{l:'uri'},Xyz:{l:'uri'},Foo:{l:'uri'},Bar:{l:'uri'}}}
- params = { Abc:'abc', Xyz:'xyz', Bar:'bar' } # omitted Foo
- expect(buildRequest(params).path).toEqual('/abc/xyz?bar=bar')
-
- it 'uri escapes params in both path and querystring', ->
- operation.u = '/{Path}?query={Query}'
- operation.i = {m:{Path:{l:'uri'},Query:{l:'uri'}}}
- params = { Path:'a b', Query:'a/b' }
- expect(buildRequest(params).path).toEqual('/a%20b?query=a%2Fb')
-
- describe 'headers', ->
-
- it 'populates default headers', ->
- req = new AWS.HttpRequest()
- expect(buildRequest().headers).toEqual(req.headers)
-
- it 'populates the headers with present params', ->
- operation.i = {m:{ACL:{l:'header',n:'x-amz-acl'}}}
- headers = buildRequest(ACL:'public-read').headers
- expect(headers['x-amz-acl']).toEqual('public-read')
-
- it 'works with map types', ->
- operation.i = {m:{Metadata:{t:'m',l:'header',n:'x-amz-meta-'}}}
- params =
- Metadata:
- foo: 'bar'
- abc: 'xyz'
- headers = buildRequest(params).headers
- expect(headers['x-amz-meta-foo']).toEqual('bar')
- expect(headers['x-amz-meta-abc']).toEqual('xyz')
-
- describe 'extractData', ->
-
- extractData = (resp) ->
- svc.extractData(resp, 'sampleOperation')
-
- describe 'headers', ->
-
- it 'extracts header values', ->
- operation.o = {ContentType:{t:'s',l:'header',n:'content-type'}}
- resp = new AWS.HttpResponse()
- resp.headers['content-type'] = 'text/plain'
- expect(extractData(resp).ContentType).toEqual('text/plain')
-
- it 'extracts headers when the rule name is camel-cased', ->
- operation.o = {ContentType:{t:'s',l:'header',n:'Content-Type'}}
- resp = new AWS.HttpResponse()
- resp.headers['content-type'] = 'text/plain'
- expect(extractData(resp).ContentType).toEqual('text/plain')
-
- it 'extracts headers when the header name is camel-cased', ->
- operation.o = {ContentType:{t:'s',l:'header',n:'content-type'}}
- resp = new AWS.HttpResponse()
- resp.headers['Content-Type'] = 'text/plain'
- expect(extractData(resp).ContentType).toEqual('text/plain')
-
- describe 'status code', ->
-
- it 'extracts the http status when instructed to', ->
- operation.o = {Result:{t:'i',l:'status'}}
- resp = new AWS.HttpResponse()
- resp.statusCode = 200
- expect(extractData(resp).Result).toEqual(200)
-
- it 'casts string status codes to integers', ->
- operation.o = {Result:{t:'i',l:'status'}}
- resp = new AWS.HttpResponse()
- resp.statusCode = '202'
- expect(extractData(resp).Result).toEqual(202)
diff --git a/test/unit/rest_xml_client.spec.coffee b/test/unit/rest_xml_client.spec.coffee
deleted file mode 100644
index ad47b36578..0000000000
--- a/test/unit/rest_xml_client.spec.coffee
+++ /dev/null
@@ -1,246 +0,0 @@
-# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You
-# may not use this file except in compliance with the License. A copy of
-# the License is located at
-#
-# http://aws.amazon.com/apache2.0/
-#
-# or in the "license" file accompanying this file. This file is
-# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
-# ANY KIND, either express or implied. See the License for the specific
-# language governing permissions and limitations under the License.
-
-helpers = require('../helpers'); AWS = helpers.AWS
-require('../../lib/rest_xml_client')
-
-describe 'AWS.RESTXMLClient', ->
-
- xmlns = 'http://mockservice.com/xmlns'
-
- operation = null
-
- MockRESTXMLClient = AWS.util.inherit AWS.RESTXMLClient,
- constructor: (config) ->
- this.serviceName = 'mockservice'
- AWS.RESTXMLClient.call(this, config)
-
- beforeEach ->
-
- MockRESTXMLClient.prototype.api =
- xmlNamespace: xmlns
- operations:
- sampleOperation:
- m: 'POST' # http method
- u: '/' # uri
- i: null # no params
- o: null # no ouputs
-
- AWS.Client.defineMethods(MockRESTXMLClient)
-
- operation = MockRESTXMLClient.prototype.api.operations.sampleOperation
-
- svc = new MockRESTXMLClient()
-
- it 'defines a method for each api operation', ->
- expect(typeof svc.sampleOperation).toEqual('function')
-
- describe 'buildRequest', ->
-
- buildRequest = (params) ->
- svc.buildRequest('sampleOperation', params)
-
- describe 'empty bodies', ->
-
- it 'defaults body to null when there are no inputs', ->
- operation.i = null
- expect(buildRequest().body).toEqual(null)
-
- it 'defaults body to null when all inputs are uri or header values', ->
- operation.u = '/{Bucket}'
- operation.i = {m:{Bucket:{l:'uri',r:1},ACL:{n:'x-amz-acl',l:'header'}}}
- params = { Bucket:'abc', ACL:'canned-acl' }
- req = buildRequest(params)
- expect(req.body).toEqual(null)
- expect(req.path).toEqual('/abc')
- expect(req.headers['x-amz-acl']).toEqual('canned-acl')
-
- it 'includes Content-Length header if body is empty', ->
- operation.i = null
- req = buildRequest()
- expect(req.body).toEqual(null)
- expect(req.headers['Content-Length']).toEqual(0)
-
- describe 'string bodies', ->
-
- it 'populates the body with string types directly', ->
- operation.u = '/{Bucket}'
- operation.i = {m:{Bucket:{l:'uri',r:1},Data:{t:'s',l:'body'}}}
- params = { Bucket: 'bucket-name', Data: 'abc' }
- expect(buildRequest(params).body).toEqual('abc')
-
- describe 'xml bodies', ->
-
- it 'populates the body with XML from the params w/out a location', ->
- operation.u = '/{Bucket}?next-marker={Marker}&limit={Limit}'
- operation.i =
- n: 'ComplexRequest', # the root xml element name
- m:
- Bucket: # uri path param
- t: 's'
- l: 'uri'
- r: 1
- Marker: # uri querystring param
- t: 's'
- l: 'uri'
- Limit: # uri querystring integer param
- t: 'i'
- l: 'uri'
- ACL: # header string param
- t: 's'
- l: 'header'
- n: 'x-amz-acl'
- Metadata: # header map param
- t: 'm'
- l: 'header'
- n: 'x-amz-meta-'
- Config: # structure of mixed tpyes
- t: 'o'
- r: 1
- m:
- Abc: {} # string
- Locations: # array of strings
- t: 'a'
- m:
- t: 's'
- n: 'Location'
- Data: # array of structures
- t: 'a'
- m:
- t: 'o'
- m:
- Foo: {}
- Bar: {}
- Enabled: # boolean
- t: 'b'
-
- params = {
- Enabled: true
- ACL: 'canned-acl'
- Config:
- Abc: 'abc'
- Locations: ['a', 'b', 'c']
- Data: [
- { Foo:'foo1', Bar:'bar1' },
- { Foo:'foo2', Bar:'bar2' },
- ]
- Bucket: 'bucket-name'
- Marker: 'marker'
- Limit: 123
- Metadata:
- abc: 'xyz'
- mno: 'hjk'
- }
-
- xml = """
-
-
- abc
-
- a
- b
- c
-
-
-
- foo1
- bar1
-
-
- foo2
- bar2
-
-
-
- true
-
- """
-
- req = buildRequest(params)
- expect(req.method).toEqual('POST')
- expect(req.path).toEqual('/bucket-name?next-marker=marker&limit=123')
- expect(req.headers['x-amz-acl']).toEqual('canned-acl')
- expect(req.headers['x-amz-meta-abc']).toEqual('xyz')
- expect(req.headers['x-amz-meta-mno']).toEqual('hjk')
- helpers.matchXML(req.body, xml)
-
- it 'omits the body xml when body params are not present', ->
- operation.u = '/{Bucket}'
- operation.i = {n:'CreateBucketConfig', m:{Bucket:{l:'uri',r:1},Config:{}}}
- params = { Bucket:'abc' } # omitting Config purposefully
- req = buildRequest(params)
- expect(req.body).toEqual(null)
- expect(req.path).toEqual('/abc')
-
- describe 'parseResponse', ->
-
- resp = null
-
- beforeEach ->
- resp = new AWS.HttpResponse()
-
- parse = (callback) ->
- svc.parseResponse resp, 'sampleOperation', (error,data) ->
- callback.call(this, error, data)
-
- describe 'with data', ->
-
- extractData = (resp) ->
- svc.extractData(resp, 'sampleOperation')
-
- it 'parses the xml body', ->
- operation.o = {Foo:{},Bar:{t:'a',m:{n:'Item'}}}
- resp = new AWS.HttpResponse()
- resp.status = 200
- resp.body = """
-
- foo
-
- a
- b
- c
-
-
- """
- expect(extractData(resp)).toEqual({Foo:'foo', Bar:['a', 'b', 'c']})
-
- describe 'with error', ->
-
- beforeEach ->
- resp.statusCode = 400
- resp.body = """
-
- InvalidArgument
- Provided param is bad
-
- """
-
- it 'extracts the error code', ->
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.code).toEqual('InvalidArgument')
- expect(data).toEqual(null)
-
- it 'extracts the error message', ->
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.message).toEqual('Provided param is bad')
- expect(data).toEqual(null)
-
- it 'returns an empty error when the body is blank', ->
- resp.body = ''
- parse (error, data) ->
- expect(error instanceof Error).toBeTruthy()
- expect(error.code).toEqual(400)
- expect(error.message).toEqual(null)
- expect(data).toEqual(null)
diff --git a/test/unit/service_interface/json.spec.coffee b/test/unit/service_interface/json.spec.coffee
new file mode 100644
index 0000000000..6f373bde3f
--- /dev/null
+++ b/test/unit/service_interface/json.spec.coffee
@@ -0,0 +1,144 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+AWS = require('../../../lib/core')
+require('../../../lib/service_interface/json')
+
+describe 'AWS.ServiceInterface.Json', ->
+
+ MockJSONClient = AWS.util.inherit AWS.Client,
+ serviceName: 'mockservice'
+ api:
+ targetPrefix: 'prefix-'
+ operations:
+ operationName:
+ n: 'OperationName'
+
+ AWS.Client.defineMethods(MockJSONClient)
+
+ request = null
+ response = null
+ svc = eval(@description)
+
+ beforeEach ->
+ client = new MockJSONClient(region: 'region')
+ request = new AWS.Request(client, 'operationName')
+ response = new AWS.Response(request)
+
+ describe 'buildRequest', ->
+ buildRequest = ->
+ svc.buildRequest(request)
+
+ it 'should use POST method requests', ->
+ buildRequest()
+ expect(request.httpRequest.method).toEqual('POST')
+
+ it 'should perform all operations on root (/)', ->
+ buildRequest()
+ expect(request.httpRequest.path).toEqual('/')
+
+ it 'should set Content-Type header', ->
+ buildRequest()
+ expect(request.httpRequest.headers['Content-Type']).
+ toEqual('application/x-amz-json-1.0')
+
+ it 'should set X-Amz-Target header', ->
+ buildRequest()
+ expect(request.httpRequest.headers['X-Amz-Target']).
+ toEqual('prefix-OperationName')
+
+ it 'should set Content-Length to body length', ->
+ buildRequest()
+ expect(request.httpRequest.body).toEqual('{}')
+ expect(request.httpRequest.headers['Content-Length']).toEqual(2)
+
+ it 'should set the body to JSON serialized params', ->
+ request.params = foo: 'bar'
+ buildRequest()
+ expect(request.httpRequest.body).toEqual('{"foo":"bar"}')
+
+ it 'should preserve numeric types', ->
+ request.params = count: 3
+ buildRequest()
+ expect(request.httpRequest.body).toEqual('{"count":3}')
+
+ describe 'extractError', ->
+ extractError = (body) ->
+ response.httpResponse.statusCode = 500
+ response.httpResponse.body = body
+ svc.extractError(response)
+
+ it 'removes prefixes from the error code', ->
+ extractError '{"__type":"com.amazon.coral.service#ErrorCode" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual('ErrorCode')
+ expect(response.data).toEqual(null)
+
+ it 'returns the full code when a # is not present', ->
+ extractError '{"__type":"ErrorCode" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual('ErrorCode')
+ expect(response.data).toEqual(null)
+
+ it 'returns the status code when the body is blank', ->
+ extractError null
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual(500)
+ expect(response.error.message).toEqual(null)
+ expect(response.data).toEqual(null)
+
+ it 'returns null for the message when not present', ->
+ extractError '{"__type":"ErrorCode" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.message).toEqual(null)
+ expect(response.data).toEqual(null)
+
+ it 'returns the message when present', ->
+ extractError '{"__type":"ErrorCode", "message":"Error Message" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.message).toEqual('Error Message')
+ expect(response.data).toEqual(null)
+
+ # DynamoDB and SWF return error message properties with different case
+ it 'returns the message when the message property is upper-cased', ->
+ extractError '{"__type":"ErrorCode", "Message":"Error Message" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.message).toEqual('Error Message')
+ expect(response.data).toEqual(null)
+
+ it 'returns a special message for RequestEntityToLarge errors', ->
+ extractError '{"__type":"RequestEntityTooLarge" }'
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.message).toEqual('Request body must be less than 1 MB')
+ expect(response.data).toEqual(null)
+
+ describe 'extractData', ->
+ extractData = (body) ->
+ response.httpResponse.statusCode = 200
+ response.httpResponse.body = body
+ svc.extractData(response)
+
+ it 'JSON parses http response bodies', ->
+ extractData '{"a":1, "b":"xyz"}'
+ expect(response.error).toEqual(null)
+ expect(response.data).toEqual({a:1, b:'xyz'})
+
+ it 'returns an empty object when the body is an empty string', ->
+ extractData ''
+ expect(response.error).toEqual(null)
+ expect(response.data).toEqual({})
+
+ it 'returns an empty object when the body is null', ->
+ extractData null
+ expect(response.error).toEqual(null)
+ expect(response.data).toEqual({})
diff --git a/test/unit/service_interface/query.spec.coffee b/test/unit/service_interface/query.spec.coffee
new file mode 100644
index 0000000000..b3784b1165
--- /dev/null
+++ b/test/unit/service_interface/query.spec.coffee
@@ -0,0 +1,115 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+AWS = require('../../../lib/core')
+require('../../../lib/service_interface/query')
+
+describe 'AWS.ServiceInterface.Query', ->
+
+ MockQueryClient = AWS.util.inherit AWS.Client,
+ serviceName: 'mockservice'
+ api:
+ apiVersion: '2012-01-01'
+ operations:
+ operationName:
+ n: 'OperationName'
+ i: {m:{Input:{m:{}}}}
+ o: {Data:{t:'o',m:{Name:{t:'s'},Count:{t:'i'}}}}
+
+ AWS.Client.defineMethods(MockQueryClient)
+
+ request = null
+ response = null
+ svc = eval(@description)
+
+ beforeEach ->
+ client = new MockQueryClient({region:'region'})
+ request = new AWS.Request(client, 'operationName')
+ response = new AWS.Response(request)
+
+ describe 'buildRequest', ->
+ buildRequest = ->
+ request.params = Input: 'foo+bar: yuck/baz=~'
+ svc.buildRequest(request)
+
+ it 'should use POST method requests', ->
+ buildRequest()
+ expect(request.httpRequest.method).toEqual('POST')
+
+ it 'should perform all operations on root (/)', ->
+ buildRequest()
+ expect(request.httpRequest.path).toEqual('/')
+
+ it 'should set Content-Type header', ->
+ buildRequest()
+ expect(request.httpRequest.headers['Content-Type']).
+ toEqual('application/x-www-form-urlencoded; charset=utf-8')
+
+ it 'should add the api version param', ->
+ buildRequest()
+ expect(request.httpRequest.params.toString()).
+ toMatch(/Version=2012-01-01/)
+
+ it 'should add the operation name as Action', ->
+ buildRequest()
+ expect(request.httpRequest.params.toString()).
+ toMatch(/Action=OperationName/)
+
+ it 'should uri encode params properly', ->
+ buildRequest()
+ expect(request.httpRequest.params.toString()).
+ toMatch(/foo%2Bbar%3A%20yuck%2Fbaz%3D~/);
+
+ describe 'extractError', ->
+ extractError = (body) ->
+ if body == undefined
+ body = """
+
+ InvalidArgument
+ Provided param is bad
+
+ """
+ response.httpResponse.statusCode = 400
+ response.httpResponse.body = body
+ svc.extractError(response)
+
+ it 'extracts the error code and message', ->
+ extractError()
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual('InvalidArgument')
+ expect(response.error.message).toEqual('Provided param is bad')
+ expect(response.data).toEqual(null)
+
+ it 'returns an empty error when the body is blank', ->
+ extractError('')
+ expect(response.error.code).toEqual(400)
+ expect(response.error.message).toEqual(null)
+ expect(response.data).toEqual(null)
+
+ describe 'extractData', ->
+ extractData = (body) ->
+ response.httpResponse.statusCode = 200
+ response.httpResponse.body = body
+ svc.extractData(response)
+
+ it 'parses the response using the operation output rules', ->
+ extractData """
+
+
+ abc
+ 123
+
+
+ """
+ expect(response.error).toEqual(null)
+ expect(response.data).toEqual({Data:{Name:'abc',Count:123}})
diff --git a/test/unit/query_param_serializer.spec.coffee b/test/unit/service_interface/query_param_serializer.spec.coffee
similarity index 98%
rename from test/unit/query_param_serializer.spec.coffee
rename to test/unit/service_interface/query_param_serializer.spec.coffee
index babfc39389..47238e4ae3 100644
--- a/test/unit/query_param_serializer.spec.coffee
+++ b/test/unit/service_interface/query_param_serializer.spec.coffee
@@ -11,8 +11,8 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
-AWS = require('../../lib/core')
-require('../../lib/query_client')
+AWS = require('../../../lib/core')
+require('../../../lib/service_interface/query')
describe 'AWS.QueryParamSerializer', ->
diff --git a/test/unit/service_interface/rest.spec.coffee b/test/unit/service_interface/rest.spec.coffee
new file mode 100644
index 0000000000..8cae30a335
--- /dev/null
+++ b/test/unit/service_interface/rest.spec.coffee
@@ -0,0 +1,155 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+AWS = require('../../../lib/core')
+require('../../../lib/service_interface/rest')
+
+describe 'AWS.ServiceInterface.Rest', ->
+
+ MockRESTClient = AWS.util.inherit AWS.Client,
+ serviceName: 'mockservice'
+
+ operation = null
+ request = null
+ response = null
+ svc = eval(@description)
+
+ beforeEach ->
+ MockRESTClient.prototype.api =
+ operations:
+ sampleOperation:
+ m: 'POST' # http method
+ u: '/' # uri
+ i: null # no params
+ o: null # no ouputs
+
+ AWS.Client.defineMethods(MockRESTClient)
+
+ operation = MockRESTClient.prototype.api.operations.sampleOperation
+ client = new MockRESTClient(region: 'region')
+ request = new AWS.Request(client, 'sampleOperation')
+ response = new AWS.Response(request)
+
+ describe 'buildRequest', ->
+ buildRequest = (callback) ->
+ if callback
+ callback()
+ svc.buildRequest(request)
+
+ describe 'method', ->
+ it 'populates method from the operation', ->
+ buildRequest ->
+ operation.m = 'GET'
+ expect(request.httpRequest.method).toEqual('GET')
+
+ describe 'uri', ->
+ it 'populates uri from the operation', ->
+ buildRequest ->
+ operation.u = '/path'
+ expect(request.httpRequest.path).toEqual('/path')
+
+ it 'replaces param placeholders', ->
+ buildRequest ->
+ operation.u = '/Owner/{Id}'
+ operation.i = {m:{Id:{l:'uri'}}}
+ request.params = Id: 'abc'
+ expect(request.httpRequest.path).toEqual('/Owner/abc')
+
+ it 'can replace multiple path placeholders', ->
+ buildRequest ->
+ operation.u = '/{Id}/{Count}'
+ operation.i = {m:{Id:{l:'uri'},Count:{t:'i',l:'uri'}}}
+ request.params = Id: 'abc', Count: 123
+ expect(request.httpRequest.path).toEqual('/abc/123')
+
+ it 'performs querystring param replacements', ->
+ buildRequest ->
+ operation.u = '/path?id-param={Id}'
+ operation.i = {m:{Id:{l:'uri'}}}
+ request.params = Id: 'abc'
+ expect(request.httpRequest.path).toEqual('/path?id-param=abc')
+
+ it 'omits querystring when param is not provided', ->
+ buildRequest ->
+ operation.u = '/path?id-param={Id}'
+ operation.i = {m:{Id:{l:'uri'}}}
+ expect(request.httpRequest.path).toEqual('/path')
+
+ it 'accpets multiple query params with uri params', ->
+ buildRequest ->
+ operation.u = '/{Abc}/{Xyz}?foo={Foo}&bar={Bar}'
+ operation.i = {m:{Abc:{l:'uri'},Xyz:{l:'uri'},Foo:{l:'uri'},Bar:{l:'uri'}}}
+ request.params = { Abc:'abc', Xyz:'xyz', Bar:'bar' } # omitted Foo
+ expect(request.httpRequest.path).toEqual('/abc/xyz?bar=bar')
+
+ it 'uri escapes params in both path and querystring', ->
+ buildRequest ->
+ operation.u = '/{Path}?query={Query}'
+ operation.i = {m:{Path:{l:'uri'},Query:{l:'uri'}}}
+ request.params = { Path:'a b', Query:'a/b' }
+ expect(request.httpRequest.path).toEqual('/a%20b?query=a%2Fb')
+
+ describe 'headers', ->
+ it 'populates the headers with present params', ->
+ buildRequest ->
+ operation.i = {m:{ACL:{l:'header',n:'x-amz-acl'}}}
+ request.params = ACL: 'public-read'
+ expect(request.httpRequest.headers['x-amz-acl']).toEqual('public-read')
+
+ it 'works with map types', ->
+ buildRequest ->
+ operation.i = {m:{Metadata:{t:'m',l:'header',n:'x-amz-meta-'}}}
+ request.params =
+ Metadata:
+ foo: 'bar'
+ abc: 'xyz'
+ expect(request.httpRequest.headers['x-amz-meta-foo']).toEqual('bar')
+ expect(request.httpRequest.headers['x-amz-meta-abc']).toEqual('xyz')
+
+ describe 'extractData', ->
+ extractData = (callback) ->
+ if callback
+ callback()
+ svc.extractData(response)
+
+ describe 'headers', ->
+ it 'extracts header values', ->
+ extractData ->
+ operation.o = {ContentType:{t:'s',l:'header',n:'content-type'}}
+ response.httpResponse.headers['content-type'] = 'text/plain'
+ expect(response.data.ContentType).toEqual('text/plain')
+
+ it 'extracts headers when the rule name is camel-cased', ->
+ extractData ->
+ operation.o = {ContentType:{t:'s',l:'header',n:'Content-Type'}}
+ response.httpResponse.headers['content-type'] = 'text/plain'
+ expect(response.data.ContentType).toEqual('text/plain')
+
+ it 'extracts headers when the header name is camel-cased', ->
+ extractData ->
+ operation.o = {ContentType:{t:'s',l:'header',n:'content-type'}}
+ response.httpResponse.headers['Content-Type'] = 'text/plain'
+ expect(response.data.ContentType).toEqual('text/plain')
+
+ describe 'status code', ->
+ it 'extracts the http status when instructed to', ->
+ extractData ->
+ operation.o = {Result:{t:'i',l:'status'}}
+ response.httpResponse.statusCode = 200
+ expect(response.data.Result).toEqual(200)
+
+ it 'casts string status codes to integers', ->
+ extractData ->
+ operation.o = {Result:{t:'i',l:'status'}}
+ response.httpResponse.statusCode = '202'
+ expect(response.data.Result).toEqual(202)
diff --git a/test/unit/service_interface/rest_xml.spec.coffee b/test/unit/service_interface/rest_xml.spec.coffee
new file mode 100644
index 0000000000..dbd31ae275
--- /dev/null
+++ b/test/unit/service_interface/rest_xml.spec.coffee
@@ -0,0 +1,226 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+helpers = require('../../helpers'); AWS = helpers.AWS
+require('../../../lib/service_interface/rest_xml')
+
+describe 'AWS.ServiceInterface.RestXml', ->
+
+ MockRESTXMLClient = AWS.util.inherit AWS.Client,
+ serviceName: 'mockservice'
+
+ xmlns = 'http://mockservice.com/xmlns'
+ operation = null
+ request = null
+ response = null
+ svc = eval(@description)
+
+ beforeEach ->
+ MockRESTXMLClient.prototype.api =
+ xmlNamespace: xmlns
+ operations:
+ sampleOperation:
+ m: 'POST' # http method
+ u: '/' # uri
+ i: null # no params
+ o: null # no ouputs
+
+ AWS.Client.defineMethods(MockRESTXMLClient)
+ operation = MockRESTXMLClient.prototype.api.operations.sampleOperation
+ client = new MockRESTXMLClient(region: 'region')
+ request = new AWS.Request(client, 'sampleOperation')
+ response = new AWS.Response(request)
+
+ describe 'buildRequest', ->
+ buildRequest = (callback) ->
+ if callback
+ callback()
+ svc.buildRequest(request)
+
+ describe 'empty bodies', ->
+ it 'defaults body to null when there are no inputs', ->
+ buildRequest ->
+ operation.i = null
+ expect(request.httpRequest.body).toEqual(null)
+
+ it 'defaults body to null when all inputs are uri or header values', ->
+ buildRequest ->
+ operation.u = '/{Bucket}'
+ operation.i = {m:{Bucket:{l:'uri',r:1},ACL:{n:'x-amz-acl',l:'header'}}}
+ request.params = Bucket: 'abc', ACL: 'canned-acl'
+ expect(request.httpRequest.body).toEqual(null)
+ expect(request.httpRequest.path).toEqual('/abc')
+ expect(request.httpRequest.headers['x-amz-acl']).toEqual('canned-acl')
+
+ it 'includes Content-Length header if body is empty', ->
+ buildRequest ->
+ operation.i = null
+ expect(request.httpRequest.body).toEqual(null)
+ expect(request.httpRequest.headers['Content-Length']).toEqual(0)
+
+ describe 'string bodies', ->
+ it 'populates the body with string types directly', ->
+ buildRequest ->
+ operation.u = '/{Bucket}'
+ operation.i = {m:{Bucket:{l:'uri',r:1},Data:{t:'s',l:'body'}}}
+ request.params = Bucket: 'bucket-name', Data: 'abc'
+ expect(request.httpRequest.body).toEqual('abc')
+
+ describe 'xml bodies', ->
+ it 'populates the body with XML from the params w/out a location', ->
+ buildRequest ->
+ operation.u = '/{Bucket}?next-marker={Marker}&limit={Limit}'
+ operation.i =
+ n: 'ComplexRequest', # the root xml element name
+ m:
+ Bucket: # uri path param
+ t: 's'
+ l: 'uri'
+ r: 1
+ Marker: # uri querystring param
+ t: 's'
+ l: 'uri'
+ Limit: # uri querystring integer param
+ t: 'i'
+ l: 'uri'
+ ACL: # header string param
+ t: 's'
+ l: 'header'
+ n: 'x-amz-acl'
+ Metadata: # header map param
+ t: 'm'
+ l: 'header'
+ n: 'x-amz-meta-'
+ Config: # structure of mixed tpyes
+ t: 'o'
+ r: 1
+ m:
+ Abc: {} # string
+ Locations: # array of strings
+ t: 'a'
+ m:
+ t: 's'
+ n: 'Location'
+ Data: # array of structures
+ t: 'a'
+ m:
+ t: 'o'
+ m:
+ Foo: {}
+ Bar: {}
+ Enabled: # boolean
+ t: 'b'
+
+ request.params =
+ Enabled: true
+ ACL: 'canned-acl'
+ Config:
+ Abc: 'abc'
+ Locations: ['a', 'b', 'c']
+ Data: [
+ { Foo:'foo1', Bar:'bar1' },
+ { Foo:'foo2', Bar:'bar2' },
+ ]
+ Bucket: 'bucket-name'
+ Marker: 'marker'
+ Limit: 123
+ Metadata:
+ abc: 'xyz'
+ mno: 'hjk'
+
+ xml = """
+
+
+ abc
+
+ a
+ b
+ c
+
+
+
+ foo1
+ bar1
+
+
+ foo2
+ bar2
+
+
+
+ true
+
+ """
+
+ expect(request.httpRequest.method).toEqual('POST')
+ expect(request.httpRequest.path).
+ toEqual('/bucket-name?next-marker=marker&limit=123')
+ expect(request.httpRequest.headers['x-amz-acl']).toEqual('canned-acl')
+ expect(request.httpRequest.headers['x-amz-meta-abc']).toEqual('xyz')
+ expect(request.httpRequest.headers['x-amz-meta-mno']).toEqual('hjk')
+ helpers.matchXML(request.httpRequest.body, xml)
+
+ it 'omits the body xml when body params are not present', ->
+ buildRequest ->
+ operation.u = '/{Bucket}'
+ operation.i = {n:'CreateBucketConfig', m:{Bucket:{l:'uri',r:1},Config:{}}}
+ request.params = Bucket:'abc' # omitting Config purposefully
+ expect(request.httpRequest.body).toEqual(null)
+ expect(request.httpRequest.path).toEqual('/abc')
+
+ describe 'extractError', ->
+ extractError = (body) ->
+ if body == undefined
+ body = """
+
+ InvalidArgument
+ Provided param is bad
+
+ """
+ response.httpResponse.statusCode = 400
+ response.httpResponse.body = body
+ svc.extractError(response)
+
+ it 'extracts the error code and message', ->
+ extractError()
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual('InvalidArgument')
+ expect(response.error.message).toEqual('Provided param is bad')
+ expect(response.data).toEqual(null)
+
+ it 'returns an empty error when the body is blank', ->
+ extractError ''
+ expect(response.error instanceof Error).toBeTruthy()
+ expect(response.error.code).toEqual(400)
+ expect(response.error.message).toEqual(null)
+ expect(response.data).toEqual(null)
+
+ describe 'extractData', ->
+ extractData = (body) ->
+ response.httpResponse.statusCode = 200
+ response.httpResponse.body = body
+ svc.extractData(response)
+
+ it 'parses the xml body', ->
+ operation.o = {Foo:{},Bar:{t:'a',m:{n:'Item'}}}
+ extractData """
+
+ foo
+
+ a
+ b
+ c
+
+
+ """
+ expect(response.data).toEqual({Foo:'foo', Bar:['a', 'b', 'c']})
diff --git a/test/unit/services/ec2.spec.coffee b/test/unit/services/ec2.spec.coffee
index 36b63b229e..eeef361786 100644
--- a/test/unit/services/ec2.spec.coffee
+++ b/test/unit/services/ec2.spec.coffee
@@ -12,38 +12,34 @@
# language governing permissions and limitations under the License.
AWS = require('../../../lib/core')
+helpers = require('../../helpers')
require('../../../lib/services/ec2')
describe 'AWS.EC2.Client', ->
- ec2 = new AWS.EC2.Client()
+ ec2 = new AWS.EC2.Client({region: 'us-east-1'})
describe 'parseResponse', ->
-
- resp = null
-
- beforeEach ->
- resp = new AWS.HttpResponse()
-
+ body = ''
parse = (callback) ->
- ec2.parseResponse resp, 'operationName', (error,data) ->
+ helpers.mockHttpResponse 400, {}, body
+ ec2.makeRequest 'describeInstances', (error, data) ->
callback.call(this, error, data)
describe 'with error', ->
-
beforeEach ->
- resp.statusCode = 400
- resp.body = """
-
-
-
- InvalidInstanceID.Malformed
- Invalid id: "i-12345678"
-
-
- ab123mno-6432-dceb-asdf-123mno543123
-
- """
+ body =
+ """
+
+
+
+ InvalidInstanceID.Malformed
+ Invalid id: "i-12345678"
+
+
+ ab123mno-6432-dceb-asdf-123mno543123
+
+ """
it 'extracts the error code', ->
parse (error, data) ->
@@ -56,7 +52,7 @@ describe 'AWS.EC2.Client', ->
expect(data).toEqual(null)
it 'returns an empty error when the body is blank', ->
- resp.body = ''
+ body = ''
parse (error, data) ->
expect(error.code).toEqual(400)
expect(error.message).toEqual(null)
diff --git a/test/unit/services/s3.spec.coffee b/test/unit/services/s3.spec.coffee
index 1f900357b9..6d995ff5ca 100644
--- a/test/unit/services/s3.spec.coffee
+++ b/test/unit/services/s3.spec.coffee
@@ -12,11 +12,17 @@
# language governing permissions and limitations under the License.
AWS = require('../../../lib/core')
+helpers = require('../../helpers')
+
require('../../../lib/services/s3')
describe 'AWS.S3.Client', ->
s3 = null
+ request = (operation, params) ->
+ req = new AWS.Request(s3, operation, params || {})
+ req.client.addAllRequestListeners(req)
+ req
beforeEach ->
s3 = new AWS.S3.Client()
@@ -70,42 +76,41 @@ describe 'AWS.S3.Client', ->
s3 = new AWS.S3.Client({ region: 'us-west-1' })
expect(s3.endpoint.hostname).toEqual('s3-us-west-1.amazonaws.com')
- describe 'buildRequest', ->
-
- it 'returns a http request object', ->
- req = s3.buildRequest('listBuckets')
- expect(req.constructor).toEqual(AWS.HttpRequest)
+ describe 'building a request', ->
+ build = (operation, params) ->
+ req = request(operation, params)
+ resp = new AWS.Response(req)
+ req.emitEvents(resp, 'build')
+ return req.httpRequest
it 'obeys the configuration for s3ForcePathStyle', ->
config = new AWS.Config({s3ForcePathStyle: true })
s3 = new AWS.S3.Client(config)
expect(s3.config.s3ForcePathStyle).toEqual(true)
- req = s3.buildRequest('headObject', {Bucket:'bucket', Key:'key'})
+ req = build('headObject', {Bucket:'bucket', Key:'key'})
expect(req.endpoint.hostname).toEqual('s3.amazonaws.com')
expect(req.path).toEqual('/bucket/key')
describe 'uri escaped params', ->
-
it 'uri-escapes path and querystring params', ->
# bucket param ends up as part of the hostname
params = { Bucket: 'bucket', Key: 'a b c', VersionId: 'a&b' }
- req = s3.buildRequest('headObject', params)
+ req = build('headObject', params)
expect(req.path).toEqual('/a%20b%20c?versionId=a%26b')
it 'does not uri-escape forward slashes in the path', ->
params = { Bucket: 'bucket', Key: 'k e/y' }
- req = s3.buildRequest('headObject', params)
+ req = build('headObject', params)
expect(req.path).toEqual('/k%20e/y')
it 'ensures a single forward slash exists', ->
-
- req = s3.buildRequest('listObjects', { Bucket: 'bucket' })
+ req = build('listObjects', { Bucket: 'bucket' })
expect(req.path).toEqual('/')
- req = s3.buildRequest('listObjects', { Bucket: 'bucket', MaxKeys:123 })
+ req = build('listObjects', { Bucket: 'bucket', MaxKeys:123 })
expect(req.path).toEqual('/?max-keys=123')
- it 'ensures a single forward slash exists when querystring is present', ->
+ it 'ensures a single forward slash exists when querystring is present'
describe 'vitual-hosted vs path-style bucket requests', ->
@@ -115,29 +120,29 @@ describe 'AWS.S3.Client', ->
s3 = new AWS.S3.Client({ sslEnabled: true, region: 'us-east-1' })
it 'puts dns-compat bucket names in the hostname', ->
- req = s3.buildRequest('headObject', {Bucket:'bucket-name',Key:'abc'})
+ req = build('headObject', {Bucket:'bucket-name',Key:'abc'})
expect(req.method).toEqual('HEAD')
expect(req.endpoint.hostname).toEqual('bucket-name.s3.amazonaws.com')
expect(req.path).toEqual('/abc')
it 'ensures the path contains / at a minimum when moving bucket', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket-name'})
+ req = build('listObjects', {Bucket:'bucket-name'})
expect(req.endpoint.hostname).toEqual('bucket-name.s3.amazonaws.com')
expect(req.path).toEqual('/')
it 'puts dns-compat bucket names in path if they contain a dot', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket.name'})
+ req = build('listObjects', {Bucket:'bucket.name'})
expect(req.endpoint.hostname).toEqual('s3.amazonaws.com')
expect(req.path).toEqual('/bucket.name')
it 'puts dns-compat bucket names in path if configured to do so', ->
s3 = new AWS.S3.Client({ sslEnabled: true, s3ForcePathStyle: true })
- req = s3.buildRequest('listObjects', {Bucket:'bucket-name'})
+ req = build('listObjects', {Bucket:'bucket-name'})
expect(req.endpoint.hostname).toEqual('s3.amazonaws.com')
expect(req.path).toEqual('/bucket-name')
it 'puts dns-incompat bucket names in path', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket_name'})
+ req = build('listObjects', {Bucket:'bucket_name'})
expect(req.endpoint.hostname).toEqual('s3.amazonaws.com')
expect(req.path).toEqual('/bucket_name')
@@ -147,17 +152,17 @@ describe 'AWS.S3.Client', ->
s3 = new AWS.S3.Client({ sslEnabled: false, region: 'us-east-1' })
it 'puts dns-compat bucket names in the hostname', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket-name'})
+ req = build('listObjects', {Bucket:'bucket-name'})
expect(req.endpoint.hostname).toEqual('bucket-name.s3.amazonaws.com')
expect(req.path).toEqual('/')
it 'puts dns-compat bucket names in the hostname if they contain a dot', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket.name'})
+ req = build('listObjects', {Bucket:'bucket.name'})
expect(req.endpoint.hostname).toEqual('bucket.name.s3.amazonaws.com')
expect(req.path).toEqual('/')
it 'puts dns-incompat bucket names in path', ->
- req = s3.buildRequest('listObjects', {Bucket:'bucket_name'})
+ req = build('listObjects', {Bucket:'bucket_name'})
expect(req.endpoint.hostname).toEqual('s3.amazonaws.com')
expect(req.path).toEqual('/bucket_name')
@@ -165,34 +170,32 @@ describe 'AWS.S3.Client', ->
# http spec) these tests ensure we give meaningful codes/messages for these.
describe 'errors with no XML body', ->
- extractError = (resp) ->
- s3.extractError(resp)
+ extractError = (statusCode) ->
+ req = request('operation')
+ resp = new AWS.Response(req)
+ resp.httpResponse.body = ''
+ resp.httpResponse.statusCode = statusCode
+ req.emit('foo')
+ req.emit('extractError', resp, req)
+ resp.error
it 'handles 304 errors', ->
- resp = new AWS.HttpResponse()
- resp.statusCode = 304
- error = extractError(resp)
+ error = extractError(304)
expect(error.code).toEqual('NotModified')
expect(error.message).toEqual(null)
it 'handles 403 errors', ->
- resp = new AWS.HttpResponse()
- resp.statusCode = 403
- error = extractError(resp)
+ error = extractError(403)
expect(error.code).toEqual('Forbidden')
expect(error.message).toEqual(null)
it 'handles 404 errors', ->
- resp = new AWS.HttpResponse()
- resp.statusCode = 404
- error = extractError(resp)
+ error = extractError(404)
expect(error.code).toEqual('NotFound')
expect(error.message).toEqual(null)
it 'misc errors not known to return an empty body', ->
- resp = new AWS.HttpResponse()
- resp.statusCode = 412 # made up
- error = extractError(resp)
+ error = extractError(412) # made up
expect(error.code).toEqual(412)
expect(error.message).toEqual(null)
@@ -201,12 +204,11 @@ describe 'AWS.S3.Client', ->
describe 'completeMultipartUpload', ->
it 'returns data when the resp is 200 with valid response', ->
- resp =
- statusCode: 200
- headers:
- 'x-amz-id-2': 'Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg=='
- 'x-amz-request-id': '656c76696e6727732072657175657374'
- body: """
+ headers =
+ 'x-amz-id-2': 'Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg=='
+ 'x-amz-request-id': '656c76696e6727732072657175657374'
+ body =
+ """
http://Example-Bucket.s3.amazonaws.com/Example-Object
@@ -215,7 +217,9 @@ describe 'AWS.S3.Client', ->
"3858f62230ac3c915f300c664312c11f-9"
"""
- s3.parseResponse resp, 'completeMultipartUpload', (error, data) ->
+
+ helpers.mockHttpResponse 200, headers, body
+ s3.completeMultipartUpload (error, data) ->
expect(error).toBe(null)
expect(data).toEqual({
Location: 'http://Example-Bucket.s3.amazonaws.com/Example-Object'
@@ -226,23 +230,19 @@ describe 'AWS.S3.Client', ->
})
it 'returns an error when the resp is 200 with an error xml document', ->
- resp =
- statusCode: 200
- headers: {}
- body: """
-
-
-
-
-
-
- InternalError
- We encountered an internal error. Please try again.
- 656c76696e6727732072657175657374
- Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==
-
- """
- s3.parseResponse resp, 'completeMultipartUpload', (error, data) ->
+ body =
+ """
+
+
+ InternalError
+ We encountered an internal error. Please try again.
+ 656c76696e6727732072657175657374
+ Uuag1LuByRx9e6j5Onimru9pO4ZVKnJ2Qz7/C1NPcfTWAtRPfTaOFg==
+
+ """
+
+ helpers.mockHttpResponse 200, {}, body
+ s3.completeMultipartUpload (error, data) ->
expect(error instanceof Error).toBeTruthy()
expect(error.code).toEqual('InternalError')
expect(error.message).toEqual('We encountered an internal error. Please try again.')
@@ -253,20 +253,17 @@ describe 'AWS.S3.Client', ->
describe 'getBucketLocation', ->
it 'returns null for the location constraint when not present', ->
- resp =
- statusCode: 200
- headers: {}
- body: '\n'
- s3.parseResponse resp, 'getBucketLocation', (error, data) ->
+ body = '\n'
+ helpers.mockHttpResponse 200, {}, body
+ s3.getBucketLocation (error, data) ->
expect(error).toBe(null)
expect(data).toEqual({})
it 'parses the location constraint from the root xml', ->
- resp =
- statusCode: 200
- headers: { 'x-amz-request-id': 'abcxyz' }
- body: '\nEU'
- s3.parseResponse resp, 'getBucketLocation', (error, data) ->
+ headers = { 'x-amz-request-id': 'abcxyz' }
+ body = '\nEU'
+ helpers.mockHttpResponse 200, headers, body
+ s3.getBucketLocation (error, data) ->
expect(error).toBe(null)
expect(data).toEqual({
LocationConstraint: 'EU',
diff --git a/test/unit/sigv2.spec.coffee b/test/unit/sigv2.spec.coffee
index e4efc15bb5..779d351dce 100644
--- a/test/unit/sigv2.spec.coffee
+++ b/test/unit/sigv2.spec.coffee
@@ -12,7 +12,7 @@
# language governing permissions and limitations under the License.
AWS = require('../../lib/core')
-require('../../lib/query_client')
+require('../../lib/service_interface/query')
require('../../lib/sigv2')
describe 'AWS.SigV2', ->
@@ -23,9 +23,7 @@ describe 'AWS.SigV2', ->
signer = null
buildRequest = ->
- request = new AWS.HttpRequest()
- request.endpoint = new AWS.Endpoint('localhost')
- request.endpoint.hostname = 'locahost'
+ request = new AWS.HttpRequest(new AWS.Endpoint('localhost'))
request.params = new AWS.QueryParamList()
request
diff --git a/test/unit/sigv4.spec.coffee b/test/unit/sigv4.spec.coffee
index 3d8e4fd834..b644f726c9 100644
--- a/test/unit/sigv4.spec.coffee
+++ b/test/unit/sigv4.spec.coffee
@@ -12,16 +12,18 @@
# language governing permissions and limitations under the License.
AWS = require('../../lib/core')
+helpers = require('../helpers')
require('../../lib/services/dynamodb')
beforeEach ->
spyOn(AWS.util, 'userAgent').andReturn('aws-sdk-js/0.1')
buildRequest = ->
- ddb = new AWS.DynamoDB.Client({ region:'region' })
- req = ddb.buildRequest('listTables', { foo: 'bar' })
- req.endpoint.hostname = 'localhost'
- return req
+ ddb = new AWS.DynamoDB.Client({region: 'region', endpoint: 'localhost'})
+ req = ddb.makeRequest('listTables', {foo: 'bar'})
+ resp = new AWS.Response(req)
+ req.emitEvents(resp, 'validate', 'build')
+ return req.httpRequest
buildSigner = (request) ->
return new AWS.SigV4(request || buildRequest(), 'dynamodb')
diff --git a/test/unit/sigvs3.spec.coffee b/test/unit/sigvs3.spec.coffee
index 17581439ec..6d2f5d8d88 100644
--- a/test/unit/sigvs3.spec.coffee
+++ b/test/unit/sigvs3.spec.coffee
@@ -32,7 +32,7 @@ describe 'AWS.SigVS3', ->
method = 'POST'
path = '/'
virtualHostedBucket = null
- date = undefined
+ date = new Date(0)
headers = {}
body = null
accessKeyId = 'akid'
@@ -65,33 +65,16 @@ describe 'AWS.SigVS3', ->
signer.stringToSign()
describe 'addAuthorization', ->
-
- beforeEach ->
- date = AWS.util.date.rfc822(new Date(0))
-
it 'sets the date header when not present', ->
-
req = buildRequest()
+ addAuth(req)
+ expect(req.headers['Date']).toEqual(AWS.util.date.rfc822(date))
- # stub date.rfc822 to return a fixed date string
- spyOn(AWS.util.date, 'rfc822')
- AWS.util.date.rfc822.andReturn('date-string')
-
- signer = new AWS.SigVS3(req)
- signer.addAuthorization(credentials())
-
- expect(req.headers['Date']).toEqual('date-string')
-
- it 'does not set the date header if x-amz-date is present', ->
-
+ it 'overwrites Date if present', ->
req = buildRequest()
- req.headers['X-Amz-Date'] = 'date-string'
-
- signer = new AWS.SigVS3(buildRequest())
- signer.addAuthorization(credentials())
-
- expect(req.headers['Date']).toEqual(null)
- expect(req.headers['X-Amz-Date']).toEqual('date-string')
+ req.headers['Date'] = 'date-string'
+ addAuth(req)
+ expect(req.headers['Date']).toEqual(AWS.util.date.rfc822(date))
it 'omits the security token header when session token is blank', ->
sessionToken = null
diff --git a/test/unit/util.spec.coffee b/test/unit/util.spec.coffee
index 1ae7435605..79af6c97f0 100644
--- a/test/unit/util.spec.coffee
+++ b/test/unit/util.spec.coffee
@@ -181,6 +181,10 @@ describe 'AWS.util.arrayEach', ->
expect(total).toEqual(1)
describe 'AWS.util.copy', ->
+ it 'does not copy null or undefined', ->
+ expect(AWS.util.copy(null)).toEqual(null)
+ expect(AWS.util.copy(undefined)).toEqual(undefined)
+
it 'should perform a shallow copy of an object', ->
obj = a: 1, b: 2, c: 3
copied = AWS.util.copy(obj)
@@ -236,6 +240,17 @@ describe 'AWS.util.inherit', ->
expect(derived.defaultValue).toEqual(10)
expect(derived.foo()).toEqual('bar')
+ it 'should create pass-through constructor if not defined', ->
+ Base = AWS.util.inherit
+ constructor: createSpy()
+
+ Derived = AWS.util.inherit Base,
+ other: true
+
+ derived = new Derived(1, 2, 'three')
+ expect(derived.other).toEqual(true)
+ expect(Base.prototype.constructor).toHaveBeenCalledWith(1, 2, 'three')
+
describe 'AWS.util.isEmpty', ->
it 'returns true when passed an empty object literal', ->