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