/**
* Calls Amazon web service method.
*
* It ensures execution of the certain AWS action by transporting the request
* and receiving response.
*
* @param string $action REST METHOD (GET|PUT|DELETE|HEAD etc).
* @param array $options An options array. It's used to send headers for the HTTP request.
* extra options: _subdomain, _putData, _putFile
* @param string $path optional A relative path.
* @return ClientResponseInterface
* @throws ClientException
*/
public function call($action, $options, $path = '/')
{
$httpRequest = $this->createRequest();
$httpMethod = $action ?: 'GET';
if (substr($path, 0, 1) !== '/') {
$path = '/' . $path;
}
$this->lastApiCall = null;
$eventObserver = $this->getAws()->getEventObserver();
if ($eventObserver && $eventObserver->isSubscribed(EventType::EVENT_SEND_REQUEST)) {
foreach (debug_backtrace() as $arr) {
if (empty($arr['class']) || !preg_match("/\\\\Service\\\\Aws\\\\.+Api\$/", $arr['class']) || $arr['type'] !== '->') {
continue;
}
$this->lastApiCall = ucfirst($arr['function']);
break;
}
}
//Wipes out extra options from headers and moves them to separate array.
//It also collects an x-amz headers.
$extraOptions = ['region' => null];
foreach ($options as $key => $val) {
if (substr($key, 0, 1) === '_') {
$extraOptions[substr($key, 1)] = $val;
unset($options[$key]);
}
}
if (!isset($options['Host'])) {
$options['Host'] = (isset($extraOptions['subdomain']) ? $extraOptions['subdomain'] . '.' : '') . $this->url;
}
if (strpos($options['Host'], 'http') === 0) {
$arr = parse_url($options['Host']);
$scheme = $arr['scheme'];
$options['Host'] = $arr['host'] . (isset($arr['port']) ? ':' . $arr['port'] : '');
$path = (!empty($arr['path']) && $arr['path'] != '/' ? rtrim($arr['path'], '/') : '') . $path;
} else {
$scheme = 'https';
}
if ($httpMethod === 'PUT' || $httpMethod === 'POST') {
if (!empty($extraOptions['putData'])) {
$httpRequest->append($extraOptions['putData']);
$options['Content-Md5'] = Aws::getMd5Base64Digest($extraOptions['putData']);
} elseif (!empty($extraOptions['putFile'])) {
$httpRequest->addFiles([$extraOptions['putFile']]);
$options['Content-Md5'] = Aws::getMd5Base64DigestFile($extraOptions['putFile']);
}
}
$httpRequest->setRequestUrl($scheme . '://' . $options['Host'] . $path);
$httpRequest->setRequestMethod($httpMethod);
$httpRequest->addHeaders($options);
if (true) {
$this->signRequestV4($httpRequest, !empty($extraOptions['region']) ? $extraOptions['region'] : null, empty($extraOptions['putFile']) ? null : $extraOptions['putFile']);
} else {
$this->signRequestV3($httpRequest, isset($extraOptions['subdomain']) ? $extraOptions['subdomain'] : null);
}
$response = $this->tryCall($httpRequest);
if ($this->getAws() && $this->getAws()->getDebug()) {
echo "\n", "{$httpRequest}\n", "{$response->getResponse()}\n";
}
return $response;
}