annotate vendor/symfony/http-kernel/HttpCache/Esi.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\HttpKernel\HttpCache;
Chris@0 13
Chris@0 14 use Symfony\Component\HttpFoundation\Request;
Chris@0 15 use Symfony\Component\HttpFoundation\Response;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Esi implements the ESI capabilities to Request and Response instances.
Chris@0 19 *
Chris@0 20 * For more information, read the following W3C notes:
Chris@0 21 *
Chris@0 22 * * ESI Language Specification 1.0 (http://www.w3.org/TR/esi-lang)
Chris@0 23 *
Chris@0 24 * * Edge Architecture Specification (http://www.w3.org/TR/edge-arch)
Chris@0 25 *
Chris@0 26 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 27 */
Chris@0 28 class Esi extends AbstractSurrogate
Chris@0 29 {
Chris@0 30 public function getName()
Chris@0 31 {
Chris@0 32 return 'esi';
Chris@0 33 }
Chris@0 34
Chris@0 35 /**
Chris@0 36 * {@inheritdoc}
Chris@0 37 */
Chris@0 38 public function addSurrogateControl(Response $response)
Chris@0 39 {
Chris@0 40 if (false !== strpos($response->getContent(), '<esi:include')) {
Chris@0 41 $response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
Chris@0 42 }
Chris@0 43 }
Chris@0 44
Chris@0 45 /**
Chris@0 46 * {@inheritdoc}
Chris@0 47 */
Chris@0 48 public function renderIncludeTag($uri, $alt = null, $ignoreErrors = true, $comment = '')
Chris@0 49 {
Chris@0 50 $html = sprintf('<esi:include src="%s"%s%s />',
Chris@0 51 $uri,
Chris@0 52 $ignoreErrors ? ' onerror="continue"' : '',
Chris@0 53 $alt ? sprintf(' alt="%s"', $alt) : ''
Chris@0 54 );
Chris@0 55
Chris@0 56 if (!empty($comment)) {
Chris@0 57 return sprintf("<esi:comment text=\"%s\" />\n%s", $comment, $html);
Chris@0 58 }
Chris@0 59
Chris@0 60 return $html;
Chris@0 61 }
Chris@0 62
Chris@0 63 /**
Chris@0 64 * {@inheritdoc}
Chris@0 65 */
Chris@0 66 public function process(Request $request, Response $response)
Chris@0 67 {
Chris@0 68 $type = $response->headers->get('Content-Type');
Chris@0 69 if (empty($type)) {
Chris@0 70 $type = 'text/html';
Chris@0 71 }
Chris@0 72
Chris@0 73 $parts = explode(';', $type);
Chris@17 74 if (!\in_array($parts[0], $this->contentTypes)) {
Chris@0 75 return $response;
Chris@0 76 }
Chris@0 77
Chris@0 78 // we don't use a proper XML parser here as we can have ESI tags in a plain text response
Chris@0 79 $content = $response->getContent();
Chris@0 80 $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#s', '', $content);
Chris@0 81 $content = preg_replace('#<esi\:comment[^>]+>#s', '', $content);
Chris@0 82
Chris@0 83 $chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
Chris@0 84 $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
Chris@0 85
Chris@0 86 $i = 1;
Chris@0 87 while (isset($chunks[$i])) {
Chris@17 88 $options = [];
Chris@0 89 preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER);
Chris@0 90 foreach ($matches as $set) {
Chris@0 91 $options[$set[1]] = $set[2];
Chris@0 92 }
Chris@0 93
Chris@0 94 if (!isset($options['src'])) {
Chris@0 95 throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
Chris@0 96 }
Chris@0 97
Chris@0 98 $chunks[$i] = sprintf('<?php echo $this->surrogate->handle($this, %s, %s, %s) ?>'."\n",
Chris@0 99 var_export($options['src'], true),
Chris@0 100 var_export(isset($options['alt']) ? $options['alt'] : '', true),
Chris@0 101 isset($options['onerror']) && 'continue' === $options['onerror'] ? 'true' : 'false'
Chris@0 102 );
Chris@0 103 ++$i;
Chris@0 104 $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]);
Chris@0 105 ++$i;
Chris@0 106 }
Chris@0 107 $content = implode('', $chunks);
Chris@0 108
Chris@0 109 $response->setContent($content);
Chris@0 110 $response->headers->set('X-Body-Eval', 'ESI');
Chris@0 111
Chris@0 112 // remove ESI/1.0 from the Surrogate-Control header
Chris@0 113 $this->removeFromControl($response);
Chris@0 114 }
Chris@0 115 }