403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/ilovecveti.ru/bitrix/modules/calendar/lib/sync/office365/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/ilovecveti.ru/bitrix/modules/calendar/lib/sync/office365/apiclient.php
<?php

namespace Bitrix\Calendar\Sync\Office365;

use Bitrix\Calendar\Sync\Exceptions\PreconditionFailedException;
use Bitrix\Calendar\Sync\Office365\Util\ObjectStatusTrait;
use Bitrix\Calendar\Sync\Exceptions\ApiException;
use Bitrix\Calendar\Sync\Exceptions\AuthException;
use Bitrix\Calendar\Sync\Exceptions\GoneException;
use Bitrix\Calendar\Sync\Internals\ContextInterface;
use Bitrix\Calendar\Sync\Internals\HasContextTrait;
use Bitrix\Calendar\Sync\Exceptions\ConflictException;
use Bitrix\Calendar\Sync\Exceptions\NotFoundException;
use Bitrix\Calendar\Sync\Util\RequestLogger;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Json;
use Exception;

/**
 * Low level controller for working with rest-api.
 */
class ApiClient
{
	use ObjectStatusTrait, HasContextTrait;

	/** @var HttpClient */
	protected HttpClient $httpClient;
	/** @var RequestLogger */
	protected RequestLogger $logger;

	/**
	 * @param HttpClient $httpClient
	 *
	 * @param Office365Context $context
	 */
	public function __construct(HttpClient $httpClient, ContextInterface $context)
	{
		$this->httpClient = $httpClient;
		$this->context = $context;
	}

	/**
	 * @param string $method
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function request(string $method, string $uri, array $params): array
	{
		$getLogContext = static function (int $statusCode, $response, string $error = '' )
			use ($method, $uri, $params): array
		{
			return [
				'serviceName' => Helper::ACCOUNT_TYPE,
				'host' => Helper::SERVER_PATH,
				'method' => $method,
				'url' => $uri,
				'requestParams' => $params,
				'statusCode' => $statusCode,
				'error' => $error,
				'response' => $response,
			];
		};
		$this->getStatus()->resetErrors();
		try
		{
			$response = [];
			$paramString = $this->prepareParams($params);

			$uri = Helper::SERVER_PATH . $uri;

			$this->httpClient->waitResponse(true);
			$this->httpClient->query($method, $uri, $paramString);

			if ($this->httpClient->getStatus() < 300)
			{
				$response = $this->prepareResponse();
				$this->context->getLogger()
					->debug("API office365 success" . $this->httpClient->getStatus()
						, $getLogContext(
							$this->httpClient->getStatus(),
							$this->httpClient->getResult(),
						)
					);
			}
			else
			{
				try
				{
					$error = Json::decode($this->httpClient->getResult());
					$this->getStatus()->addError(
						"CONNECTION",
						"[" . $error['error']['code'] . "] " . $error['error']['message'],
					);
					$this->context->getLogger()
						->warning("API office365 returned error code "
								. $this->httpClient->getStatus()
								. ": " . $error['error']['message'],
							$getLogContext(
								$this->httpClient->getStatus(),
								$this->httpClient->getResult(),
								$error['error']['message']
							)
						);
					switch ($this->httpClient->getStatus())
					{
						case 401:
							throw new AuthException(
								$error['error']['code'],
								401,
								__FILE__,
								__LINE__
							);
						case 404:
							throw new NotFoundException(
								$error['error']['code'],
								404,
								__FILE__,
								__LINE__
							);
						case 409:
							throw new ConflictException(
								$error['error']['code'],
								409,
								__FILE__,
								__LINE__
							);
						case 410:
							throw new GoneException(
								$error['error']['code'],
								410,
								__FILE__,
								__LINE__
							);
						case 412:
							throw new PreconditionFailedException(
								$error['error']['code'],
								412,
								__FILE__,
								__LINE__
							);
						default:
							throw new ApiException(
								$error['error']['code'],
								$this->httpClient->getStatus(),
								__FILE__,
								__LINE__
							);
					}
				}
				catch (ArgumentException $exception)
				{
					$this->context->getLogger()
						->error("ArgumentException from office365", $getLogContext(
							$this->httpClient->getStatus(),
							$this->httpClient->getResult(),
							$exception->getMessage()
						));
					foreach($this->httpClient->getError() as $code => $error)
					{
						$this->getStatus()->addError($code, $error);
					}
				}
			}
		}
		catch (ApiException $e)
		{
			$this->context->getLogger()
				->error("ApiException from office365", $getLogContext(
					$e->getCode(),
					'',
					$e->getMessage()
					)
				);
			throw $e;
		}
		catch (Exception $e)
		{
			$this->context->getLogger()
				->error("Exception from office365: " . $e->getMessage(), $getLogContext(
					$e->getCode(),
					'',
					$e->getMessage()
					)
				);
			throw $e;
		}

		return $response;
	}

	/**
	 * @param string $response
	 * @param string $boundary
	 *
	 * @return array
	 */
	protected function multipartDecode(string $response, string $boundary): array
	{
		$events = [];

		$response = str_replace("--$boundary--", "--$boundary", $response);
		$parts = explode("--$boundary\r\n", $response);

		foreach ($parts as $part)
		{
			$part = trim($part);
			if (!empty($part))
			{
				$partEvent = explode("\r\n\r\n", $part);
				$data = $this->getMetaInfo($partEvent[1]);
				$id = $this->getId($partEvent[0]);

				if ($data['status'] === 200)
				{
					if ($id === null)
					{
						continue;
					}

					try
					{
						$event = Json::decode($partEvent[2]);
					}
					catch (Exception $exception)
					{
						continue;
					}

					$event['etag'] = $data['etag'];
					$events[$id] = $event;
				}
			}
		}

		return $events;
	}

