/server/wordpress/wp-content/plugins/wordpress-seo/vendor_prefixed/guzzlehttp/guzzle/src/RedirectMiddleware.php
https://gitlab.com/suporte.spturis/carnaval2015.spturis.com.br · PHP · 177 lines · 110 code · 2 blank · 65 comment · 21 complexity · 72128f259c0faf324c800b43d27370a1 MD5 · raw file
- <?php
- namespace YoastSEO_Vendor\GuzzleHttp;
- use YoastSEO_Vendor\GuzzleHttp\Exception\BadResponseException;
- use YoastSEO_Vendor\GuzzleHttp\Exception\TooManyRedirectsException;
- use YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
- use YoastSEO_Vendor\GuzzleHttp\Psr7;
- use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
- use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
- use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
- /**
- * Request redirect middleware.
- *
- * Apply this middleware like other middleware using
- * {@see \GuzzleHttp\Middleware::redirect()}.
- */
- class RedirectMiddleware
- {
- const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
- const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
- public static $defaultSettings = ['max' => 5, 'protocols' => ['http', 'https'], 'strict' => \false, 'referer' => \false, 'track_redirects' => \false];
- /** @var callable */
- private $nextHandler;
- /**
- * @param callable $nextHandler Next handler to invoke.
- */
- public function __construct(callable $nextHandler)
- {
- $this->nextHandler = $nextHandler;
- }
- /**
- * @param RequestInterface $request
- * @param array $options
- *
- * @return PromiseInterface
- */
- public function __invoke(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options)
- {
- $fn = $this->nextHandler;
- if (empty($options['allow_redirects'])) {
- return $fn($request, $options);
- }
- if ($options['allow_redirects'] === \true) {
- $options['allow_redirects'] = self::$defaultSettings;
- } elseif (!\is_array($options['allow_redirects'])) {
- throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
- } else {
- // Merge the default settings with the provided settings
- $options['allow_redirects'] += self::$defaultSettings;
- }
- if (empty($options['allow_redirects']['max'])) {
- return $fn($request, $options);
- }
- return $fn($request, $options)->then(function (\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response) use($request, $options) {
- return $this->checkRedirect($request, $options, $response);
- });
- }
- /**
- * @param RequestInterface $request
- * @param array $options
- * @param ResponseInterface $response
- *
- * @return ResponseInterface|PromiseInterface
- */
- public function checkRedirect(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response)
- {
- if (\substr($response->getStatusCode(), 0, 1) != '3' || !$response->hasHeader('Location')) {
- return $response;
- }
- $this->guardMax($request, $options);
- $nextRequest = $this->modifyRequest($request, $options, $response);
- if (isset($options['allow_redirects']['on_redirect'])) {
- \call_user_func($options['allow_redirects']['on_redirect'], $request, $response, $nextRequest->getUri());
- }
- /** @var PromiseInterface|ResponseInterface $promise */
- $promise = $this($nextRequest, $options);
- // Add headers to be able to track history of redirects.
- if (!empty($options['allow_redirects']['track_redirects'])) {
- return $this->withTracking($promise, (string) $nextRequest->getUri(), $response->getStatusCode());
- }
- return $promise;
- }
- /**
- * Enable tracking on promise.
- *
- * @return PromiseInterface
- */
- private function withTracking(\YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $promise, $uri, $statusCode)
- {
- return $promise->then(function (\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response) use($uri, $statusCode) {
- // Note that we are pushing to the front of the list as this
- // would be an earlier response than what is currently present
- // in the history header.
- $historyHeader = $response->getHeader(self::HISTORY_HEADER);
- $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
- \array_unshift($historyHeader, $uri);
- \array_unshift($statusHeader, $statusCode);
- return $response->withHeader(self::HISTORY_HEADER, $historyHeader)->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
- });
- }
- /**
- * Check for too many redirects
- *
- * @return void
- *
- * @throws TooManyRedirectsException Too many redirects.
- */
- private function guardMax(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array &$options)
- {
- $current = isset($options['__redirect_count']) ? $options['__redirect_count'] : 0;
- $options['__redirect_count'] = $current + 1;
- $max = $options['allow_redirects']['max'];
- if ($options['__redirect_count'] > $max) {
- throw new \YoastSEO_Vendor\GuzzleHttp\Exception\TooManyRedirectsException("Will not follow more than {$max} redirects", $request);
- }
- }
- /**
- * @param RequestInterface $request
- * @param array $options
- * @param ResponseInterface $response
- *
- * @return RequestInterface
- */
- public function modifyRequest(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response)
- {
- // Request modifications to apply.
- $modify = [];
- $protocols = $options['allow_redirects']['protocols'];
- // Use a GET request if this is an entity enclosing request and we are
- // not forcing RFC compliance, but rather emulating what all browsers
- // would do.
- $statusCode = $response->getStatusCode();
- if ($statusCode == 303 || $statusCode <= 302 && !$options['allow_redirects']['strict']) {
- $modify['method'] = 'GET';
- $modify['body'] = '';
- }
- $uri = $this->redirectUri($request, $response, $protocols);
- if (isset($options['idn_conversion']) && $options['idn_conversion'] !== \false) {
- $idnOptions = $options['idn_conversion'] === \true ? \IDNA_DEFAULT : $options['idn_conversion'];
- $uri = _idn_uri_convert($uri, $idnOptions);
- }
- $modify['uri'] = $uri;
- \YoastSEO_Vendor\GuzzleHttp\Psr7\rewind_body($request);
- // Add the Referer header if it is told to do so and only
- // add the header if we are not redirecting from https to http.
- if ($options['allow_redirects']['referer'] && $modify['uri']->getScheme() === $request->getUri()->getScheme()) {
- $uri = $request->getUri()->withUserInfo('');
- $modify['set_headers']['Referer'] = (string) $uri;
- } else {
- $modify['remove_headers'][] = 'Referer';
- }
- // Remove Authorization header if host is different.
- if ($request->getUri()->getHost() !== $modify['uri']->getHost()) {
- $modify['remove_headers'][] = 'Authorization';
- }
- return \YoastSEO_Vendor\GuzzleHttp\Psr7\modify_request($request, $modify);
- }
- /**
- * Set the appropriate URL on the request based on the location header
- *
- * @param RequestInterface $request
- * @param ResponseInterface $response
- * @param array $protocols
- *
- * @return UriInterface
- */
- private function redirectUri(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, array $protocols)
- {
- $location = \YoastSEO_Vendor\GuzzleHttp\Psr7\UriResolver::resolve($request->getUri(), new \YoastSEO_Vendor\GuzzleHttp\Psr7\Uri($response->getHeaderLine('Location')));
- // Ensure that the redirect URI is allowed based on the protocols.
- if (!\in_array($location->getScheme(), $protocols)) {
- throw new \YoastSEO_Vendor\GuzzleHttp\Exception\BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response);
- }
- return $location;
- }
- }