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\HttpCacheView 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 |