vendor/symfony/http-client/Response/TraceableResponse.php line 121

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\HttpClient\Response;
  11. use Symfony\Component\HttpClient\Chunk\ErrorChunk;
  12. use Symfony\Component\HttpClient\Exception\ClientException;
  13. use Symfony\Component\HttpClient\Exception\RedirectionException;
  14. use Symfony\Component\HttpClient\Exception\ServerException;
  15. use Symfony\Component\HttpClient\TraceableHttpClient;
  16. use Symfony\Component\Stopwatch\StopwatchEvent;
  17. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  18. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  19. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  20. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  21. use Symfony\Contracts\HttpClient\HttpClientInterface;
  22. use Symfony\Contracts\HttpClient\ResponseInterface;
  23. /**
  24.  * @author Nicolas Grekas <p@tchwork.com>
  25.  *
  26.  * @internal
  27.  */
  28. class TraceableResponse implements ResponseInterfaceStreamableInterface
  29. {
  30.     private $client;
  31.     private $response;
  32.     private $content;
  33.     private $event;
  34.     public function __construct(HttpClientInterface $clientResponseInterface $response, &$contentStopwatchEvent $event null)
  35.     {
  36.         $this->client $client;
  37.         $this->response $response;
  38.         $this->content = &$content;
  39.         $this->event $event;
  40.     }
  41.     public function __sleep(): array
  42.     {
  43.         throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
  44.     }
  45.     public function __wakeup()
  46.     {
  47.         throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
  48.     }
  49.     public function __destruct()
  50.     {
  51.         try {
  52.             $this->response->__destruct();
  53.         } finally {
  54.             if ($this->event && $this->event->isStarted()) {
  55.                 $this->event->stop();
  56.             }
  57.         }
  58.     }
  59.     public function getStatusCode(): int
  60.     {
  61.         try {
  62.             return $this->response->getStatusCode();
  63.         } finally {
  64.             if ($this->event && $this->event->isStarted()) {
  65.                 $this->event->lap();
  66.             }
  67.         }
  68.     }
  69.     public function getHeaders(bool $throw true): array
  70.     {
  71.         try {
  72.             return $this->response->getHeaders($throw);
  73.         } finally {
  74.             if ($this->event && $this->event->isStarted()) {
  75.                 $this->event->lap();
  76.             }
  77.         }
  78.     }
  79.     public function getContent(bool $throw true): string
  80.     {
  81.         try {
  82.             if (false === $this->content) {
  83.                 return $this->response->getContent($throw);
  84.             }
  85.             return $this->content $this->response->getContent(false);
  86.         } finally {
  87.             if ($this->event && $this->event->isStarted()) {
  88.                 $this->event->stop();
  89.             }
  90.             if ($throw) {
  91.                 $this->checkStatusCode($this->response->getStatusCode());
  92.             }
  93.         }
  94.     }
  95.     public function toArray(bool $throw true): array
  96.     {
  97.         try {
  98.             if (false === $this->content) {
  99.                 return $this->response->toArray($throw);
  100.             }
  101.             return $this->content $this->response->toArray(false);
  102.         } finally {
  103.             if ($this->event && $this->event->isStarted()) {
  104.                 $this->event->stop();
  105.             }
  106.             if ($throw) {
  107.                 $this->checkStatusCode($this->response->getStatusCode());
  108.             }
  109.         }
  110.     }
  111.     public function cancel(): void
  112.     {
  113.         $this->response->cancel();
  114.         if ($this->event && $this->event->isStarted()) {
  115.             $this->event->stop();
  116.         }
  117.     }
  118.     public function getInfo(string $type null)
  119.     {
  120.         return $this->response->getInfo($type);
  121.     }
  122.     /**
  123.      * Casts the response to a PHP stream resource.
  124.      *
  125.      * @return resource
  126.      *
  127.      * @throws TransportExceptionInterface   When a network error occurs
  128.      * @throws RedirectionExceptionInterface On a 3xx when $throw is true and the "max_redirects" option has been reached
  129.      * @throws ClientExceptionInterface      On a 4xx when $throw is true
  130.      * @throws ServerExceptionInterface      On a 5xx when $throw is true
  131.      */
  132.     public function toStream(bool $throw true)
  133.     {
  134.         if ($throw) {
  135.             // Ensure headers arrived
  136.             $this->response->getHeaders(true);
  137.         }
  138.         if ($this->response instanceof StreamableInterface) {
  139.             return $this->response->toStream(false);
  140.         }
  141.         return StreamWrapper::createResource($this->response$this->client);
  142.     }
  143.     /**
  144.      * @internal
  145.      */
  146.     public static function stream(HttpClientInterface $clientiterable $responses, ?float $timeout): \Generator
  147.     {
  148.         $wrappedResponses = [];
  149.         $traceableMap = new \SplObjectStorage();
  150.         foreach ($responses as $r) {
  151.             if (!$r instanceof self) {
  152.                 throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.'TraceableHttpClient::class, get_debug_type($r)));
  153.             }
  154.             $traceableMap[$r->response] = $r;
  155.             $wrappedResponses[] = $r->response;
  156.             if ($r->event && !$r->event->isStarted()) {
  157.                 $r->event->start();
  158.             }
  159.         }
  160.         foreach ($client->stream($wrappedResponses$timeout) as $r => $chunk) {
  161.             if ($traceableMap[$r]->event && $traceableMap[$r]->event->isStarted()) {
  162.                 try {
  163.                     if ($chunk->isTimeout() || !$chunk->isLast()) {
  164.                         $traceableMap[$r]->event->lap();
  165.                     } else {
  166.                         $traceableMap[$r]->event->stop();
  167.                     }
  168.                 } catch (TransportExceptionInterface $e) {
  169.                     $traceableMap[$r]->event->stop();
  170.                     if ($chunk instanceof ErrorChunk) {
  171.                         $chunk->didThrow(false);
  172.                     } else {
  173.                         $chunk = new ErrorChunk($chunk->getOffset(), $e);
  174.                     }
  175.                 }
  176.             }
  177.             yield $traceableMap[$r] => $chunk;
  178.         }
  179.     }
  180.     private function checkStatusCode(int $code)
  181.     {
  182.         if (500 <= $code) {
  183.             throw new ServerException($this);
  184.         }
  185.         if (400 <= $code) {
  186.             throw new ClientException($this);
  187.         }
  188.         if (300 <= $code) {
  189.             throw new RedirectionException($this);
  190.         }
  191.     }
  192. }