	private function getMetaInfo($headers): array
	{
		$data = [];
		foreach (explode("\n", $headers) as $k => $header)
		{
			if($k === 0)
			{
				if(preg_match('#HTTP\S+ (\d+)#', $header, $find))
				{
					$data['status'] = (int)$find[1];
				}
			}
			elseif(mb_strpos($header, ':') !== false)
			{
				[$headerName, $headerValue] = explode(':', $header, 2);
				if(mb_strtolower($headerName) === 'etag')
				{
					$data['etag'] = trim($headerValue);
				}
			}
		}

		return $data;
	}

	/**
	 * @param string $headers
	 *
	 * @return int|null
	 */
	private function getId(string $headers): ?int
	{
		$id = null;
		foreach (explode("\n", $headers) as $header)
		{
			if(mb_strpos($header, ':') !== false)
			{
				[$headerName, $headerValue] = explode(':', $header, 2);
				if(mb_strtolower($headerName) === 'content-id')
				{
					$part = explode(':', $headerValue);
					$id = (int) rtrim($part[1], ">");
					break;
				}
			}
		}

		return $id;
	}


	/**
	 * @param array $params
	 *
	 * @return string|null
	 *
	 * @throws ArgumentException
	 */
	protected function prepareParams(array $params): ?string
	{
		return $this->formatParams($params);
	}

	/**
	 * @param array $params
	 *
	 * @return string|null
	 *
	 * @throws ArgumentException
	 */
	protected function formatParams(array $params): ?string
	{
		return $params ? Json::encode($params, JSON_UNESCAPED_SLASHES) : null;
	}

	/**
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function get(string $uri, array $params = []): array
	{
		if ($params)
		{
			$uri .= (strpos($uri, '?') ? '&' : '?')
				. http_build_query($params)
			;
		}
		return $this->request(HttpClient::HTTP_GET, $uri, $params);
	}

	/**
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function post(string $uri, array $params = []): array
	{
		return $this->request(HttpClient::HTTP_POST, $uri, $params);
	}

	/**
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function delete(string $uri, array $params = []): array
	{
		return $this->request(HttpClient::HTTP_DELETE, $uri, $params);
	}

	/**
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function put(string $uri, array $params = []): array
	{
		return $this->request(HttpClient::HTTP_PUT, $uri, $params);
	}

	/**
	 * @param string $uri
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function patch(string $uri, array $params = []): array
	{
		return $this->request(HttpClient::HTTP_PATCH, $uri, $params);
	}

	/**
	 * @return array|mixed
	 *
	 * @throws ArgumentException
	 */
	protected function prepareResponse()
	{
		$contentType = $this->httpClient->getHeaders()->getContentType();

		if ($contentType === 'multipart/mixed')
		{
			$response = $this->multipartDecode(
				$this->httpClient->getResult(),
				$this->httpClient->getHeaders()->getBoundary()
			);
		}
		else
		{
			$response = $this->httpClient->getResult()
				? Json::decode($this->httpClient->getResult())
				: [];
		}

		return $response;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit