PageRenderTime 26ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. <?php
  2. namespace YoastSEO_Vendor\GuzzleHttp;
  3. use YoastSEO_Vendor\GuzzleHttp\Exception\BadResponseException;
  4. use YoastSEO_Vendor\GuzzleHttp\Exception\TooManyRedirectsException;
  5. use YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface;
  6. use YoastSEO_Vendor\GuzzleHttp\Psr7;
  7. use YoastSEO_Vendor\Psr\Http\Message\RequestInterface;
  8. use YoastSEO_Vendor\Psr\Http\Message\ResponseInterface;
  9. use YoastSEO_Vendor\Psr\Http\Message\UriInterface;
  10. /**
  11. * Request redirect middleware.
  12. *
  13. * Apply this middleware like other middleware using
  14. * {@see \GuzzleHttp\Middleware::redirect()}.
  15. */
  16. class RedirectMiddleware
  17. {
  18. const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
  19. const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
  20. public static $defaultSettings = ['max' => 5, 'protocols' => ['http', 'https'], 'strict' => \false, 'referer' => \false, 'track_redirects' => \false];
  21. /** @var callable */
  22. private $nextHandler;
  23. /**
  24. * @param callable $nextHandler Next handler to invoke.
  25. */
  26. public function __construct(callable $nextHandler)
  27. {
  28. $this->nextHandler = $nextHandler;
  29. }
  30. /**
  31. * @param RequestInterface $request
  32. * @param array $options
  33. *
  34. * @return PromiseInterface
  35. */
  36. public function __invoke(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options)
  37. {
  38. $fn = $this->nextHandler;
  39. if (empty($options['allow_redirects'])) {
  40. return $fn($request, $options);
  41. }
  42. if ($options['allow_redirects'] === \true) {
  43. $options['allow_redirects'] = self::$defaultSettings;
  44. } elseif (!\is_array($options['allow_redirects'])) {
  45. throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
  46. } else {
  47. // Merge the default settings with the provided settings
  48. $options['allow_redirects'] += self::$defaultSettings;
  49. }
  50. if (empty($options['allow_redirects']['max'])) {
  51. return $fn($request, $options);
  52. }
  53. return $fn($request, $options)->then(function (\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response) use($request, $options) {
  54. return $this->checkRedirect($request, $options, $response);
  55. });
  56. }
  57. /**
  58. * @param RequestInterface $request
  59. * @param array $options
  60. * @param ResponseInterface $response
  61. *
  62. * @return ResponseInterface|PromiseInterface
  63. */
  64. public function checkRedirect(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response)
  65. {
  66. if (\substr($response->getStatusCode(), 0, 1) != '3' || !$response->hasHeader('Location')) {
  67. return $response;
  68. }
  69. $this->guardMax($request, $options);
  70. $nextRequest = $this->modifyRequest($request, $options, $response);
  71. if (isset($options['allow_redirects']['on_redirect'])) {
  72. \call_user_func($options['allow_redirects']['on_redirect'], $request, $response, $nextRequest->getUri());
  73. }
  74. /** @var PromiseInterface|ResponseInterface $promise */
  75. $promise = $this($nextRequest, $options);
  76. // Add headers to be able to track history of redirects.
  77. if (!empty($options['allow_redirects']['track_redirects'])) {
  78. return $this->withTracking($promise, (string) $nextRequest->getUri(), $response->getStatusCode());
  79. }
  80. return $promise;
  81. }
  82. /**
  83. * Enable tracking on promise.
  84. *
  85. * @return PromiseInterface
  86. */
  87. private function withTracking(\YoastSEO_Vendor\GuzzleHttp\Promise\PromiseInterface $promise, $uri, $statusCode)
  88. {
  89. return $promise->then(function (\YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response) use($uri, $statusCode) {
  90. // Note that we are pushing to the front of the list as this
  91. // would be an earlier response than what is currently present
  92. // in the history header.
  93. $historyHeader = $response->getHeader(self::HISTORY_HEADER);
  94. $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
  95. \array_unshift($historyHeader, $uri);
  96. \array_unshift($statusHeader, $statusCode);
  97. return $response->withHeader(self::HISTORY_HEADER, $historyHeader)->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
  98. });
  99. }
  100. /**
  101. * Check for too many redirects
  102. *
  103. * @return void
  104. *
  105. * @throws TooManyRedirectsException Too many redirects.
  106. */
  107. private function guardMax(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array &$options)
  108. {
  109. $current = isset($options['__redirect_count']) ? $options['__redirect_count'] : 0;
  110. $options['__redirect_count'] = $current + 1;
  111. $max = $options['allow_redirects']['max'];
  112. if ($options['__redirect_count'] > $max) {
  113. throw new \YoastSEO_Vendor\GuzzleHttp\Exception\TooManyRedirectsException("Will not follow more than {$max} redirects", $request);
  114. }
  115. }
  116. /**
  117. * @param RequestInterface $request
  118. * @param array $options
  119. * @param ResponseInterface $response
  120. *
  121. * @return RequestInterface
  122. */
  123. public function modifyRequest(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, array $options, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response)
  124. {
  125. // Request modifications to apply.
  126. $modify = [];
  127. $protocols = $options['allow_redirects']['protocols'];
  128. // Use a GET request if this is an entity enclosing request and we are
  129. // not forcing RFC compliance, but rather emulating what all browsers
  130. // would do.
  131. $statusCode = $response->getStatusCode();
  132. if ($statusCode == 303 || $statusCode <= 302 && !$options['allow_redirects']['strict']) {
  133. $modify['method'] = 'GET';
  134. $modify['body'] = '';
  135. }
  136. $uri = $this->redirectUri($request, $response, $protocols);
  137. if (isset($options['idn_conversion']) && $options['idn_conversion'] !== \false) {
  138. $idnOptions = $options['idn_conversion'] === \true ? \IDNA_DEFAULT : $options['idn_conversion'];
  139. $uri = _idn_uri_convert($uri, $idnOptions);
  140. }
  141. $modify['uri'] = $uri;
  142. \YoastSEO_Vendor\GuzzleHttp\Psr7\rewind_body($request);
  143. // Add the Referer header if it is told to do so and only
  144. // add the header if we are not redirecting from https to http.
  145. if ($options['allow_redirects']['referer'] && $modify['uri']->getScheme() === $request->getUri()->getScheme()) {
  146. $uri = $request->getUri()->withUserInfo('');
  147. $modify['set_headers']['Referer'] = (string) $uri;
  148. } else {
  149. $modify['remove_headers'][] = 'Referer';
  150. }
  151. // Remove Authorization header if host is different.
  152. if ($request->getUri()->getHost() !== $modify['uri']->getHost()) {
  153. $modify['remove_headers'][] = 'Authorization';
  154. }
  155. return \YoastSEO_Vendor\GuzzleHttp\Psr7\modify_request($request, $modify);
  156. }
  157. /**
  158. * Set the appropriate URL on the request based on the location header
  159. *
  160. * @param RequestInterface $request
  161. * @param ResponseInterface $response
  162. * @param array $protocols
  163. *
  164. * @return UriInterface
  165. */
  166. private function redirectUri(\YoastSEO_Vendor\Psr\Http\Message\RequestInterface $request, \YoastSEO_Vendor\Psr\Http\Message\ResponseInterface $response, array $protocols)
  167. {
  168. $location = \YoastSEO_Vendor\GuzzleHttp\Psr7\UriResolver::resolve($request->getUri(), new \YoastSEO_Vendor\GuzzleHttp\Psr7\Uri($response->getHeaderLine('Location')));
  169. // Ensure that the redirect URI is allowed based on the protocols.
  170. if (!\in_array($location->getScheme(), $protocols)) {
  171. 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);
  172. }
  173. return $location;
  174. }
  175. }