PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/rainloop/v/0.0.0/app/libraries/GuzzleHttp/Cookie/SetCookie.php

https://gitlab.com/wuhang2003/rainloop-webmail
PHP | 410 lines | 387 code | 7 blank | 16 comment | 2 complexity | 76199ad71bcdbc3a3b22d26b8fe82494 MD5 | raw file
  1. <?php
  2. namespace GuzzleHttp\Cookie;
  3. use GuzzleHttp\ToArrayInterface;
  4. /**
  5. * Set-Cookie object
  6. */
  7. class SetCookie implements ToArrayInterface
  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. /** @var array Cookie data */
  22. private $data;
  23. /**
  24. * Create a new SetCookie object from a string
  25. *
  26. * @param string $cookie Set-Cookie header string
  27. *
  28. * @return self
  29. */
  30. public static function fromString($cookie)
  31. {
  32. // Create the default return array
  33. $data = self::$defaults;
  34. // Explode the cookie string using a series of semicolons
  35. $pieces = array_filter(array_map('trim', explode(';', $cookie)));
  36. // The name of the cookie (first kvp) must include an equal sign.
  37. if (empty($pieces) || !strpos($pieces[0], '=')) {
  38. return new self($data);
  39. }
  40. // Add the cookie pieces into the parsed data array
  41. foreach ($pieces as $part) {
  42. $cookieParts = explode('=', $part, 2);
  43. $key = trim($cookieParts[0]);
  44. $value = isset($cookieParts[1])
  45. ? trim($cookieParts[1], " \n\r\t\0\x0B\"")
  46. : true;
  47. // Only check for non-cookies when cookies have been found
  48. if (empty($data['Name'])) {
  49. $data['Name'] = $key;
  50. $data['Value'] = $value;
  51. } else {
  52. foreach (array_keys(self::$defaults) as $search) {
  53. if (!strcasecmp($search, $key)) {
  54. $data[$search] = $value;
  55. continue 2;
  56. }
  57. }
  58. $data[$key] = $value;
  59. }
  60. }
  61. return new self($data);
  62. }
  63. /**
  64. * @param array $data Array of cookie data provided by a Cookie parser
  65. */
  66. public function __construct(array $data = [])
  67. {
  68. $this->data = array_replace(self::$defaults, $data);
  69. // Extract the Expires value and turn it into a UNIX timestamp if needed
  70. if (!$this->getExpires() && $this->getMaxAge()) {
  71. // Calculate the Expires date
  72. $this->setExpires(time() + $this->getMaxAge());
  73. } elseif ($this->getExpires() && !is_numeric($this->getExpires())) {
  74. $this->setExpires($this->getExpires());
  75. }
  76. }
  77. public function __toString()
  78. {
  79. $str = $this->data['Name'] . '=' . $this->data['Value'] . '; ';
  80. foreach ($this->data as $k => $v) {
  81. if ($k != 'Name' && $k != 'Value'&& $v !== null && $v !== false) {
  82. if ($k == 'Expires') {
  83. $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; ';
  84. } else {
  85. $str .= ($v === true ? $k : "{$k}={$v}") . '; ';
  86. }
  87. }
  88. }
  89. return rtrim($str, '; ');
  90. }
  91. public function toArray()
  92. {
  93. return $this->data;
  94. }
  95. /**
  96. * Get the cookie name
  97. *
  98. * @return string
  99. */
  100. public function getName()
  101. {
  102. return $this->data['Name'];
  103. }
  104. /**
  105. * Set the cookie name
  106. *
  107. * @param string $name Cookie name
  108. *
  109. * @return self
  110. */
  111. public function setName($name)
  112. {
  113. $this->data['Name'] = $name;
  114. return $this;
  115. }
  116. /**
  117. * Get the cookie value
  118. *
  119. * @return string
  120. */
  121. public function getValue()
  122. {
  123. return $this->data['Value'];
  124. }
  125. /**
  126. * Set the cookie value
  127. *
  128. * @param string $value Cookie value
  129. *
  130. * @return self
  131. */
  132. public function setValue($value)
  133. {
  134. $this->data['Value'] = $value;
  135. return $this;
  136. }
  137. /**
  138. * Get the domain
  139. *
  140. * @return string|null
  141. */
  142. public function getDomain()
  143. {
  144. return $this->data['Domain'];
  145. }
  146. /**
  147. * Set the domain of the cookie
  148. *
  149. * @param string $domain
  150. *
  151. * @return self
  152. */
  153. public function setDomain($domain)
  154. {
  155. $this->data['Domain'] = $domain;
  156. return $this;
  157. }
  158. /**
  159. * Get the path
  160. *
  161. * @return string
  162. */
  163. public function getPath()
  164. {
  165. return $this->data['Path'];
  166. }
  167. /**
  168. * Set the path of the cookie
  169. *
  170. * @param string $path Path of the cookie
  171. *
  172. * @return self
  173. */
  174. public function setPath($path)
  175. {
  176. $this->data['Path'] = $path;
  177. return $this;
  178. }
  179. /**
  180. * Maximum lifetime of the cookie in seconds
  181. *
  182. * @return int|null
  183. */
  184. public function getMaxAge()
  185. {
  186. return $this->data['Max-Age'];
  187. }
  188. /**
  189. * Set the max-age of the cookie
  190. *
  191. * @param int $maxAge Max age of the cookie in seconds
  192. *
  193. * @return self
  194. */
  195. public function setMaxAge($maxAge)
  196. {
  197. $this->data['Max-Age'] = $maxAge;
  198. return $this;
  199. }
  200. /**
  201. * The UNIX timestamp when the cookie Expires
  202. *
  203. * @return mixed
  204. */
  205. public function getExpires()
  206. {
  207. return $this->data['Expires'];
  208. }
  209. /**
  210. * Set the unix timestamp for which the cookie will expire
  211. *
  212. * @param int $timestamp Unix timestamp
  213. *
  214. * @return self
  215. */
  216. public function setExpires($timestamp)
  217. {
  218. $this->data['Expires'] = is_numeric($timestamp)
  219. ? (int) $timestamp
  220. : strtotime($timestamp);
  221. return $this;
  222. }
  223. /**
  224. * Get whether or not this is a secure cookie
  225. *
  226. * @return null|bool
  227. */
  228. public function getSecure()
  229. {
  230. return $this->data['Secure'];
  231. }
  232. /**
  233. * Set whether or not the cookie is secure
  234. *
  235. * @param bool $secure Set to true or false if secure
  236. *
  237. * @return self
  238. */
  239. public function setSecure($secure)
  240. {
  241. $this->data['Secure'] = $secure;
  242. return $this;
  243. }
  244. /**
  245. * Get whether or not this is a session cookie
  246. *
  247. * @return null|bool
  248. */
  249. public function getDiscard()
  250. {
  251. return $this->data['Discard'];
  252. }
  253. /**
  254. * Set whether or not this is a session cookie
  255. *
  256. * @param bool $discard Set to true or false if this is a session cookie
  257. *
  258. * @return self
  259. */
  260. public function setDiscard($discard)
  261. {
  262. $this->data['Discard'] = $discard;
  263. return $this;
  264. }
  265. /**
  266. * Get whether or not this is an HTTP only cookie
  267. *
  268. * @return bool
  269. */
  270. public function getHttpOnly()
  271. {
  272. return $this->data['HttpOnly'];
  273. }
  274. /**
  275. * Set whether or not this is an HTTP only cookie
  276. *
  277. * @param bool $httpOnly Set to true or false if this is HTTP only
  278. *
  279. * @return self
  280. */
  281. public function setHttpOnly($httpOnly)
  282. {
  283. $this->data['HttpOnly'] = $httpOnly;
  284. return $this;
  285. }
  286. /**
  287. * Check if the cookie matches a path value
  288. *
  289. * @param string $path Path to check against
  290. *
  291. * @return bool
  292. */
  293. public function matchesPath($path)
  294. {
  295. return !$this->getPath() || 0 === stripos($path, $this->getPath());
  296. }
  297. /**
  298. * Check if the cookie matches a domain value
  299. *
  300. * @param string $domain Domain to check against
  301. *
  302. * @return bool
  303. */
  304. public function matchesDomain($domain)
  305. {
  306. // Remove the leading '.' as per spec in RFC 6265.
  307. // http://tools.ietf.org/html/rfc6265#section-5.2.3
  308. $cookieDomain = ltrim($this->getDomain(), '.');
  309. // Domain not set or exact match.
  310. if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) {
  311. return true;
  312. }
  313. // Matching the subdomain according to RFC 6265.
  314. // http://tools.ietf.org/html/rfc6265#section-5.1.3
  315. if (filter_var($domain, FILTER_VALIDATE_IP)) {
  316. return false;
  317. }
  318. return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/i', $domain);
  319. }
  320. /**
  321. * Check if the cookie is expired
  322. *
  323. * @return bool
  324. */
  325. public function isExpired()
  326. {
  327. return $this->getExpires() && time() > $this->getExpires();
  328. }
  329. /**
  330. * Check if the cookie is valid according to RFC 6265
  331. *
  332. * @return bool|string Returns true if valid or an error message if invalid
  333. */
  334. public function validate()
  335. {
  336. // Names must not be empty, but can be 0
  337. $name = $this->getName();
  338. if (empty($name) && !is_numeric($name)) {
  339. return 'The cookie name must not be empty';
  340. }
  341. // Check if any of the invalid characters are present in the cookie name
  342. if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
  343. return "Cookie name must not cannot invalid characters: =,; \\t\\r\\n\\013\\014";
  344. }
  345. // Value must not be empty, but can be 0
  346. $value = $this->getValue();
  347. if (empty($value) && !is_numeric($value)) {
  348. return 'The cookie value must not be empty';
  349. }
  350. // Domains must not be empty, but can be 0
  351. // A "0" is not a valid internet domain, but may be used as server name
  352. // in a private network.
  353. $domain = $this->getDomain();
  354. if (empty($domain) && !is_numeric($domain)) {
  355. return 'The cookie domain must not be empty';
  356. }
  357. return true;
  358. }
  359. }