- Модуль: 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());
}
}
}