private function _request($action, $params = array()) {
		// Add in required params
		$params['Action'] = $action;
		$params['AWSAccessKeyId'] = $this->access_key;
		$params['Timestamp'] = gmdate('Y-m-d\TH:i:s.000\Z');
		$params['SignatureVersion'] = 2;
		$params['SignatureMethod'] = 'HmacSHA256';

		// Sort and encode into string
		uksort($params, 'strnatcmp');
		$queryString = '';
		foreach ($params as $key => $val) {
			$queryString .= "&{$key}=".rawurlencode($val);
		}
		$queryString = substr($queryString, 1);

		// Form request string
		$requestString = "GET\n"
			. $this->endpoint."\n"
			. "/\n"
			. $queryString;

		// Create signature - Version 2
		$params['Signature'] = base64_encode(
			hash_hmac('sha256', $requestString, $this->secret_key, true)
		);

		// Finally create request
		$request = $this->endpoint . '/?' . http_build_query($params, '', '&');

		// Instantiate cUrl and perform request
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $request);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

		$output = curl_exec($ch);
		$info = curl_getinfo($ch);

		// Close cUrl
		curl_close($ch);

		// Load XML response
		$xmlResponse = simplexml_load_string($output);

		// Check return code
		if($this->_checkGoodResponse($info['http_code']) === false) {
			// Response not in 200 range
			if(isset($xmlResponse->Error)) {
				// Amazon returned an XML error
				throw new SNSException(strval($xmlResponse->Error->Code) . ': ' . strval($xmlResponse->Error->Message), $info['http_code']);
			}
			else {
				// Some other problem
				throw new APIException('There was a problem executing this request', $info['http_code']);
			}
		}
		else {
			// All good
			return $xmlResponse;
		}
	}