• Модуль: clouds
  • Путь к файлу: ~/bitrix/modules/clouds/classes/general/storage_service_s3.php
  • Класс: CCloudStorageService_S3
  • Вызов: CCloudStorageService_S3::SendRequest
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;
	}
}