Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\HttpKernel\HttpCache; Chris@0: Chris@0: use Symfony\Component\HttpFoundation\Request; Chris@0: use Symfony\Component\HttpFoundation\Response; Chris@0: use Symfony\Component\HttpKernel\HttpKernelInterface; Chris@0: Chris@0: /** Chris@0: * Abstract class implementing Surrogate capabilities to Request and Response instances. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: * @author Robin Chalas Chris@0: */ Chris@0: abstract class AbstractSurrogate implements SurrogateInterface Chris@0: { Chris@0: protected $contentTypes; Chris@17: protected $phpEscapeMap = [ Chris@17: ['', '', '', ''], Chris@17: ]; Chris@0: Chris@0: /** Chris@0: * @param array $contentTypes An array of content-type that should be parsed for Surrogate information Chris@0: * (default: text/html, text/xml, application/xhtml+xml, and application/xml) Chris@0: */ Chris@17: public function __construct(array $contentTypes = ['text/html', 'text/xml', 'application/xhtml+xml', 'application/xml']) Chris@0: { Chris@0: $this->contentTypes = $contentTypes; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns a new cache strategy instance. Chris@0: * Chris@0: * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance Chris@0: */ Chris@0: public function createCacheStrategy() Chris@0: { Chris@0: return new ResponseCacheStrategy(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function hasSurrogateCapability(Request $request) Chris@0: { Chris@0: if (null === $value = $request->headers->get('Surrogate-Capability')) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: return false !== strpos($value, sprintf('%s/1.0', strtoupper($this->getName()))); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function addSurrogateCapability(Request $request) Chris@0: { Chris@0: $current = $request->headers->get('Surrogate-Capability'); Chris@0: $new = sprintf('symfony="%s/1.0"', strtoupper($this->getName())); Chris@0: Chris@0: $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function needsParsing(Response $response) Chris@0: { Chris@0: if (!$control = $response->headers->get('Surrogate-Control')) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: $pattern = sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName())); Chris@0: Chris@0: return (bool) preg_match($pattern, $control); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors) Chris@0: { Chris@17: $subRequest = Request::create($uri, Request::METHOD_GET, [], $cache->getRequest()->cookies->all(), [], $cache->getRequest()->server->all()); Chris@0: Chris@0: try { Chris@0: $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); Chris@0: Chris@0: if (!$response->isSuccessful()) { Chris@0: throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode())); Chris@0: } Chris@0: Chris@0: return $response->getContent(); Chris@0: } catch (\Exception $e) { Chris@0: if ($alt) { Chris@0: return $this->handle($cache, $alt, '', $ignoreErrors); Chris@0: } Chris@0: Chris@0: if (!$ignoreErrors) { Chris@0: throw $e; Chris@0: } Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Remove the Surrogate from the Surrogate-Control header. Chris@0: */ Chris@0: protected function removeFromControl(Response $response) Chris@0: { Chris@0: if (!$response->headers->has('Surrogate-Control')) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $value = $response->headers->get('Surrogate-Control'); Chris@0: $upperName = strtoupper($this->getName()); Chris@0: Chris@0: if (sprintf('content="%s/1.0"', $upperName) == $value) { Chris@0: $response->headers->remove('Surrogate-Control'); Chris@0: } elseif (preg_match(sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) { Chris@0: $response->headers->set('Surrogate-Control', preg_replace(sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value)); Chris@0: } elseif (preg_match(sprintf('#content="%s/1.0",\s*#', $upperName), $value)) { Chris@0: $response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value)); Chris@0: } Chris@0: } Chris@0: }