[ Index ]

PHP Cross Reference of phpBB-3.3.2-deutsch

title

Body

[close]

/vendor/guzzlehttp/guzzle/src/ -> Client.php (source)

   1  <?php
   2  namespace GuzzleHttp;
   3  
   4  use GuzzleHttp\Cookie\CookieJar;
   5  use GuzzleHttp\Exception\GuzzleException;
   6  use GuzzleHttp\Promise;
   7  use GuzzleHttp\Psr7;
   8  use Psr\Http\Message\RequestInterface;
   9  use Psr\Http\Message\ResponseInterface;
  10  use Psr\Http\Message\UriInterface;
  11  
  12  /**
  13   * @method ResponseInterface get(string|UriInterface $uri, array $options = [])
  14   * @method ResponseInterface head(string|UriInterface $uri, array $options = [])
  15   * @method ResponseInterface put(string|UriInterface $uri, array $options = [])
  16   * @method ResponseInterface post(string|UriInterface $uri, array $options = [])
  17   * @method ResponseInterface patch(string|UriInterface $uri, array $options = [])
  18   * @method ResponseInterface delete(string|UriInterface $uri, array $options = [])
  19   * @method Promise\PromiseInterface getAsync(string|UriInterface $uri, array $options = [])
  20   * @method Promise\PromiseInterface headAsync(string|UriInterface $uri, array $options = [])
  21   * @method Promise\PromiseInterface putAsync(string|UriInterface $uri, array $options = [])
  22   * @method Promise\PromiseInterface postAsync(string|UriInterface $uri, array $options = [])
  23   * @method Promise\PromiseInterface patchAsync(string|UriInterface $uri, array $options = [])
  24   * @method Promise\PromiseInterface deleteAsync(string|UriInterface $uri, array $options = [])
  25   */
  26  class Client implements ClientInterface
  27  {
  28      /** @var array Default request options */
  29      private $config;
  30  
  31      /**
  32       * Clients accept an array of constructor parameters.
  33       *
  34       * Here's an example of creating a client using a base_uri and an array of
  35       * default request options to apply to each request:
  36       *
  37       *     $client = new Client([
  38       *         'base_uri'        => 'http://www.foo.com/1.0/',
  39       *         'timeout'         => 0,
  40       *         'allow_redirects' => false,
  41       *         'proxy'           => '192.168.16.1:10'
  42       *     ]);
  43       *
  44       * Client configuration settings include the following options:
  45       *
  46       * - handler: (callable) Function that transfers HTTP requests over the
  47       *   wire. The function is called with a Psr7\Http\Message\RequestInterface
  48       *   and array of transfer options, and must return a
  49       *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
  50       *   Psr7\Http\Message\ResponseInterface on success.
  51       *   If no handler is provided, a default handler will be created
  52       *   that enables all of the request options below by attaching all of the
  53       *   default middleware to the handler.
  54       * - base_uri: (string|UriInterface) Base URI of the client that is merged
  55       *   into relative URIs. Can be a string or instance of UriInterface.
  56       * - **: any request option
  57       *
  58       * @param array $config Client configuration settings.
  59       *
  60       * @see \GuzzleHttp\RequestOptions for a list of available request options.
  61       */
  62      public function __construct(array $config = [])
  63      {
  64          if (!isset($config['handler'])) {
  65              $config['handler'] = HandlerStack::create();
  66          } elseif (!is_callable($config['handler'])) {
  67              throw new \InvalidArgumentException('handler must be a callable');
  68          }
  69  
  70          // Convert the base_uri to a UriInterface
  71          if (isset($config['base_uri'])) {
  72              $config['base_uri'] = Psr7\uri_for($config['base_uri']);
  73          }
  74  
  75          $this->configureDefaults($config);
  76      }
  77  
  78      /**
  79       * @param string $method
  80       * @param array  $args
  81       *
  82       * @return Promise\PromiseInterface
  83       */
  84      public function __call($method, $args)
  85      {
  86          if (count($args) < 1) {
  87              throw new \InvalidArgumentException('Magic request methods require a URI and optional options array');
  88          }
  89  
  90          $uri = $args[0];
  91          $opts = isset($args[1]) ? $args[1] : [];
  92  
  93          return substr($method, -5) === 'Async'
  94              ? $this->requestAsync(substr($method, 0, -5), $uri, $opts)
  95              : $this->request($method, $uri, $opts);
  96      }
  97  
  98      /**
  99       * Asynchronously send an HTTP request.
 100       *
 101       * @param array $options Request options to apply to the given
 102       *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
 103       *
 104       * @return Promise\PromiseInterface
 105       */
 106      public function sendAsync(RequestInterface $request, array $options = [])
 107      {
 108          // Merge the base URI into the request URI if needed.
 109          $options = $this->prepareDefaults($options);
 110  
 111          return $this->transfer(
 112              $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
 113              $options
 114          );
 115      }
 116  
 117      /**
 118       * Send an HTTP request.
 119       *
 120       * @param array $options Request options to apply to the given
 121       *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
 122       *
 123       * @return ResponseInterface
 124       * @throws GuzzleException
 125       */
 126      public function send(RequestInterface $request, array $options = [])
 127      {
 128          $options[RequestOptions::SYNCHRONOUS] = true;
 129          return $this->sendAsync($request, $options)->wait();
 130      }
 131  
 132      /**
 133       * Create and send an asynchronous HTTP request.
 134       *
 135       * Use an absolute path to override the base path of the client, or a
 136       * relative path to append to the base path of the client. The URL can
 137       * contain the query string as well. Use an array to provide a URL
 138       * template and additional variables to use in the URL template expansion.
 139       *
 140       * @param string              $method  HTTP method
 141       * @param string|UriInterface $uri     URI object or string.
 142       * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
 143       *
 144       * @return Promise\PromiseInterface
 145       */
 146      public function requestAsync($method, $uri = '', array $options = [])
 147      {
 148          $options = $this->prepareDefaults($options);
 149          // Remove request modifying parameter because it can be done up-front.
 150          $headers = isset($options['headers']) ? $options['headers'] : [];
 151          $body = isset($options['body']) ? $options['body'] : null;
 152          $version = isset($options['version']) ? $options['version'] : '1.1';
 153          // Merge the URI into the base URI.
 154          $uri = $this->buildUri($uri, $options);
 155          if (is_array($body)) {
 156              $this->invalidBody();
 157          }
 158          $request = new Psr7\Request($method, $uri, $headers, $body, $version);
 159          // Remove the option so that they are not doubly-applied.
 160          unset($options['headers'], $options['body'], $options['version']);
 161  
 162          return $this->transfer($request, $options);
 163      }
 164  
 165      /**
 166       * Create and send an HTTP request.
 167       *
 168       * Use an absolute path to override the base path of the client, or a
 169       * relative path to append to the base path of the client. The URL can
 170       * contain the query string as well.
 171       *
 172       * @param string              $method  HTTP method.
 173       * @param string|UriInterface $uri     URI object or string.
 174       * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
 175       *
 176       * @return ResponseInterface
 177       * @throws GuzzleException
 178       */
 179      public function request($method, $uri = '', array $options = [])
 180      {
 181          $options[RequestOptions::SYNCHRONOUS] = true;
 182          return $this->requestAsync($method, $uri, $options)->wait();
 183      }
 184  
 185      /**
 186       * Get a client configuration option.
 187       *
 188       * These options include default request options of the client, a "handler"
 189       * (if utilized by the concrete client), and a "base_uri" if utilized by
 190       * the concrete client.
 191       *
 192       * @param string|null $option The config option to retrieve.
 193       *
 194       * @return mixed
 195       */
 196      public function getConfig($option = null)
 197      {
 198          return $option === null
 199              ? $this->config
 200              : (isset($this->config[$option]) ? $this->config[$option] : null);
 201      }
 202  
 203      /**
 204       * @param  string|null $uri
 205       *
 206       * @return UriInterface
 207       */
 208      private function buildUri($uri, array $config)
 209      {
 210          // for BC we accept null which would otherwise fail in uri_for
 211          $uri = Psr7\uri_for($uri === null ? '' : $uri);
 212  
 213          if (isset($config['base_uri'])) {
 214              $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri);
 215          }
 216  
 217          if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
 218              $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion'];
 219              $uri = Utils::idnUriConvert($uri, $idnOptions);
 220          }
 221  
 222          return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
 223      }
 224  
 225      /**
 226       * Configures the default options for a client.
 227       *
 228       * @param array $config
 229       * @return void
 230       */
 231      private function configureDefaults(array $config)
 232      {
 233          $defaults = [
 234              'allow_redirects' => RedirectMiddleware::$defaultSettings,
 235              'http_errors'     => true,
 236              'decode_content'  => true,
 237              'verify'          => true,
 238              'cookies'         => false,
 239              'idn_conversion'  => true,
 240          ];
 241  
 242          // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
 243  
 244          // We can only trust the HTTP_PROXY environment variable in a CLI
 245          // process due to the fact that PHP has no reliable mechanism to
 246          // get environment variables that start with "HTTP_".
 247          if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) {
 248              $defaults['proxy']['http'] = getenv('HTTP_PROXY');
 249          }
 250  
 251          if ($proxy = getenv('HTTPS_PROXY')) {
 252              $defaults['proxy']['https'] = $proxy;
 253          }
 254  
 255          if ($noProxy = getenv('NO_PROXY')) {
 256              $cleanedNoProxy = str_replace(' ', '', $noProxy);
 257              $defaults['proxy']['no'] = explode(',', $cleanedNoProxy);
 258          }
 259  
 260          $this->config = $config + $defaults;
 261  
 262          if (!empty($config['cookies']) && $config['cookies'] === true) {
 263              $this->config['cookies'] = new CookieJar();
 264          }
 265  
 266          // Add the default user-agent header.
 267          if (!isset($this->config['headers'])) {
 268              $this->config['headers'] = ['User-Agent' => default_user_agent()];
 269          } else {
 270              // Add the User-Agent header if one was not already set.
 271              foreach (array_keys($this->config['headers']) as $name) {
 272                  if (strtolower($name) === 'user-agent') {
 273                      return;
 274                  }
 275              }
 276              $this->config['headers']['User-Agent'] = default_user_agent();
 277          }
 278      }
 279  
 280      /**
 281       * Merges default options into the array.
 282       *
 283       * @param array $options Options to modify by reference
 284       *
 285       * @return array
 286       */
 287      private function prepareDefaults(array $options)
 288      {
 289          $defaults = $this->config;
 290  
 291          if (!empty($defaults['headers'])) {
 292              // Default headers are only added if they are not present.
 293              $defaults['_conditional'] = $defaults['headers'];
 294              unset($defaults['headers']);
 295          }
 296  
 297          // Special handling for headers is required as they are added as
 298          // conditional headers and as headers passed to a request ctor.
 299          if (array_key_exists('headers', $options)) {
 300              // Allows default headers to be unset.
 301              if ($options['headers'] === null) {
 302                  $defaults['_conditional'] = [];
 303                  unset($options['headers']);
 304              } elseif (!is_array($options['headers'])) {
 305                  throw new \InvalidArgumentException('headers must be an array');
 306              }
 307          }
 308  
 309          // Shallow merge defaults underneath options.
 310          $result = $options + $defaults;
 311  
 312          // Remove null values.
 313          foreach ($result as $k => $v) {
 314              if ($v === null) {
 315                  unset($result[$k]);
 316              }
 317          }
 318  
 319          return $result;
 320      }
 321  
 322      /**
 323       * Transfers the given request and applies request options.
 324       *
 325       * The URI of the request is not modified and the request options are used
 326       * as-is without merging in default options.
 327       *
 328       * @param array $options See \GuzzleHttp\RequestOptions.
 329       *
 330       * @return Promise\PromiseInterface
 331       */
 332      private function transfer(RequestInterface $request, array $options)
 333      {
 334          // save_to -> sink
 335          if (isset($options['save_to'])) {
 336              $options['sink'] = $options['save_to'];
 337              unset($options['save_to']);
 338          }
 339  
 340          // exceptions -> http_errors
 341          if (isset($options['exceptions'])) {
 342              $options['http_errors'] = $options['exceptions'];
 343              unset($options['exceptions']);
 344          }
 345  
 346          $request = $this->applyOptions($request, $options);
 347          /** @var HandlerStack $handler */
 348          $handler = $options['handler'];
 349  
 350          try {
 351              return Promise\promise_for($handler($request, $options));
 352          } catch (\Exception $e) {
 353              return Promise\rejection_for($e);
 354          }
 355      }
 356  
 357      /**
 358       * Applies the array of request options to a request.
 359       *
 360       * @param RequestInterface $request
 361       * @param array            $options
 362       *
 363       * @return RequestInterface
 364       */
 365      private function applyOptions(RequestInterface $request, array &$options)
 366      {
 367          $modify = [
 368              'set_headers' => [],
 369          ];
 370  
 371          if (isset($options['headers'])) {
 372              $modify['set_headers'] = $options['headers'];
 373              unset($options['headers']);
 374          }
 375  
 376          if (isset($options['form_params'])) {
 377              if (isset($options['multipart'])) {
 378                  throw new \InvalidArgumentException('You cannot use '
 379                      . 'form_params and multipart at the same time. Use the '
 380                      . 'form_params option if you want to send application/'
 381                      . 'x-www-form-urlencoded requests, and the multipart '
 382                      . 'option to send multipart/form-data requests.');
 383              }
 384              $options['body'] = http_build_query($options['form_params'], '', '&');
 385              unset($options['form_params']);
 386              // Ensure that we don't have the header in different case and set the new value.
 387              $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
 388              $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
 389          }
 390  
 391          if (isset($options['multipart'])) {
 392              $options['body'] = new Psr7\MultipartStream($options['multipart']);
 393              unset($options['multipart']);
 394          }
 395  
 396          if (isset($options['json'])) {
 397              $options['body'] = \GuzzleHttp\json_encode($options['json']);
 398              unset($options['json']);
 399              // Ensure that we don't have the header in different case and set the new value.
 400              $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
 401              $options['_conditional']['Content-Type'] = 'application/json';
 402          }
 403  
 404          if (!empty($options['decode_content'])
 405              && $options['decode_content'] !== true
 406          ) {
 407              // Ensure that we don't have the header in different case and set the new value.
 408              $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']);
 409              $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
 410          }
 411  
 412          if (isset($options['body'])) {
 413              if (is_array($options['body'])) {
 414                  $this->invalidBody();
 415              }
 416              $modify['body'] = Psr7\stream_for($options['body']);
 417              unset($options['body']);
 418          }
 419  
 420          if (!empty($options['auth']) && is_array($options['auth'])) {
 421              $value = $options['auth'];
 422              $type = isset($value[2]) ? strtolower($value[2]) : 'basic';
 423              switch ($type) {
 424                  case 'basic':
 425                      // Ensure that we don't have the header in different case and set the new value.
 426                      $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']);
 427                      $modify['set_headers']['Authorization'] = 'Basic '
 428                          . base64_encode("$value[0]:$value[1]");
 429                      break;
 430                  case 'digest':
 431                      // @todo: Do not rely on curl
 432                      $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST;
 433                      $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
 434                      break;
 435                  case 'ntlm':
 436                      $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM;
 437                      $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]";
 438                      break;
 439              }
 440          }
 441  
 442          if (isset($options['query'])) {
 443              $value = $options['query'];
 444              if (is_array($value)) {
 445                  $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986);
 446              }
 447              if (!is_string($value)) {
 448                  throw new \InvalidArgumentException('query must be a string or array');
 449              }
 450              $modify['query'] = $value;
 451              unset($options['query']);
 452          }
 453  
 454          // Ensure that sink is not an invalid value.
 455          if (isset($options['sink'])) {
 456              // TODO: Add more sink validation?
 457              if (is_bool($options['sink'])) {
 458                  throw new \InvalidArgumentException('sink must not be a boolean');
 459              }
 460          }
 461  
 462          $request = Psr7\modify_request($request, $modify);
 463          if ($request->getBody() instanceof Psr7\MultipartStream) {
 464              // Use a multipart/form-data POST if a Content-Type is not set.
 465              // Ensure that we don't have the header in different case and set the new value.
 466              $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']);
 467              $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
 468                  . $request->getBody()->getBoundary();
 469          }
 470  
 471          // Merge in conditional headers if they are not present.
 472          if (isset($options['_conditional'])) {
 473              // Build up the changes so it's in a single clone of the message.
 474              $modify = [];
 475              foreach ($options['_conditional'] as $k => $v) {
 476                  if (!$request->hasHeader($k)) {
 477                      $modify['set_headers'][$k] = $v;
 478                  }
 479              }
 480              $request = Psr7\modify_request($request, $modify);
 481              // Don't pass this internal value along to middleware/handlers.
 482              unset($options['_conditional']);
 483          }
 484  
 485          return $request;
 486      }
 487  
 488      /**
 489       * Throw Exception with pre-set message.
 490       * @return void
 491       * @throws \InvalidArgumentException Invalid body.
 492       */
 493      private function invalidBody()
 494      {
 495          throw new \InvalidArgumentException('Passing in the "body" request '
 496              . 'option as an array to send a POST request has been deprecated. '
 497              . 'Please use the "form_params" request option to send a '
 498              . 'application/x-www-form-urlencoded request, or the "multipart" '
 499              . 'request option to send a multipart/form-data request.');
 500      }
 501  }


Generated: Wed Nov 11 20:28:18 2020 Cross-referenced by PHPXref 0.7.1