PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/w3-total-cache/lib/Microsoft/Http/CookieJar.php

https://github.com/sharpmachine/wakeupmedia.com
PHP | 406 lines | 179 code | 41 blank | 186 comment | 28 complexity | f458c85f3745721bcfa0bd4568071caa MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Microsoft
  16. * @package Microsoft_Http
  17. * @subpackage CookieJar
  18. * @version $Id: CookieJar.php 17131 2009-07-26 10:03:39Z shahar $
  19. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  20. * @license http://framework.zend.com/license/new-bsd New BSD License
  21. */
  22. if (!defined('W3TC')) {
  23. die();
  24. }
  25. /**
  26. * @see Microsoft_Uri
  27. */
  28. require_once "Microsoft/Uri.php";
  29. /**
  30. * @see Microsoft_Http_Cookie
  31. */
  32. require_once "Microsoft/Http/Cookie.php";
  33. /**
  34. * @see Microsoft_Http_Response
  35. */
  36. require_once "Microsoft/Http/Response.php";
  37. /**
  38. * A Microsoft_Http_CookieJar object is designed to contain and maintain HTTP cookies, and should
  39. * be used along with Microsoft_Http_Client in order to manage cookies across HTTP requests and
  40. * responses.
  41. *
  42. * The class contains an array of Microsoft_Http_Cookie objects. Cookies can be added to the jar
  43. * automatically from a request or manually. Then, the jar can find and return the cookies
  44. * needed for a specific HTTP request.
  45. *
  46. * A special parameter can be passed to all methods of this class that return cookies: Cookies
  47. * can be returned either in their native form (as Microsoft_Http_Cookie objects) or as strings -
  48. * the later is suitable for sending as the value of the "Cookie" header in an HTTP request.
  49. * You can also choose, when returning more than one cookie, whether to get an array of strings
  50. * (by passing Microsoft_Http_CookieJar::COOKIE_STRING_ARRAY) or one unified string for all cookies
  51. * (by passing Microsoft_Http_CookieJar::COOKIE_STRING_CONCAT).
  52. *
  53. * @link http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
  54. *
  55. * @category Microsoft
  56. * @package Microsoft_Http
  57. * @subpackage CookieJar
  58. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  59. * @license http://framework.zend.com/license/new-bsd New BSD License
  60. */
  61. class Microsoft_Http_CookieJar implements Countable, IteratorAggregate
  62. {
  63. /**
  64. * Return cookie(s) as a Microsoft_Http_Cookie object
  65. *
  66. */
  67. const COOKIE_OBJECT = 0;
  68. /**
  69. * Return cookie(s) as a string (suitable for sending in an HTTP request)
  70. *
  71. */
  72. const COOKIE_STRING_ARRAY = 1;
  73. /**
  74. * Return all cookies as one long string (suitable for sending in an HTTP request)
  75. *
  76. */
  77. const COOKIE_STRING_CONCAT = 2;
  78. /**
  79. * Array storing cookies
  80. *
  81. * Cookies are stored according to domain and path:
  82. * $cookies
  83. * + www.mydomain.com
  84. * + /
  85. * - cookie1
  86. * - cookie2
  87. * + /somepath
  88. * - othercookie
  89. * + www.otherdomain.net
  90. * + /
  91. * - alsocookie
  92. *
  93. * @var array
  94. */
  95. protected $cookies = array();
  96. /**
  97. * The Microsoft_Http_Cookie array
  98. *
  99. * @var array
  100. */
  101. protected $_rawCookies = array();
  102. /**
  103. * Construct a new CookieJar object
  104. *
  105. */
  106. public function __construct()
  107. { }
  108. /**
  109. * Add a cookie to the jar. Cookie should be passed either as a Microsoft_Http_Cookie object
  110. * or as a string - in which case an object is created from the string.
  111. *
  112. * @param Microsoft_Http_Cookie|string $cookie
  113. * @param Microsoft_Uri_Http|string $ref_uri Optional reference URI (for domain, path, secure)
  114. */
  115. public function addCookie($cookie, $ref_uri = null)
  116. {
  117. if (is_string($cookie)) {
  118. $cookie = Microsoft_Http_Cookie::fromString($cookie, $ref_uri);
  119. }
  120. if ($cookie instanceof Microsoft_Http_Cookie) {
  121. $domain = $cookie->getDomain();
  122. $path = $cookie->getPath();
  123. if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array();
  124. if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array();
  125. $this->cookies[$domain][$path][$cookie->getName()] = $cookie;
  126. $this->_rawCookies[] = $cookie;
  127. } else {
  128. require_once 'Microsoft/Http/Exception.php';
  129. throw new Microsoft_Http_Exception('Supplient argument is not a valid cookie string or object');
  130. }
  131. }
  132. /**
  133. * Parse an HTTP response, adding all the cookies set in that response
  134. * to the cookie jar.
  135. *
  136. * @param Microsoft_Http_Response $response
  137. * @param Microsoft_Uri_Http|string $ref_uri Requested URI
  138. */
  139. public function addCookiesFromResponse($response, $ref_uri)
  140. {
  141. if (! $response instanceof Microsoft_Http_Response) {
  142. require_once 'Microsoft/Http/Exception.php';
  143. throw new Microsoft_Http_Exception('$response is expected to be a Response object, ' .
  144. gettype($response) . ' was passed');
  145. }
  146. $cookie_hdrs = $response->getHeader('Set-Cookie');
  147. if (is_array($cookie_hdrs)) {
  148. foreach ($cookie_hdrs as $cookie) {
  149. $this->addCookie($cookie, $ref_uri);
  150. }
  151. } elseif (is_string($cookie_hdrs)) {
  152. $this->addCookie($cookie_hdrs, $ref_uri);
  153. }
  154. }
  155. /**
  156. * Get all cookies in the cookie jar as an array
  157. *
  158. * @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
  159. * @return array|string
  160. */
  161. public function getAllCookies($ret_as = self::COOKIE_OBJECT)
  162. {
  163. $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
  164. return $cookies;
  165. }
  166. /**
  167. * Return an array of all cookies matching a specific request according to the request URI,
  168. * whether session cookies should be sent or not, and the time to consider as "now" when
  169. * checking cookie expiry time.
  170. *
  171. * @param string|Microsoft_Uri_Http $uri URI to check against (secure, domain, path)
  172. * @param boolean $matchSessionCookies Whether to send session cookies
  173. * @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
  174. * @param int $now Override the current time when checking for expiry time
  175. * @return array|string
  176. */
  177. public function getMatchingCookies($uri, $matchSessionCookies = true,
  178. $ret_as = self::COOKIE_OBJECT, $now = null)
  179. {
  180. if (is_string($uri)) $uri = Microsoft_Uri::factory($uri);
  181. if (! $uri instanceof Microsoft_Uri_Http) {
  182. require_once 'Microsoft/Http/Exception.php';
  183. throw new Microsoft_Http_Exception("Invalid URI string or object passed");
  184. }
  185. // First, reduce the array of cookies to only those matching domain and path
  186. $cookies = $this->_matchDomain($uri->getHost());
  187. $cookies = $this->_matchPath($cookies, $uri->getPath());
  188. $cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT);
  189. // Next, run Cookie->match on all cookies to check secure, time and session mathcing
  190. $ret = array();
  191. foreach ($cookies as $cookie)
  192. if ($cookie->match($uri, $matchSessionCookies, $now))
  193. $ret[] = $cookie;
  194. // Now, use self::_flattenCookiesArray again - only to convert to the return format ;)
  195. $ret = $this->_flattenCookiesArray($ret, $ret_as);
  196. return $ret;
  197. }
  198. /**
  199. * Get a specific cookie according to a URI and name
  200. *
  201. * @param Microsoft_Uri_Http|string $uri The uri (domain and path) to match
  202. * @param string $cookie_name The cookie's name
  203. * @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
  204. * @return Microsoft_Http_Cookie|string
  205. */
  206. public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
  207. {
  208. if (is_string($uri)) {
  209. $uri = Microsoft_Uri::factory($uri);
  210. }
  211. if (! $uri instanceof Microsoft_Uri_Http) {
  212. require_once 'Microsoft/Http/Exception.php';
  213. throw new Microsoft_Http_Exception('Invalid URI specified');
  214. }
  215. // Get correct cookie path
  216. $path = $uri->getPath();
  217. $path = substr($path, 0, strrpos($path, '/'));
  218. if (! $path) $path = '/';
  219. if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) {
  220. $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name];
  221. switch ($ret_as) {
  222. case self::COOKIE_OBJECT:
  223. return $cookie;
  224. break;
  225. case self::COOKIE_STRING_ARRAY:
  226. case self::COOKIE_STRING_CONCAT:
  227. return $cookie->__toString();
  228. break;
  229. default:
  230. require_once 'Microsoft/Http/Exception.php';
  231. throw new Microsoft_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
  232. break;
  233. }
  234. } else {
  235. return false;
  236. }
  237. }
  238. /**
  239. * Helper function to recursivly flatten an array. Shoud be used when exporting the
  240. * cookies array (or parts of it)
  241. *
  242. * @param Microsoft_Http_Cookie|array $ptr
  243. * @param int $ret_as What value to return
  244. * @return array|string
  245. */
  246. protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
  247. if (is_array($ptr)) {
  248. $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
  249. foreach ($ptr as $item) {
  250. if ($ret_as == self::COOKIE_STRING_CONCAT) {
  251. $ret .= $this->_flattenCookiesArray($item, $ret_as);
  252. } else {
  253. $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as));
  254. }
  255. }
  256. return $ret;
  257. } elseif ($ptr instanceof Microsoft_Http_Cookie) {
  258. switch ($ret_as) {
  259. case self::COOKIE_STRING_ARRAY:
  260. return array($ptr->__toString());
  261. break;
  262. case self::COOKIE_STRING_CONCAT:
  263. return $ptr->__toString();
  264. break;
  265. case self::COOKIE_OBJECT:
  266. default:
  267. return array($ptr);
  268. break;
  269. }
  270. }
  271. return null;
  272. }
  273. /**
  274. * Return a subset of the cookies array matching a specific domain
  275. *
  276. * @param string $domain
  277. * @return array
  278. */
  279. protected function _matchDomain($domain)
  280. {
  281. $ret = array();
  282. foreach (array_keys($this->cookies) as $cdom) {
  283. if (Microsoft_Http_Cookie::matchCookieDomain($cdom, $domain)) {
  284. $ret[$cdom] = $this->cookies[$cdom];
  285. }
  286. }
  287. return $ret;
  288. }
  289. /**
  290. * Return a subset of a domain-matching cookies that also match a specified path
  291. *
  292. * @param array $dom_array
  293. * @param string $path
  294. * @return array
  295. */
  296. protected function _matchPath($domains, $path)
  297. {
  298. $ret = array();
  299. foreach ($domains as $dom => $paths_array) {
  300. foreach (array_keys($paths_array) as $cpath) {
  301. if (Microsoft_Http_Cookie::matchCookiePath($cpath, $path)) {
  302. if (! isset($ret[$dom])) {
  303. $ret[$dom] = array();
  304. }
  305. $ret[$dom][$cpath] = $paths_array[$cpath];
  306. }
  307. }
  308. }
  309. return $ret;
  310. }
  311. /**
  312. * Create a new CookieJar object and automatically load into it all the
  313. * cookies set in an Http_Response object. If $uri is set, it will be
  314. * considered as the requested URI for setting default domain and path
  315. * of the cookie.
  316. *
  317. * @param Microsoft_Http_Response $response HTTP Response object
  318. * @param Microsoft_Uri_Http|string $uri The requested URI
  319. * @return Microsoft_Http_CookieJar
  320. * @todo Add the $uri functionality.
  321. */
  322. public static function fromResponse(Microsoft_Http_Response $response, $ref_uri)
  323. {
  324. $jar = new self();
  325. $jar->addCookiesFromResponse($response, $ref_uri);
  326. return $jar;
  327. }
  328. /**
  329. * Required by Countable interface
  330. *
  331. * @return int
  332. */
  333. public function count()
  334. {
  335. return count($this->_rawCookies);
  336. }
  337. /**
  338. * Required by IteratorAggregate interface
  339. *
  340. * @return ArrayIterator
  341. */
  342. public function getIterator()
  343. {
  344. return new ArrayIterator($this->_rawCookies);
  345. }
  346. /**
  347. * Tells if the jar is empty of any cookie
  348. *
  349. * @return bool
  350. */
  351. public function isEmpty()
  352. {
  353. return count($this) == 0;
  354. }
  355. /**
  356. * Empties the cookieJar of any cookie
  357. *
  358. * @return Microsoft_Http_CookieJar
  359. */
  360. public function reset()
  361. {
  362. $this->cookies = $this->_rawCookies = array();
  363. return $this;
  364. }
  365. }