Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. AbstractSurrogate.php

class AbstractSurrogate

Abstract class implementing Surrogate capabilities to Request and Response instances.

@author Fabien Potencier <fabien@symfony.com> @author Robin Chalas <robin.chalas@gmail.com>

Hierarchy

  • class \Symfony\Component\HttpKernel\HttpCache\AbstractSurrogate implements \Symfony\Component\HttpKernel\HttpCache\SurrogateInterface

Expanded class hierarchy of AbstractSurrogate

File

vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php, line 24

Namespace

Symfony\Component\HttpKernel\HttpCache
View source
abstract class AbstractSurrogate implements SurrogateInterface {
    
    /**
     * @param array $contentTypes An array of content-type that should be parsed for Surrogate information
     *                            (default: text/html, text/xml, application/xhtml+xml, and application/xml)
     */
    public function __construct(array $contentTypes = [
        'text/html',
        'text/xml',
        'application/xhtml+xml',
        'application/xml',
    ]) {
    }
    
    /**
     * Returns a new cache strategy instance.
     */
    public function createCacheStrategy() : ResponseCacheStrategyInterface {
        return new ResponseCacheStrategy();
    }
    public function hasSurrogateCapability(Request $request) : bool {
        if (null === ($value = $request->headers
            ->get('Surrogate-Capability'))) {
            return false;
        }
        return str_contains($value, \sprintf('%s/1.0', strtoupper($this->getName())));
    }
    public function addSurrogateCapability(Request $request) : void {
        $current = $request->headers
            ->get('Surrogate-Capability');
        $new = \sprintf('symfony="%s/1.0"', strtoupper($this->getName()));
        $request->headers
            ->set('Surrogate-Capability', $current ? $current . ', ' . $new : $new);
    }
    public function needsParsing(Response $response) : bool {
        if (!($control = $response->headers
            ->get('Surrogate-Control'))) {
            return false;
        }
        $pattern = \sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName()));
        return (bool) preg_match($pattern, $control);
    }
    public function handle(HttpCache $cache, string $uri, string $alt, bool $ignoreErrors) : string {
        $subRequest = Request::create($uri, Request::METHOD_GET, [], $cache->getRequest()->cookies
            ->all(), [], $cache->getRequest()->server
            ->all());
        try {
            $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
            if (!$response->isSuccessful() && Response::HTTP_NOT_MODIFIED !== $response->getStatusCode()) {
                throw new \RuntimeException(\sprintf('Error when rendering "%s" (Status code is %d).', $subRequest->getUri(), $response->getStatusCode()));
            }
            return $response->getContent();
        } catch (\Exception $e) {
            if ($alt) {
                return $this->handle($cache, $alt, '', $ignoreErrors);
            }
            if (!$ignoreErrors) {
                throw $e;
            }
        }
        return '';
    }
    
    /**
     * Remove the Surrogate from the Surrogate-Control header.
     */
    protected function removeFromControl(Response $response) : void {
        if (!$response->headers
            ->has('Surrogate-Control')) {
            return;
        }
        $value = $response->headers
            ->get('Surrogate-Control');
        $upperName = strtoupper($this->getName());
        if (\sprintf('content="%s/1.0"', $upperName) == $value) {
            $response->headers
                ->remove('Surrogate-Control');
        }
        elseif (preg_match(\sprintf('#,\\s*content="%s/1.0"#', $upperName), $value)) {
            $response->headers
                ->set('Surrogate-Control', preg_replace(\sprintf('#,\\s*content="%s/1.0"#', $upperName), '', $value));
        }
        elseif (preg_match(\sprintf('#content="%s/1.0",\\s*#', $upperName), $value)) {
            $response->headers
                ->set('Surrogate-Control', preg_replace(\sprintf('#content="%s/1.0",\\s*#', $upperName), '', $value));
        }
    }
    protected static function generateBodyEvalBoundary() : string {
        static $cookie;
        $cookie = hash('xxh128', $cookie ?? ($cookie = random_bytes(16)), true);
        $boundary = base64_encode($cookie);
        \assert(HttpCache::BODY_EVAL_BOUNDARY_LENGTH === \strlen($boundary));
        return $boundary;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
AbstractSurrogate::addSurrogateCapability public function Adds Surrogate-capability to the given Request. Overrides SurrogateInterface::addSurrogateCapability
AbstractSurrogate::createCacheStrategy public function Returns a new cache strategy instance. Overrides SurrogateInterface::createCacheStrategy
AbstractSurrogate::generateBodyEvalBoundary protected static function
AbstractSurrogate::handle public function Handles a Surrogate from the cache. Overrides SurrogateInterface::handle
AbstractSurrogate::hasSurrogateCapability public function Checks that at least one surrogate has Surrogate capability. Overrides SurrogateInterface::hasSurrogateCapability
AbstractSurrogate::needsParsing public function Checks that the Response needs to be parsed for Surrogate tags. Overrides SurrogateInterface::needsParsing
AbstractSurrogate::removeFromControl protected function Remove the Surrogate from the Surrogate-Control header.
AbstractSurrogate::__construct public function
SurrogateInterface::addSurrogateControl public function Adds HTTP headers to specify that the Response needs to be parsed for Surrogate. 2
SurrogateInterface::getName public function Returns surrogate name. 2
SurrogateInterface::process public function Replaces a Response Surrogate tags with the included resource content. 2
SurrogateInterface::renderIncludeTag public function Renders a Surrogate tag. 2

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal