[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/SimplePie/src/HTTP/ -> Psr18Client.php (source)

   1  <?php
   2  
   3  // SPDX-FileCopyrightText: 2004-2023 Ryan Parman, Sam Sneddon, Ryan McCue
   4  // SPDX-License-Identifier: BSD-3-Clause
   5  
   6  declare(strict_types=1);
   7  
   8  namespace SimplePie\HTTP;
   9  
  10  use InvalidArgumentException;
  11  use Psr\Http\Client\ClientExceptionInterface;
  12  use Psr\Http\Client\ClientInterface;
  13  use Psr\Http\Message\RequestFactoryInterface;
  14  use Psr\Http\Message\UriFactoryInterface;
  15  use Throwable;
  16  
  17  /**
  18   * HTTP Client based on PSR-18 and PSR-17 implementations
  19   *
  20   * @internal
  21   */
  22  final class Psr18Client implements Client
  23  {
  24      /**
  25       * @var ClientInterface
  26       */
  27      private $httpClient;
  28  
  29      /**
  30       * @var RequestFactoryInterface
  31       */
  32      private $requestFactory;
  33  
  34      /**
  35       * @var UriFactoryInterface
  36       */
  37      private $uriFactory;
  38  
  39      /**
  40       * @var int
  41       */
  42      private $allowedRedirects = 5;
  43  
  44      public function __construct(ClientInterface $httpClient, RequestFactoryInterface $requestFactory, UriFactoryInterface $uriFactory)
  45      {
  46          $this->httpClient = $httpClient;
  47          $this->requestFactory = $requestFactory;
  48          $this->uriFactory = $uriFactory;
  49      }
  50  
  51      public function getHttpClient(): ClientInterface
  52      {
  53          return $this->httpClient;
  54      }
  55  
  56      public function getRequestFactory(): RequestFactoryInterface
  57      {
  58          return $this->requestFactory;
  59      }
  60  
  61      public function getUriFactory(): UriFactoryInterface
  62      {
  63          return $this->uriFactory;
  64      }
  65  
  66      /**
  67       * send a request and return the response
  68       *
  69       * @param Client::METHOD_* $method
  70       * @param string $url
  71       * @param array<string,string|string[]> $headers
  72       *
  73       * @throws ClientException if anything goes wrong requesting the data
  74       */
  75      public function request(string $method, string $url, array $headers = []): Response
  76      {
  77          if ($method !== self::METHOD_GET) {
  78              throw new InvalidArgumentException(sprintf(
  79                  '%s(): Argument #1 ($method) only supports method "%s".',
  80                  __METHOD__,
  81                  self::METHOD_GET
  82              ), 1);
  83          }
  84  
  85          if (preg_match('/^http(s)?:\/\//i', $url)) {
  86              return $this->requestUrl($method, $url, $headers);
  87          }
  88  
  89          return $this->requestLocalFile($url);
  90      }
  91  
  92      /**
  93       * @param array<string,string|string[]> $headers
  94       */
  95      private function requestUrl(string $method, string $url, array $headers): Response
  96      {
  97          $permanentUrl = $url;
  98          $requestedUrl = $url;
  99          $remainingRedirects = $this->allowedRedirects;
 100  
 101          $request = $this->requestFactory->createRequest(
 102              $method,
 103              $this->uriFactory->createUri($requestedUrl)
 104          );
 105  
 106          foreach ($headers as $name => $value) {
 107              $request = $request->withHeader($name, $value);
 108          }
 109  
 110          do {
 111              $followRedirect = false;
 112  
 113              try {
 114                  $response = $this->httpClient->sendRequest($request);
 115              } catch (ClientExceptionInterface $th) {
 116                  throw new ClientException($th->getMessage(), $th->getCode(), $th);
 117              }
 118  
 119              $statusCode = $response->getStatusCode();
 120  
 121              // If we have a redirect
 122              if (in_array($statusCode, [300, 301, 302, 303, 307]) && $response->hasHeader('Location')) {
 123                  // Prevent infinity redirect loops
 124                  if ($remainingRedirects <= 0) {
 125                      break;
 126                  }
 127  
 128                  $remainingRedirects--;
 129                  $followRedirect = true;
 130  
 131                  $requestedUrl = $response->getHeaderLine('Location');
 132  
 133                  if ($statusCode === 301) {
 134                      $permanentUrl = $requestedUrl;
 135                  }
 136  
 137                  $request = $request->withUri($this->uriFactory->createUri($requestedUrl));
 138              }
 139          } while ($followRedirect);
 140  
 141          return new Psr7Response($response, $permanentUrl, $requestedUrl);
 142      }
 143  
 144      private function requestLocalFile(string $path): Response
 145      {
 146          if (!is_readable($path)) {
 147              throw new ClientException(sprintf('file "%s" is not readable', $path));
 148          }
 149  
 150          try {
 151              $raw = file_get_contents($path);
 152          } catch (Throwable $th) {
 153              throw new ClientException($th->getMessage(), $th->getCode(), $th);
 154          }
 155  
 156          if ($raw === false) {
 157              throw new ClientException('file_get_contents() could not read the file', 1);
 158          }
 159  
 160          return new RawTextResponse($raw, $path);
 161      }
 162  }


Generated : Wed Sep 17 08:20:04 2025 Cross-referenced by PHPXref