Pull merge.
[yaffs-website] / vendor / symfony / http-kernel / HttpCache / AbstractSurrogate.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\HttpKernel\HttpCache;
13
14 use Symfony\Component\HttpFoundation\Request;
15 use Symfony\Component\HttpFoundation\Response;
16 use Symfony\Component\HttpKernel\HttpKernelInterface;
17
18 /**
19  * Abstract class implementing Surrogate capabilities to Request and Response instances.
20  *
21  * @author Fabien Potencier <fabien@symfony.com>
22  * @author Robin Chalas <robin.chalas@gmail.com>
23  */
24 abstract class AbstractSurrogate implements SurrogateInterface
25 {
26     protected $contentTypes;
27     protected $phpEscapeMap = array(
28         array('<?', '<%', '<s', '<S'),
29         array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'),
30     );
31
32     /**
33      * @param array $contentTypes An array of content-type that should be parsed for Surrogate information
34      *                            (default: text/html, text/xml, application/xhtml+xml, and application/xml)
35      */
36     public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))
37     {
38         $this->contentTypes = $contentTypes;
39     }
40
41     /**
42      * Returns a new cache strategy instance.
43      *
44      * @return ResponseCacheStrategyInterface A ResponseCacheStrategyInterface instance
45      */
46     public function createCacheStrategy()
47     {
48         return new ResponseCacheStrategy();
49     }
50
51     /**
52      * {@inheritdoc}
53      */
54     public function hasSurrogateCapability(Request $request)
55     {
56         if (null === $value = $request->headers->get('Surrogate-Capability')) {
57             return false;
58         }
59
60         return false !== strpos($value, sprintf('%s/1.0', strtoupper($this->getName())));
61     }
62
63     /**
64      * {@inheritdoc}
65      */
66     public function addSurrogateCapability(Request $request)
67     {
68         $current = $request->headers->get('Surrogate-Capability');
69         $new = sprintf('symfony="%s/1.0"', strtoupper($this->getName()));
70
71         $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new);
72     }
73
74     /**
75      * {@inheritdoc}
76      */
77     public function needsParsing(Response $response)
78     {
79         if (!$control = $response->headers->get('Surrogate-Control')) {
80             return false;
81         }
82
83         $pattern = sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName()));
84
85         return (bool) preg_match($pattern, $control);
86     }
87
88     /**
89      * {@inheritdoc}
90      */
91     public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors)
92     {
93         $subRequest = Request::create($uri, Request::METHOD_GET, array(), $cache->getRequest()->cookies->all(), array(), $cache->getRequest()->server->all());
94
95         try {
96             $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
97
98             if (!$response->isSuccessful()) {
99                 throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode()));
100             }
101
102             return $response->getContent();
103         } catch (\Exception $e) {
104             if ($alt) {
105                 return $this->handle($cache, $alt, '', $ignoreErrors);
106             }
107
108             if (!$ignoreErrors) {
109                 throw $e;
110             }
111         }
112     }
113
114     /**
115      * Remove the Surrogate from the Surrogate-Control header.
116      */
117     protected function removeFromControl(Response $response)
118     {
119         if (!$response->headers->has('Surrogate-Control')) {
120             return;
121         }
122
123         $value = $response->headers->get('Surrogate-Control');
124         $upperName = strtoupper($this->getName());
125
126         if (sprintf('content="%s/1.0"', $upperName) == $value) {
127             $response->headers->remove('Surrogate-Control');
128         } elseif (preg_match(sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) {
129             $response->headers->set('Surrogate-Control', preg_replace(sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value));
130         } elseif (preg_match(sprintf('#content="%s/1.0",\s*#', $upperName), $value)) {
131             $response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value));
132         }
133     }
134 }