• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/web/http/socket/handler.php
  • Класс: BitrixMainWebHttpSocketHandler
  • Вызов: Handler::process
public function process(HttpPromise $promise)
{
	$request = $this->request;

	try
	{
		switch ($this->state)
		{
			case self::PENDING:
				// this is a new job - should connect asynchronously
				try
				{
					$this->socket->connect();
				}
				catch (RuntimeException $e)
				{
					throw new HttpNetworkException($request, $e->getMessage());
				}

				$this->state = self::CONNECTED;
				break;

			case self::CONNECTED:
			case self::CONNECT_RECEIVED:
				if ($this->state === self::CONNECTED && $this->useProxy && $request->getUri()->getScheme() === 'https')
				{
					// implement CONNECT method for https connections via proxy
					$this->sendConnect();

					$this->state = self::CONNECT_SENT;
				}
				else
				{
					// enable ssl before sending request headers
					if ($request->getUri()->getScheme() === 'https')
					{
						$this->socket->setBlocking();

						if ($this->socket->enableCrypto() === false)
						{
							throw new HttpNetworkException($request, 'Error establishing an SSL connection.');
						}
					}

					// the socket is ready - can write headers
					$this->sendHeaders();

					// prepare the body for sending
					$body = $request->getBody();
					if ($body->isSeekable())
					{
						$body->rewind();
					}

					$this->state = self::HEADERS_SENT;
				}
				break;

			case self::CONNECT_SENT:
				if ($this->receiveHeaders())
				{
					$this->log("<<responseHeaders . "n", WebHttpDebug::REQUEST_HEADERS);

					// response to CONNECT from the proxy
					$headers = WebHttpHeaders::createFromString($this->responseHeaders);

					if (($status = $headers->getStatus()) >= 200 && $status < 300)
					{
						$this->responseHeaders = '';

						$this->state = self::CONNECT_RECEIVED;
					}
					else
					{
						throw new HttpNetworkException($request, 'Error receiving the CONNECT response from the proxy: ' . $headers->getStatus() . ' ' . $headers->getReasonPhrase());
					}
				}
				break;

			case self::HEADERS_SENT:
				// it's time to send the request body asynchronously
				if ($this->sendBody())
				{
					// sent all the body
					$this->state = self::BODY_SENT;
				}
				break;

			case self::BODY_SENT:
				// request is sent now - switching to reading
				if ($this->receiveHeaders())
				{
					// all headers received
					$this->log("n<<responseHeaders . "n", WebHttpDebug::RESPONSE_HEADERS);

					try
					{
						// build the response for the next stage
						$this->response = $this->responseBuilder->createFromString($this->responseHeaders);
					}
					catch (InvalidArgumentException $e)
					{
//							throw new HttpNetworkException($request, 'Incorrect response header: ' . $e->getMessage());
						throw new InvalidArgumentException($e->getMessage() . ' ' . $request->getUri());
					}

					$fetchBody = $this->waitResponse;

					if ($this->shouldFetchBody !== null)
					{
						$fetchBody = call_user_func($this->shouldFetchBody, $this->response, $request);
					}

					if ($fetchBody)
					{
						$this->state = self::HEADERS_RECEIVED;
					}
					else
					{
						$this->socket->close();

						// we don't want a body, just fulfil a promise with response headers
						$promise->fulfill($this->response);

						$this->state = self::BODY_RECEIVED;
					}
				}
				break;

			case self::HEADERS_RECEIVED:
				// receiving a response body
				if ($this->receiveBody())
				{
					// have read all the body
					$this->socket->close();

					if ($this->debugLevel & WebHttpDebug::RESPONSE_BODY)
					{
						$this->log($this->response->getBody(), WebHttpDebug::RESPONSE_BODY);
					}

					// need to ajust the response headers (PSR-18)
					$this->response->adjustHeaders();

					// we have a result!
					$promise->fulfill($this->response);

					$this->state = self::BODY_RECEIVED;
				}
				break;
		}
	}
	catch (HttpClientException $exception)
	{
		$this->socket->close();

		$promise->reject($exception);

		if ($logger = $this->getLogger())
		{
			$logger->error($exception->getMessage());
		}
	}
}