Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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

Redirect.php

Zuletzt modifiziert: 09.10.2024, 12:57 - Dateigröße: 6.06 KiB


 001  <?php
 002  namespace GuzzleHttp\Subscriber;
 003   
 004  use GuzzleHttp\Event\CompleteEvent;
 005  use GuzzleHttp\Event\RequestEvents;
 006  use GuzzleHttp\Event\SubscriberInterface;
 007  use GuzzleHttp\Exception\BadResponseException;
 008  use GuzzleHttp\Exception\CouldNotRewindStreamException;
 009  use GuzzleHttp\Exception\TooManyRedirectsException;
 010  use GuzzleHttp\Message\RequestInterface;
 011  use GuzzleHttp\Message\ResponseInterface;
 012  use GuzzleHttp\Url;
 013   
 014  /**
 015   * Subscriber used to implement HTTP redirects.
 016   *
 017   * **Request options**
 018   *
 019   * - redirect: Associative array containing the 'max', 'strict', and 'referer'
 020   *   keys.
 021   *
 022   *   - max: Maximum number of redirects allowed per-request
 023   *   - strict: You can use strict redirects by setting this value to ``true``.
 024   *     Strict redirects adhere to strict RFC compliant redirection (e.g.,
 025   *     redirect POST with POST) vs doing what most clients do (e.g., redirect
 026   *     POST request with a GET request).
 027   *   - referer: Set to true to automatically add the "Referer" header when a
 028   *     redirect request is sent.
 029   *   - protocols: Array of allowed protocols. Defaults to 'http' and 'https'.
 030   *     When a redirect attempts to utilize a protocol that is not white listed,
 031   *     an exception is thrown.
 032   */
 033  class Redirect implements SubscriberInterface
 034  {
 035      public function getEvents()
 036      {
 037          return ['complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE]];
 038      }
 039   
 040      /**
 041       * Rewind the entity body of the request if needed
 042       *
 043       * @param RequestInterface $redirectRequest
 044       * @throws CouldNotRewindStreamException
 045       */
 046      public static function rewindEntityBody(RequestInterface $redirectRequest)
 047      {
 048          // Rewind the entity body of the request if needed
 049          if ($body = $redirectRequest->getBody()) {
 050              // Only rewind the body if some of it has been read already, and
 051              // throw an exception if the rewind fails
 052              if ($body->tell() && !$body->seek(0)) {
 053                  throw new CouldNotRewindStreamException(
 054                      'Unable to rewind the non-seekable request body after redirecting',
 055                      $redirectRequest
 056                  );
 057              }
 058          }
 059      }
 060   
 061      /**
 062       * Called when a request receives a redirect response
 063       *
 064       * @param CompleteEvent $event Event emitted
 065       * @throws TooManyRedirectsException
 066       */
 067      public function onComplete(CompleteEvent $event)
 068      {
 069          $response = $event->getResponse();
 070   
 071          if (substr($response->getStatusCode(), 0, 1) != '3'
 072              || !$response->hasHeader('Location')
 073          ) {
 074              return;
 075          }
 076   
 077          $request = $event->getRequest();
 078          $config = $request->getConfig();
 079   
 080          // Increment the redirect and initialize the redirect state.
 081          if ($redirectCount = $config['redirect_count']) {
 082              $config['redirect_count'] = ++$redirectCount;
 083          } else {
 084              $config['redirect_scheme'] = $request->getScheme();
 085              $config['redirect_count'] = $redirectCount = 1;
 086          }
 087   
 088          $max = $config->getPath('redirect/max') ?: 5;
 089   
 090          if ($redirectCount > $max) {
 091              throw new TooManyRedirectsException(
 092                  "Will not follow more than {$redirectCount} redirects",
 093                  $request
 094              );
 095          }
 096   
 097          $this->modifyRedirectRequest($request, $response);
 098          $event->retry();
 099      }
 100   
 101      private function modifyRedirectRequest(
 102          RequestInterface $request,
 103          ResponseInterface $response
 104      ) {
 105          $config = $request->getConfig();
 106          $protocols = $config->getPath('redirect/protocols') ?: ['http', 'https'];
 107   
 108          // Use a GET request if this is an entity enclosing request and we are
 109          // not forcing RFC compliance, but rather emulating what all browsers
 110          // would do.
 111          $statusCode = $response->getStatusCode();
 112          if ($statusCode == 303 ||
 113              ($statusCode <= 302 && $request->getBody() && !$config->getPath('redirect/strict'))
 114          ) {
 115              $request->setMethod('GET');
 116              $request->setBody(null);
 117          }
 118   
 119          $previousUrl = $request->getUrl();
 120          $this->setRedirectUrl($request, $response, $protocols);
 121          $this->rewindEntityBody($request);
 122   
 123          // Add the Referer header if it is told to do so and only
 124          // add the header if we are not redirecting from https to http.
 125          if ($config->getPath('redirect/referer')
 126              && ($request->getScheme() == 'https' || $request->getScheme() == $config['redirect_scheme'])
 127          ) {
 128              $url = Url::fromString($previousUrl);
 129              $url->setUsername(null);
 130              $url->setPassword(null);
 131              $request->setHeader('Referer', (string) $url);
 132          } else {
 133              $request->removeHeader('Referer');
 134          }
 135      }
 136   
 137      /**
 138       * Set the appropriate URL on the request based on the location header
 139       *
 140       * @param RequestInterface  $request
 141       * @param ResponseInterface $response
 142       * @param array             $protocols
 143       */
 144      private function setRedirectUrl(
 145          RequestInterface $request,
 146          ResponseInterface $response,
 147          array $protocols
 148      ) {
 149          $location = $response->getHeader('Location');
 150          $location = Url::fromString($location);
 151   
 152          // Combine location with the original URL if it is not absolute.
 153          if (!$location->isAbsolute()) {
 154              $originalUrl = Url::fromString($request->getUrl());
 155              // Remove query string parameters and just take what is present on
 156              // the redirect Location header
 157              $originalUrl->getQuery()->clear();
 158              $location = $originalUrl->combine($location);
 159          }
 160   
 161          // Ensure that the redirect URL is allowed based on the protocols.
 162          if (!in_array($location->getScheme(), $protocols)) {
 163              throw new BadResponseException(
 164                  sprintf(
 165                      'Redirect URL, %s, does not use one of the allowed redirect protocols: %s',
 166                      $location,
 167                      implode(', ', $protocols)
 168                  ),
 169                  $request,
 170                  $response
 171              );
 172          }
 173   
 174          $request->setUrl($location);
 175      }
 176  }
 177