Mercurial > hg > isophonics-drupal-site
comparison vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 5fb285c0d0e3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 namespace GuzzleHttp\Cookie; | |
3 | |
4 /** | |
5 * Set-Cookie object | |
6 */ | |
7 class SetCookie | |
8 { | |
9 /** @var array */ | |
10 private static $defaults = [ | |
11 'Name' => null, | |
12 'Value' => null, | |
13 'Domain' => null, | |
14 'Path' => '/', | |
15 'Max-Age' => null, | |
16 'Expires' => null, | |
17 'Secure' => false, | |
18 'Discard' => false, | |
19 'HttpOnly' => false | |
20 ]; | |
21 | |
22 /** @var array Cookie data */ | |
23 private $data; | |
24 | |
25 /** | |
26 * Create a new SetCookie object from a string | |
27 * | |
28 * @param string $cookie Set-Cookie header string | |
29 * | |
30 * @return self | |
31 */ | |
32 public static function fromString($cookie) | |
33 { | |
34 // Create the default return array | |
35 $data = self::$defaults; | |
36 // Explode the cookie string using a series of semicolons | |
37 $pieces = array_filter(array_map('trim', explode(';', $cookie))); | |
38 // The name of the cookie (first kvp) must include an equal sign. | |
39 if (empty($pieces) || !strpos($pieces[0], '=')) { | |
40 return new self($data); | |
41 } | |
42 | |
43 // Add the cookie pieces into the parsed data array | |
44 foreach ($pieces as $part) { | |
45 | |
46 $cookieParts = explode('=', $part, 2); | |
47 $key = trim($cookieParts[0]); | |
48 $value = isset($cookieParts[1]) | |
49 ? trim($cookieParts[1], " \n\r\t\0\x0B") | |
50 : true; | |
51 | |
52 // Only check for non-cookies when cookies have been found | |
53 if (empty($data['Name'])) { | |
54 $data['Name'] = $key; | |
55 $data['Value'] = $value; | |
56 } else { | |
57 foreach (array_keys(self::$defaults) as $search) { | |
58 if (!strcasecmp($search, $key)) { | |
59 $data[$search] = $value; | |
60 continue 2; | |
61 } | |
62 } | |
63 $data[$key] = $value; | |
64 } | |
65 } | |
66 | |
67 return new self($data); | |
68 } | |
69 | |
70 /** | |
71 * @param array $data Array of cookie data provided by a Cookie parser | |
72 */ | |
73 public function __construct(array $data = []) | |
74 { | |
75 $this->data = array_replace(self::$defaults, $data); | |
76 // Extract the Expires value and turn it into a UNIX timestamp if needed | |
77 if (!$this->getExpires() && $this->getMaxAge()) { | |
78 // Calculate the Expires date | |
79 $this->setExpires(time() + $this->getMaxAge()); | |
80 } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { | |
81 $this->setExpires($this->getExpires()); | |
82 } | |
83 } | |
84 | |
85 public function __toString() | |
86 { | |
87 $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; | |
88 foreach ($this->data as $k => $v) { | |
89 if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { | |
90 if ($k === 'Expires') { | |
91 $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; | |
92 } else { | |
93 $str .= ($v === true ? $k : "{$k}={$v}") . '; '; | |
94 } | |
95 } | |
96 } | |
97 | |
98 return rtrim($str, '; '); | |
99 } | |
100 | |
101 public function toArray() | |
102 { | |
103 return $this->data; | |
104 } | |
105 | |
106 /** | |
107 * Get the cookie name | |
108 * | |
109 * @return string | |
110 */ | |
111 public function getName() | |
112 { | |
113 return $this->data['Name']; | |
114 } | |
115 | |
116 /** | |
117 * Set the cookie name | |
118 * | |
119 * @param string $name Cookie name | |
120 */ | |
121 public function setName($name) | |
122 { | |
123 $this->data['Name'] = $name; | |
124 } | |
125 | |
126 /** | |
127 * Get the cookie value | |
128 * | |
129 * @return string | |
130 */ | |
131 public function getValue() | |
132 { | |
133 return $this->data['Value']; | |
134 } | |
135 | |
136 /** | |
137 * Set the cookie value | |
138 * | |
139 * @param string $value Cookie value | |
140 */ | |
141 public function setValue($value) | |
142 { | |
143 $this->data['Value'] = $value; | |
144 } | |
145 | |
146 /** | |
147 * Get the domain | |
148 * | |
149 * @return string|null | |
150 */ | |
151 public function getDomain() | |
152 { | |
153 return $this->data['Domain']; | |
154 } | |
155 | |
156 /** | |
157 * Set the domain of the cookie | |
158 * | |
159 * @param string $domain | |
160 */ | |
161 public function setDomain($domain) | |
162 { | |
163 $this->data['Domain'] = $domain; | |
164 } | |
165 | |
166 /** | |
167 * Get the path | |
168 * | |
169 * @return string | |
170 */ | |
171 public function getPath() | |
172 { | |
173 return $this->data['Path']; | |
174 } | |
175 | |
176 /** | |
177 * Set the path of the cookie | |
178 * | |
179 * @param string $path Path of the cookie | |
180 */ | |
181 public function setPath($path) | |
182 { | |
183 $this->data['Path'] = $path; | |
184 } | |
185 | |
186 /** | |
187 * Maximum lifetime of the cookie in seconds | |
188 * | |
189 * @return int|null | |
190 */ | |
191 public function getMaxAge() | |
192 { | |
193 return $this->data['Max-Age']; | |
194 } | |
195 | |
196 /** | |
197 * Set the max-age of the cookie | |
198 * | |
199 * @param int $maxAge Max age of the cookie in seconds | |
200 */ | |
201 public function setMaxAge($maxAge) | |
202 { | |
203 $this->data['Max-Age'] = $maxAge; | |
204 } | |
205 | |
206 /** | |
207 * The UNIX timestamp when the cookie Expires | |
208 * | |
209 * @return mixed | |
210 */ | |
211 public function getExpires() | |
212 { | |
213 return $this->data['Expires']; | |
214 } | |
215 | |
216 /** | |
217 * Set the unix timestamp for which the cookie will expire | |
218 * | |
219 * @param int $timestamp Unix timestamp | |
220 */ | |
221 public function setExpires($timestamp) | |
222 { | |
223 $this->data['Expires'] = is_numeric($timestamp) | |
224 ? (int) $timestamp | |
225 : strtotime($timestamp); | |
226 } | |
227 | |
228 /** | |
229 * Get whether or not this is a secure cookie | |
230 * | |
231 * @return null|bool | |
232 */ | |
233 public function getSecure() | |
234 { | |
235 return $this->data['Secure']; | |
236 } | |
237 | |
238 /** | |
239 * Set whether or not the cookie is secure | |
240 * | |
241 * @param bool $secure Set to true or false if secure | |
242 */ | |
243 public function setSecure($secure) | |
244 { | |
245 $this->data['Secure'] = $secure; | |
246 } | |
247 | |
248 /** | |
249 * Get whether or not this is a session cookie | |
250 * | |
251 * @return null|bool | |
252 */ | |
253 public function getDiscard() | |
254 { | |
255 return $this->data['Discard']; | |
256 } | |
257 | |
258 /** | |
259 * Set whether or not this is a session cookie | |
260 * | |
261 * @param bool $discard Set to true or false if this is a session cookie | |
262 */ | |
263 public function setDiscard($discard) | |
264 { | |
265 $this->data['Discard'] = $discard; | |
266 } | |
267 | |
268 /** | |
269 * Get whether or not this is an HTTP only cookie | |
270 * | |
271 * @return bool | |
272 */ | |
273 public function getHttpOnly() | |
274 { | |
275 return $this->data['HttpOnly']; | |
276 } | |
277 | |
278 /** | |
279 * Set whether or not this is an HTTP only cookie | |
280 * | |
281 * @param bool $httpOnly Set to true or false if this is HTTP only | |
282 */ | |
283 public function setHttpOnly($httpOnly) | |
284 { | |
285 $this->data['HttpOnly'] = $httpOnly; | |
286 } | |
287 | |
288 /** | |
289 * Check if the cookie matches a path value. | |
290 * | |
291 * A request-path path-matches a given cookie-path if at least one of | |
292 * the following conditions holds: | |
293 * | |
294 * - The cookie-path and the request-path are identical. | |
295 * - The cookie-path is a prefix of the request-path, and the last | |
296 * character of the cookie-path is %x2F ("/"). | |
297 * - The cookie-path is a prefix of the request-path, and the first | |
298 * character of the request-path that is not included in the cookie- | |
299 * path is a %x2F ("/") character. | |
300 * | |
301 * @param string $requestPath Path to check against | |
302 * | |
303 * @return bool | |
304 */ | |
305 public function matchesPath($requestPath) | |
306 { | |
307 $cookiePath = $this->getPath(); | |
308 | |
309 // Match on exact matches or when path is the default empty "/" | |
310 if ($cookiePath === '/' || $cookiePath == $requestPath) { | |
311 return true; | |
312 } | |
313 | |
314 // Ensure that the cookie-path is a prefix of the request path. | |
315 if (0 !== strpos($requestPath, $cookiePath)) { | |
316 return false; | |
317 } | |
318 | |
319 // Match if the last character of the cookie-path is "/" | |
320 if (substr($cookiePath, -1, 1) === '/') { | |
321 return true; | |
322 } | |
323 | |
324 // Match if the first character not included in cookie path is "/" | |
325 return substr($requestPath, strlen($cookiePath), 1) === '/'; | |
326 } | |
327 | |
328 /** | |
329 * Check if the cookie matches a domain value | |
330 * | |
331 * @param string $domain Domain to check against | |
332 * | |
333 * @return bool | |
334 */ | |
335 public function matchesDomain($domain) | |
336 { | |
337 // Remove the leading '.' as per spec in RFC 6265. | |
338 // http://tools.ietf.org/html/rfc6265#section-5.2.3 | |
339 $cookieDomain = ltrim($this->getDomain(), '.'); | |
340 | |
341 // Domain not set or exact match. | |
342 if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { | |
343 return true; | |
344 } | |
345 | |
346 // Matching the subdomain according to RFC 6265. | |
347 // http://tools.ietf.org/html/rfc6265#section-5.1.3 | |
348 if (filter_var($domain, FILTER_VALIDATE_IP)) { | |
349 return false; | |
350 } | |
351 | |
352 return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/', $domain); | |
353 } | |
354 | |
355 /** | |
356 * Check if the cookie is expired | |
357 * | |
358 * @return bool | |
359 */ | |
360 public function isExpired() | |
361 { | |
362 return $this->getExpires() && time() > $this->getExpires(); | |
363 } | |
364 | |
365 /** | |
366 * Check if the cookie is valid according to RFC 6265 | |
367 * | |
368 * @return bool|string Returns true if valid or an error message if invalid | |
369 */ | |
370 public function validate() | |
371 { | |
372 // Names must not be empty, but can be 0 | |
373 $name = $this->getName(); | |
374 if (empty($name) && !is_numeric($name)) { | |
375 return 'The cookie name must not be empty'; | |
376 } | |
377 | |
378 // Check if any of the invalid characters are present in the cookie name | |
379 if (preg_match( | |
380 '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', | |
381 $name) | |
382 ) { | |
383 return 'Cookie name must not contain invalid characters: ASCII ' | |
384 . 'Control characters (0-31;127), space, tab and the ' | |
385 . 'following characters: ()<>@,;:\"/?={}'; | |
386 } | |
387 | |
388 // Value must not be empty, but can be 0 | |
389 $value = $this->getValue(); | |
390 if (empty($value) && !is_numeric($value)) { | |
391 return 'The cookie value must not be empty'; | |
392 } | |
393 | |
394 // Domains must not be empty, but can be 0 | |
395 // A "0" is not a valid internet domain, but may be used as server name | |
396 // in a private network. | |
397 $domain = $this->getDomain(); | |
398 if (empty($domain) && !is_numeric($domain)) { | |
399 return 'The cookie domain must not be empty'; | |
400 } | |
401 | |
402 return true; | |
403 } | |
404 } |