Mercurial > hg > cmmr2012-drupal-site
comparison vendor/symfony/http-foundation/ResponseHeaderBag.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | 5311817fb629 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
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\HttpFoundation; | |
13 | |
14 /** | |
15 * ResponseHeaderBag is a container for Response HTTP headers. | |
16 * | |
17 * @author Fabien Potencier <fabien@symfony.com> | |
18 */ | |
19 class ResponseHeaderBag extends HeaderBag | |
20 { | |
21 const COOKIES_FLAT = 'flat'; | |
22 const COOKIES_ARRAY = 'array'; | |
23 | |
24 const DISPOSITION_ATTACHMENT = 'attachment'; | |
25 const DISPOSITION_INLINE = 'inline'; | |
26 | |
27 protected $computedCacheControl = array(); | |
28 protected $cookies = array(); | |
29 protected $headerNames = array(); | |
30 | |
31 public function __construct(array $headers = array()) | |
32 { | |
33 parent::__construct($headers); | |
34 | |
35 if (!isset($this->headers['cache-control'])) { | |
36 $this->set('Cache-Control', ''); | |
37 } | |
38 | |
39 /* RFC2616 - 14.18 says all Responses need to have a Date */ | |
40 if (!isset($this->headers['date'])) { | |
41 $this->initDate(); | |
42 } | |
43 } | |
44 | |
45 /** | |
46 * Returns the headers, with original capitalizations. | |
47 * | |
48 * @return array An array of headers | |
49 */ | |
50 public function allPreserveCase() | |
51 { | |
52 $headers = array(); | |
53 foreach ($this->all() as $name => $value) { | |
54 $headers[isset($this->headerNames[$name]) ? $this->headerNames[$name] : $name] = $value; | |
55 } | |
56 | |
57 return $headers; | |
58 } | |
59 | |
60 public function allPreserveCaseWithoutCookies() | |
61 { | |
62 $headers = $this->allPreserveCase(); | |
63 if (isset($this->headerNames['set-cookie'])) { | |
64 unset($headers[$this->headerNames['set-cookie']]); | |
65 } | |
66 | |
67 return $headers; | |
68 } | |
69 | |
70 /** | |
71 * {@inheritdoc} | |
72 */ | |
73 public function replace(array $headers = array()) | |
74 { | |
75 $this->headerNames = array(); | |
76 | |
77 parent::replace($headers); | |
78 | |
79 if (!isset($this->headers['cache-control'])) { | |
80 $this->set('Cache-Control', ''); | |
81 } | |
82 | |
83 if (!isset($this->headers['date'])) { | |
84 $this->initDate(); | |
85 } | |
86 } | |
87 | |
88 /** | |
89 * {@inheritdoc} | |
90 */ | |
91 public function all() | |
92 { | |
93 $headers = parent::all(); | |
94 foreach ($this->getCookies() as $cookie) { | |
95 $headers['set-cookie'][] = (string) $cookie; | |
96 } | |
97 | |
98 return $headers; | |
99 } | |
100 | |
101 /** | |
102 * {@inheritdoc} | |
103 */ | |
104 public function set($key, $values, $replace = true) | |
105 { | |
106 $uniqueKey = str_replace('_', '-', strtolower($key)); | |
107 | |
108 if ('set-cookie' === $uniqueKey) { | |
109 if ($replace) { | |
110 $this->cookies = array(); | |
111 } | |
112 foreach ((array) $values as $cookie) { | |
113 $this->setCookie(Cookie::fromString($cookie)); | |
114 } | |
115 $this->headerNames[$uniqueKey] = $key; | |
116 | |
117 return; | |
118 } | |
119 | |
120 $this->headerNames[$uniqueKey] = $key; | |
121 | |
122 parent::set($key, $values, $replace); | |
123 | |
124 // ensure the cache-control header has sensible defaults | |
125 if (\in_array($uniqueKey, array('cache-control', 'etag', 'last-modified', 'expires'), true)) { | |
126 $computed = $this->computeCacheControlValue(); | |
127 $this->headers['cache-control'] = array($computed); | |
128 $this->headerNames['cache-control'] = 'Cache-Control'; | |
129 $this->computedCacheControl = $this->parseCacheControl($computed); | |
130 } | |
131 } | |
132 | |
133 /** | |
134 * {@inheritdoc} | |
135 */ | |
136 public function remove($key) | |
137 { | |
138 $uniqueKey = str_replace('_', '-', strtolower($key)); | |
139 unset($this->headerNames[$uniqueKey]); | |
140 | |
141 if ('set-cookie' === $uniqueKey) { | |
142 $this->cookies = array(); | |
143 | |
144 return; | |
145 } | |
146 | |
147 parent::remove($key); | |
148 | |
149 if ('cache-control' === $uniqueKey) { | |
150 $this->computedCacheControl = array(); | |
151 } | |
152 | |
153 if ('date' === $uniqueKey) { | |
154 $this->initDate(); | |
155 } | |
156 } | |
157 | |
158 /** | |
159 * {@inheritdoc} | |
160 */ | |
161 public function hasCacheControlDirective($key) | |
162 { | |
163 return array_key_exists($key, $this->computedCacheControl); | |
164 } | |
165 | |
166 /** | |
167 * {@inheritdoc} | |
168 */ | |
169 public function getCacheControlDirective($key) | |
170 { | |
171 return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null; | |
172 } | |
173 | |
174 public function setCookie(Cookie $cookie) | |
175 { | |
176 $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie; | |
177 $this->headerNames['set-cookie'] = 'Set-Cookie'; | |
178 } | |
179 | |
180 /** | |
181 * Removes a cookie from the array, but does not unset it in the browser. | |
182 * | |
183 * @param string $name | |
184 * @param string $path | |
185 * @param string $domain | |
186 */ | |
187 public function removeCookie($name, $path = '/', $domain = null) | |
188 { | |
189 if (null === $path) { | |
190 $path = '/'; | |
191 } | |
192 | |
193 unset($this->cookies[$domain][$path][$name]); | |
194 | |
195 if (empty($this->cookies[$domain][$path])) { | |
196 unset($this->cookies[$domain][$path]); | |
197 | |
198 if (empty($this->cookies[$domain])) { | |
199 unset($this->cookies[$domain]); | |
200 } | |
201 } | |
202 | |
203 if (empty($this->cookies)) { | |
204 unset($this->headerNames['set-cookie']); | |
205 } | |
206 } | |
207 | |
208 /** | |
209 * Returns an array with all cookies. | |
210 * | |
211 * @param string $format | |
212 * | |
213 * @return array | |
214 * | |
215 * @throws \InvalidArgumentException When the $format is invalid | |
216 */ | |
217 public function getCookies($format = self::COOKIES_FLAT) | |
218 { | |
219 if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) { | |
220 throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY)))); | |
221 } | |
222 | |
223 if (self::COOKIES_ARRAY === $format) { | |
224 return $this->cookies; | |
225 } | |
226 | |
227 $flattenedCookies = array(); | |
228 foreach ($this->cookies as $path) { | |
229 foreach ($path as $cookies) { | |
230 foreach ($cookies as $cookie) { | |
231 $flattenedCookies[] = $cookie; | |
232 } | |
233 } | |
234 } | |
235 | |
236 return $flattenedCookies; | |
237 } | |
238 | |
239 /** | |
240 * Clears a cookie in the browser. | |
241 * | |
242 * @param string $name | |
243 * @param string $path | |
244 * @param string $domain | |
245 * @param bool $secure | |
246 * @param bool $httpOnly | |
247 */ | |
248 public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true) | |
249 { | |
250 $this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly)); | |
251 } | |
252 | |
253 /** | |
254 * Generates a HTTP Content-Disposition field-value. | |
255 * | |
256 * @param string $disposition One of "inline" or "attachment" | |
257 * @param string $filename A unicode string | |
258 * @param string $filenameFallback A string containing only ASCII characters that | |
259 * is semantically equivalent to $filename. If the filename is already ASCII, | |
260 * it can be omitted, or just copied from $filename | |
261 * | |
262 * @return string A string suitable for use as a Content-Disposition field-value | |
263 * | |
264 * @throws \InvalidArgumentException | |
265 * | |
266 * @see RFC 6266 | |
267 */ | |
268 public function makeDisposition($disposition, $filename, $filenameFallback = '') | |
269 { | |
270 if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) { | |
271 throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE)); | |
272 } | |
273 | |
274 if ('' == $filenameFallback) { | |
275 $filenameFallback = $filename; | |
276 } | |
277 | |
278 // filenameFallback is not ASCII. | |
279 if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) { | |
280 throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.'); | |
281 } | |
282 | |
283 // percent characters aren't safe in fallback. | |
284 if (false !== strpos($filenameFallback, '%')) { | |
285 throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.'); | |
286 } | |
287 | |
288 // path separators aren't allowed in either. | |
289 if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) { | |
290 throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.'); | |
291 } | |
292 | |
293 $output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback)); | |
294 | |
295 if ($filename !== $filenameFallback) { | |
296 $output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename)); | |
297 } | |
298 | |
299 return $output; | |
300 } | |
301 | |
302 /** | |
303 * Returns the calculated value of the cache-control header. | |
304 * | |
305 * This considers several other headers and calculates or modifies the | |
306 * cache-control header to a sensible, conservative value. | |
307 * | |
308 * @return string | |
309 */ | |
310 protected function computeCacheControlValue() | |
311 { | |
312 if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) { | |
313 return 'no-cache, private'; | |
314 } | |
315 | |
316 if (!$this->cacheControl) { | |
317 // conservative by default | |
318 return 'private, must-revalidate'; | |
319 } | |
320 | |
321 $header = $this->getCacheControlHeader(); | |
322 if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) { | |
323 return $header; | |
324 } | |
325 | |
326 // public if s-maxage is defined, private otherwise | |
327 if (!isset($this->cacheControl['s-maxage'])) { | |
328 return $header.', private'; | |
329 } | |
330 | |
331 return $header; | |
332 } | |
333 | |
334 private function initDate() | |
335 { | |
336 $now = \DateTime::createFromFormat('U', time()); | |
337 $now->setTimezone(new \DateTimeZone('UTC')); | |
338 $this->set('Date', $now->format('D, d M Y H:i:s').' GMT'); | |
339 } | |
340 } |