Microsoft_Http
[ class tree: Microsoft_Http ] [ index: Microsoft_Http ] [ all elements ]

Source for file CookieJar.php

Documentation is available at CookieJar.php

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

Documentation generated on Wed, 18 May 2011 12:06:27 +0200 by phpDocumentor 1.4.3