function SendRequest($arSettings, $verb, $bucket, $file_name='/', $params='', $content='', $additional_headers=/*.(array[string]string).*/array())
{
global $APPLICATION;
$this->status = 0;
$request = new BitrixMainWebHttpClient(array(
"redirect" => false,
"streamTimeout" => $this->streamTimeout,
));
if (isset($additional_headers["option-file-result"]))
{
$request->setOutputStream($additional_headers["option-file-result"]);
}
if(isset($additional_headers["Content-Type"]))
{
$ContentType = $additional_headers["Content-Type"];
}
else
{
$ContentType = $content != ""? 'text/plain': '';
}
unset($additional_headers["Content-Type"]);
foreach($this->set_headers as $key => $value)
{
$additional_headers[$key] = $value;
}
if(array_key_exists("SESSION_TOKEN", $arSettings))
{
$additional_headers["x-amz-security-token"] = $arSettings["SESSION_TOKEN"];
}
$host = $additional_headers["Host"] = $this->GetRequestHost($bucket, $arSettings);
foreach($this->SignRequest($arSettings, $verb, $bucket, $file_name, $ContentType, $additional_headers, $params, $content) as $key => $value)
{
$request->setHeader($key, $value);
}
foreach($additional_headers as $key => $value)
if(!preg_match("/^option-/", $key))
$request->setHeader($key, $value);
$was_end_point = $this->new_end_point;
$this->new_end_point = '';
$useHttps = $arSettings["USE_HTTPS"] ?? 'N';
$this->status = 0;
$this->host = $host;
$this->verb = $verb;
$this->url = ($useHttps === "Y"? "https": "http")."://".$host.$file_name.$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,
);
if (function_exists("getmypid"))
$logRequest["pid"] = getmypid();
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"])
|| isset($additional_headers["option--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
$e = new CApplicationException(GetMessage('CLO_STORAGE_S3_XML_PARSE_ERROR', array('#errno#'=>'1')));
$APPLICATION->ThrowException($e);
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(
$arSettings,
$verb,
$bucket,
$file_name,
$params,
$content,
$additional_headers
);
}
elseif($this->status > 0)
{
if($this->result != "")
{
$obXML = new CDataXML;
if($obXML->LoadString($this->result))
{
$node = $obXML->SelectNodes("/Error/Message");
if (is_object($node))
{
$errorMessage = trim($node->textContent(), '.');
$e = new CApplicationException(GetMessage('CLO_STORAGE_S3_XML_ERROR', array(
'#errmsg#' => $errorMessage,
)));
$APPLICATION->ThrowException($e);
return false;
}
$node = $obXML->SelectNodes("/Error/Code");
if (is_object($node))
{
$errorMessage = trim($node->textContent(), '.');
$e = new CApplicationException(GetMessage('CLO_STORAGE_S3_XML_ERROR', array(
'#errmsg#' => $errorMessage,
)));
$APPLICATION->ThrowException($e);
return false;
}
}
}
$e = new CApplicationException(GetMessage('CLO_STORAGE_S3_XML_PARSE_ERROR', array('#errno#'=>'2')));
$APPLICATION->ThrowException($e);
return false;
}
else
{
$e = new CApplicationException(GetMessage('CLO_STORAGE_S3_XML_PARSE_ERROR', array('#errno#'=>'3')));
$APPLICATION->ThrowException($e);
return false;
}
}