Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

RedirectMiddleware.php

Zuletzt modifiziert: 01.05.2026, 11:26 - Dateigröße: 8.52 KiB


 001  <?php
 002  namespace GuzzleHttp;
 003   
 004  use GuzzleHttp\Exception\BadResponseException;
 005  use GuzzleHttp\Exception\TooManyRedirectsException;
 006  use GuzzleHttp\Promise\PromiseInterface;
 007  use GuzzleHttp\Psr7;
 008  use Psr\Http\Message\RequestInterface;
 009  use Psr\Http\Message\ResponseInterface;
 010  use Psr\Http\Message\UriInterface;
 011   
 012  /**
 013   * Request redirect middleware.
 014   *
 015   * Apply this middleware like other middleware using
 016   * {@see \GuzzleHttp\Middleware::redirect()}.
 017   */
 018  class RedirectMiddleware
 019  {
 020      const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
 021   
 022      const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
 023   
 024      public static $defaultSettings = [
 025          'max'             => 5,
 026          'protocols'       => ['http', 'https'],
 027          'strict'          => false,
 028          'referer'         => false,
 029          'track_redirects' => false,
 030      ];
 031   
 032      /** @var callable  */
 033      private $nextHandler;
 034   
 035      /**
 036       * @param callable $nextHandler Next handler to invoke.
 037       */
 038      public function __construct(callable $nextHandler)
 039      {
 040          $this->nextHandler = $nextHandler;
 041      }
 042   
 043      /**
 044       * @param RequestInterface $request
 045       * @param array            $options
 046       *
 047       * @return PromiseInterface
 048       */
 049      public function __invoke(RequestInterface $request, array $options)
 050      {
 051          $fn = $this->nextHandler;
 052   
 053          if (empty($options['allow_redirects'])) {
 054              return $fn($request, $options);
 055          }
 056   
 057          if ($options['allow_redirects'] === true) {
 058              $options['allow_redirects'] = self::$defaultSettings;
 059          } elseif (!is_array($options['allow_redirects'])) {
 060              throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
 061          } else {
 062              // Merge the default settings with the provided settings
 063              $options['allow_redirects'] += self::$defaultSettings;
 064          }
 065   
 066          if (empty($options['allow_redirects']['max'])) {
 067              return $fn($request, $options);
 068          }
 069   
 070          return $fn($request, $options)
 071              ->then(function (ResponseInterface $response) use ($request, $options) {
 072                  return $this->checkRedirect($request, $options, $response);
 073              });
 074      }
 075   
 076      /**
 077       * @param RequestInterface  $request
 078       * @param array             $options
 079       * @param ResponseInterface $response
 080       *
 081       * @return ResponseInterface|PromiseInterface
 082       */
 083      public function checkRedirect(
 084          RequestInterface $request,
 085          array $options,
 086          ResponseInterface $response
 087      ) {
 088          if (substr($response->getStatusCode(), 0, 1) != '3'
 089              || !$response->hasHeader('Location')
 090          ) {
 091              return $response;
 092          }
 093   
 094          $this->guardMax($request, $options);
 095          $nextRequest = $this->modifyRequest($request, $options, $response);
 096   
 097          // If authorization is handled by curl, unset it if URI is cross-origin.
 098          if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && defined('\CURLOPT_HTTPAUTH')) {
 099              unset(
 100                  $options['curl'][\CURLOPT_HTTPAUTH],
 101                  $options['curl'][\CURLOPT_USERPWD]
 102              );
 103          }
 104   
 105          if (isset($options['allow_redirects']['on_redirect'])) {
 106              call_user_func(
 107                  $options['allow_redirects']['on_redirect'],
 108                  $request,
 109                  $response,
 110                  $nextRequest->getUri()
 111              );
 112          }
 113   
 114          /** @var PromiseInterface|ResponseInterface $promise */
 115          $promise = $this($nextRequest, $options);
 116   
 117          // Add headers to be able to track history of redirects.
 118          if (!empty($options['allow_redirects']['track_redirects'])) {
 119              return $this->withTracking(
 120                  $promise,
 121                  (string) $nextRequest->getUri(),
 122                  $response->getStatusCode()
 123              );
 124          }
 125   
 126          return $promise;
 127      }
 128   
 129      /**
 130       * Enable tracking on promise.
 131       *
 132       * @return PromiseInterface
 133       */
 134      private function withTracking(PromiseInterface $promise, $uri, $statusCode)
 135      {
 136          return $promise->then(
 137              function (ResponseInterface $response) use ($uri, $statusCode) {
 138                  // Note that we are pushing to the front of the list as this
 139                  // would be an earlier response than what is currently present
 140                  // in the history header.
 141                  $historyHeader = $response->getHeader(self::HISTORY_HEADER);
 142                  $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
 143                  array_unshift($historyHeader, $uri);
 144                  array_unshift($statusHeader, $statusCode);
 145                  return $response->withHeader(self::HISTORY_HEADER, $historyHeader)
 146                                  ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
 147              }
 148          );
 149      }
 150   
 151      /**
 152       * Check for too many redirects.
 153       *
 154       * @return void
 155       *
 156       * @throws TooManyRedirectsException Too many redirects.
 157       */
 158      private function guardMax(RequestInterface $request, array &$options)
 159      {
 160          $current = isset($options['__redirect_count'])
 161              ? $options['__redirect_count']
 162              : 0;
 163          $options['__redirect_count'] = $current + 1;
 164          $max = $options['allow_redirects']['max'];
 165   
 166          if ($options['__redirect_count'] > $max) {
 167              throw new TooManyRedirectsException(
 168                  "Will not follow more than {$max} redirects",
 169                  $request
 170              );
 171          }
 172      }
 173   
 174      /**
 175       * @param RequestInterface  $request
 176       * @param array             $options
 177       * @param ResponseInterface $response
 178       *
 179       * @return RequestInterface
 180       */
 181      public function modifyRequest(
 182          RequestInterface $request,
 183          array $options,
 184          ResponseInterface $response
 185      ) {
 186          // Request modifications to apply.
 187          $modify = [];
 188          $protocols = $options['allow_redirects']['protocols'];
 189   
 190          // Use a GET request if this is an entity enclosing request and we are
 191          // not forcing RFC compliance, but rather emulating what all browsers
 192          // would do.
 193          $statusCode = $response->getStatusCode();
 194          if ($statusCode == 303 ||
 195              ($statusCode <= 302 && !$options['allow_redirects']['strict'])
 196          ) {
 197              $modify['method'] = 'GET';
 198              $modify['body'] = '';
 199          }
 200   
 201          $uri = self::redirectUri($request, $response, $protocols);
 202          if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
 203              $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion'];
 204              $uri = Utils::idnUriConvert($uri, $idnOptions);
 205          }
 206   
 207          $modify['uri'] = $uri;
 208          Psr7\rewind_body($request);
 209   
 210          // Add the Referer header if it is told to do so and only
 211          // add the header if we are not redirecting from https to http.
 212          if ($options['allow_redirects']['referer']
 213              && $modify['uri']->getScheme() === $request->getUri()->getScheme()
 214          ) {
 215              $uri = $request->getUri()->withUserInfo('');
 216              $modify['set_headers']['Referer'] = (string) $uri;
 217          } else {
 218              $modify['remove_headers'][] = 'Referer';
 219          }
 220   
 221          // Remove Authorization and Cookie headers if URI is cross-origin.
 222          if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) {
 223              $modify['remove_headers'][] = 'Authorization';
 224              $modify['remove_headers'][] = 'Cookie';
 225          }
 226   
 227          return Psr7\modify_request($request, $modify);
 228      }
 229   
 230      /**
 231       * Set the appropriate URL on the request based on the location header.
 232       *
 233       * @param RequestInterface  $request
 234       * @param ResponseInterface $response
 235       * @param array             $protocols
 236       *
 237       * @return UriInterface
 238       */
 239      private static function redirectUri(
 240          RequestInterface $request,
 241          ResponseInterface $response,
 242          array $protocols
 243      ) {
 244          $location = Psr7\UriResolver::resolve(
 245              $request->getUri(),
 246              new Psr7\Uri($response->getHeaderLine('Location'))
 247          );
 248   
 249          // Ensure that the redirect URI is allowed based on the protocols.
 250          if (!in_array($location->getScheme(), $protocols)) {
 251              throw new BadResponseException(
 252                  sprintf(
 253                      'Redirect URI, %s, does not use one of the allowed redirect protocols: %s',
 254                      $location,
 255                      implode(', ', $protocols)
 256                  ),
 257                  $request,
 258                  $response
 259              );
 260          }
 261   
 262          return $location;
 263      }
 264  }
 265