function SendRequest($access_key, $secret_key, $verb, $bucket, $file_name='/', $params='', $content='', $additional_headers=array())
{
global $APPLICATION;
$this->status = 0;
if(isset($additional_headers["Content-Type"]))
{
$ContentType = $additional_headers["Content-Type"];
unset($additional_headers["Content-Type"]);
}
else
{
$ContentType = $content? 'text/plain': '';
}
if(!array_key_exists("x-goog-api-version", $additional_headers))
$additional_headers["x-goog-api-version"] = "1";
$RequestMethod = $verb;
$RequestURI = $file_name;
$RequestDATE = gmdate('D, d M Y H:i:s', time()).' GMT';
//Prepare Signature
$CanonicalizedAmzHeaders = "";
ksort($additional_headers);
foreach($additional_headers as $key => $value)
if(preg_match("/^x-goog-/", $key))
$CanonicalizedAmzHeaders .= $key.":".$value."n";
$CanonicalizedResource = "/".$bucket.$RequestURI;
$StringToSign = "$RequestMethodnn$ContentTypen$RequestDATEn$CanonicalizedAmzHeaders$CanonicalizedResource";
//$utf = $APPLICATION->ConvertCharset($StringToSign, LANG_CHARSET, "UTF-8");
$Signature = base64_encode($this->hmacsha1($StringToSign, $secret_key));
$Authorization = "GOOG1 ".$access_key.":".$Signature;
$request = new BitrixMainWebHttpClient(array(
"redirect" => false,
"streamTimeout" => $this->streamTimeout,
));
if (isset($additional_headers["option-file-result"]))
{
$request->setOutputStream($additional_headers["option-file-result"]);
}
$request->setHeader("Date", $RequestDATE);
$request->setHeader("Authorization", $Authorization);
foreach($additional_headers as $key => $value)
if(!preg_match("/^option-/", $key))
$request->setHeader($key, $value);
if(
$this->new_end_point
&& preg_match('#^(http|https)://'.preg_quote($bucket, '#').'(.+)/#', $this->new_end_point, $match))
{
$host = $match[2];
}
else
{
$host = $bucket.".commondatastorage.googleapis.com";
}
$was_end_point = $this->new_end_point;
$this->new_end_point = '';
$this->status = 0;
$this->host = $host;
$this->verb = $RequestMethod;
$this->url = "http://".$host.$RequestURI.$params;
$this->headers = array();
$this->errno = 0;
$this->errstr = '';
$this->result = '';
$logRequest = false;
if (defined("BX_CLOUDS_TRACE") && $verb !== "GET" && $verb !== "HEAD")
{
$stime = microtime(1);
$logRequest = array(
"request_id" => md5((string)mt_rand()),
"portal" => $_SERVER["HTTP_HOST"],
"verb" => $this->verb,
"url" => $this->url,
);
AddMessage2Log(json_encode($logRequest), 'clouds', 20);
}
$request->setHeader("Content-type", $ContentType);
$request->query($this->verb, $this->url, $content);
$this->status = $request->getStatus();
foreach($request->getHeaders() as $key => $value)
{
$this->headers[$key] = is_array($value) ? $value[0] : $value;
}
$this->errstr = implode("n", $request->getError());
$this->errno = $this->errstr? 255: 0;
$this->result = $request->getResult();
if ($logRequest)
{
$logRequest["status"] = $this->status;
$logRequest["time"] = round(microtime(true) - $stime, 6);
$logRequest["headers"] = $this->headers;
AddMessage2Log(json_encode($logRequest), 'clouds', 0);
}
if($this->status == 200)
{
if(isset($additional_headers["option-raw-result"]))
{
return $this->result;
}
elseif($this->result)
{
$obXML = new CDataXML;
$text = preg_replace("/<"."\?XML.*?\?".">/i", "", $this->result);
if($obXML->LoadString($text))
{
$arXML = $obXML->GetArray();
if(is_array($arXML))
{
return $arXML;
}
}
//XML parse error
$APPLICATION->ThrowException(GetMessage('CLO_STORAGE_GOOGLE_XML_PARSE_ERROR', array('#errno#'=>1)));
return false;
}
else
{
//Empty success result
return array();
}
}
elseif(
$this->status == 307 //Temporary redirect
&& isset($this->headers["Location"])
&& !$was_end_point //No recurse yet
)
{
$this->new_end_point = $this->headers["Location"];
return $this->SendRequest(
$access_key,
$secret_key,
$verb,
$bucket,
$file_name,
$params,
$content,
$additional_headers
);
}
elseif($this->status > 0)
{
if($this->result)
{
$obXML = new CDataXML;
if($obXML->LoadString($this->result))
{
$arXML = $obXML->GetArray();
if(is_array($arXML) && is_string($arXML["Error"]["#"]["Message"][0]["#"]))
{
$APPLICATION->ThrowException(GetMessage('CLO_STORAGE_GOOGLE_XML_ERROR', array('#errmsg#'=>trim($arXML["Error"]["#"]["Message"][0]["#"], '.'))));
return false;
}
}
}
$APPLICATION->ThrowException(GetMessage('CLO_STORAGE_GOOGLE_XML_PARSE_ERROR', array('#errno#'=>2)));
return false;
}
else
{
$APPLICATION->ThrowException(GetMessage('CLO_STORAGE_GOOGLE_XML_PARSE_ERROR', array('#errno#'=>3)));
return false;
}
}