Index: aws.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/aws/aws.module,v
retrieving revision 1.2
diff -u -r1.2 aws.module
--- aws.module	22 Jan 2008 06:20:07 -0000	1.2
+++ aws.module	28 Jan 2008 02:46:44 -0000
@@ -99,20 +99,30 @@
  * @return object std class see README
  */
 function aws_request($request = array(), $headers = array(), $data = null, $retry = 3) {
-	$headers = aws_buildHeader($request, $headers, $data);
-	$response = rest_client_request($request, $headers, $data, $retry);
+  switch ($headers['host']) {
+    case 's3.amazonaws.com':  
+    	$headers = aws_buildRestHeader($request, $headers, $data);
+	    $response = rest_client_request($request, $headers, $data, $retry);
+	    break;
+    case 'ec2.amazonaws.com':
+    case 'sqs.amazonaws.com':      
+      $headers = aws_buildQueryHeader($request, $headers, $data);
+      $querystring = aws_buildQueryString($request, $headers, $data);
+      $response = drupal_http_request("http://" . $headers['host'] . "/?" . $querystring, $headers);
+      break;
+  }
 	return $response;
 }
 
 /**
- * Builds the needed headers for AWS, including signing the header.
+ * Builds the needed headers for AWS over REST, including signing the header.
  * @private
  * @param $request array see README
  * @param $headers array see README
  * @param $data    array see README
  * @return array of headers to be used in the HTTP request
  */
-function aws_buildHeader($request, $headers, $data) {
+function aws_buildRestHeader($request, $headers, $data) {
 	// TODO: run check for all aws specific required headers and provide error feedback
 	
 	// get AWS access key
@@ -142,6 +152,67 @@
 }
 
 /**
+ * Builds the needed headers for AWS over QUERY
+ * @private
+ * @param $request array see README
+ * @param $headers array see README
+ * @param $data    array see README
+ * @return the query string to be used in the HTTP request
+ */
+function aws_buildQueryHeader($request, $headers, $data) {
+	// TODO: run check for all aws specific required headers and provide error feedback
+	
+  // set defaults
+	$headers['host'] = $headers['host'] ? $headers['host'] : variable_get('aws_ec2_host', 'ec2.amazonaws.com');
+	// not using DATE_RFC822 constant to be PHP4 compat, DATE_RFC822 > PHP 5.1.1
+	$headers['date'] = gmdate('D, d M Y H:i:s T');
+
+	if ($data && ! $headers['content-type']) {
+		$headers['content-type'] = ($data['type'] === 'string')  ? 'text/plain' : 'binary/octet-stream';
+	}
+
+  return $headers;
+}
+
+/**
+ * Builds the querystring for AWS over QUERY, including signing the header.
+ * @private
+ * @param $request array see README
+ * @param $headers array see README
+ * @param $data    array see README
+ * @return the query string to be used in the HTTP request
+ */
+function aws_buildQueryString($request, $headers, $data) {
+	// TODO: run check for all aws specific required headers and provide error feedback
+	$now = time();
+	
+	// required querystring values
+  $query['Action'] = $request['Action'];
+  $query['Version'] = variable_get('ec2_api_version', '2007-08-29');
+  $query['AWSAccessKeyId'] = variable_get('aws_accessKey', '');
+  $query['SignatureVersion'] = 1;
+  
+  // Use an expiry if we've set one.  Amazon defaults to 15 minutes when a timestamp is used instead 
+  if (variable_get('aws_request_expiry', '')) {
+    $query['Expires'] = gmdate("Y-m-d\TH:i:s", $currentTime + variable_get('aws_request_expiry', '')) . 'Z';
+  }
+  else {
+    $query['Timestamp'] = gmdate("Y-m-d\TH:i:s", $now) . 'Z';
+  }
+
+	// Process parameters and allow overriding defults set above
+	foreach ($request as $key => $value) {
+	  $query[$key] = $value;
+	}
+	
+	// set authorization with header signature
+	$query['Signature'] = aws_querystringSign($query);
+	
+	// return the encoded querystring
+  return drupal_query_string_encode($query);	
+}
+
+/**
  * Creates the header signature
  * @private
  * @param $request array see README
@@ -174,11 +245,48 @@
 	}
 	
 	// get AWS secret access key
-    $secretKey = variable_get('aws_secretKey', '');
+  $secretKey = variable_get('aws_secretKey', '');
 
 	// Build and sign the string
 	$strToSign .=  $h . "\n" . $request['cresource'];
 	return rest_client_hmac($strToSign, $secretKey);
 }
 
+/**
+ * Creates the querystring signature
+ * @private
+ * @param $request array see README
+ * @return string signature
+ */
+function aws_querystringSign($request) {
+  // Amazon need items sorted case-insensitively
+  uksort($request, 'strnatcasecmp');
+
+	// get AWS secret access key
+  $secretKey = variable_get('aws_secretKey', '');
+
+	// Build and sign the string
+  foreach ($request as $key => $value) {
+    $strToSign .= $key . $value;
+  }
+  // TODO: Remove rest_client dependency
+	return rest_client_hmac($strToSign, $secretKey);
+}
+
+/**
+ * Converts an array to array with numbered labels ('item.1' => 'data', 'item.2' => 'data')
+ * @private
+ * @param $label string  Label name to prepend .<itemcount>
+ * @param $items array   Array of items
+ * @return array formatted array
+ */
+function aws_arraytorequest($label, $items = array()) {
+  $result = array();
+  $itemcount = 1;
+  foreach ($items as $item) {
+    $result[$label . '.' . $itemcount++] = $item;
+  }
+	return $result;
+}
+
 ?>
