git-svn-id: file:///home/shish/svn/shimmie2/trunk@1068 7f39781d-f577-437e-ae19-be835c7a54ca
		
			
				
	
	
		
			380 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			380 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  *  Base include file for SimpleTest
 | |
|  *  @package    SimpleTest
 | |
|  *  @subpackage WebTester
 | |
|  *  @version    $Id: cookies.php 1723 2008-04-08 00:34:10Z lastcraft $
 | |
|  */
 | |
| 
 | |
| /**#@+
 | |
|  *  include other SimpleTest class files
 | |
|  */
 | |
| require_once(dirname(__FILE__) . '/url.php');
 | |
| /**#@-*/
 | |
| 
 | |
| /**
 | |
|  *    Cookie data holder. Cookie rules are full of pretty
 | |
|  *    arbitary stuff. I have used...
 | |
|  *    http://wp.netscape.com/newsref/std/cookie_spec.html
 | |
|  *    http://www.cookiecentral.com/faq/
 | |
|  *    @package SimpleTest
 | |
|  *    @subpackage WebTester
 | |
|  */
 | |
| class SimpleCookie {
 | |
|     var $_host;
 | |
|     var $_name;
 | |
|     var $_value;
 | |
|     var $_path;
 | |
|     var $_expiry;
 | |
|     var $_is_secure;
 | |
|     
 | |
|     /**
 | |
|      *    Constructor. Sets the stored values.
 | |
|      *    @param string $name            Cookie key.
 | |
|      *    @param string $value           Value of cookie.
 | |
|      *    @param string $path            Cookie path if not host wide.
 | |
|      *    @param string $expiry          Expiry date as string.
 | |
|      *    @param boolean $is_secure      Currently ignored.
 | |
|      */
 | |
|     function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
 | |
|         $this->_host = false;
 | |
|         $this->_name = $name;
 | |
|         $this->_value = $value;
 | |
|         $this->_path = ($path ? $this->_fixPath($path) : "/");
 | |
|         $this->_expiry = false;
 | |
|         if (is_string($expiry)) {
 | |
|             $this->_expiry = strtotime($expiry);
 | |
|         } elseif (is_integer($expiry)) {
 | |
|             $this->_expiry = $expiry;
 | |
|         }
 | |
|         $this->_is_secure = $is_secure;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Sets the host. The cookie rules determine
 | |
|      *    that the first two parts are taken for
 | |
|      *    certain TLDs and three for others. If the
 | |
|      *    new host does not match these rules then the
 | |
|      *    call will fail.
 | |
|      *    @param string $host       New hostname.
 | |
|      *    @return boolean           True if hostname is valid.
 | |
|      *    @access public
 | |
|      */
 | |
|     function setHost($host) {
 | |
|         if ($host = $this->_truncateHost($host)) {
 | |
|             $this->_host = $host;
 | |
|             return true;
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for the truncated host to which this
 | |
|      *    cookie applies.
 | |
|      *    @return string       Truncated hostname.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getHost() {
 | |
|         return $this->_host;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Test for a cookie being valid for a host name.
 | |
|      *    @param string $host    Host to test against.
 | |
|      *    @return boolean        True if the cookie would be valid
 | |
|      *                           here.
 | |
|      */
 | |
|     function isValidHost($host) {
 | |
|         return ($this->_truncateHost($host) === $this->getHost());
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Extracts just the domain part that determines a
 | |
|      *    cookie's host validity.
 | |
|      *    @param string $host    Host name to truncate.
 | |
|      *    @return string        Domain or false on a bad host.
 | |
|      *    @access private
 | |
|      */
 | |
|     function _truncateHost($host) {
 | |
|         $tlds = SimpleUrl::getAllTopLevelDomains();
 | |
|         if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
 | |
|             return $matches[0];
 | |
|         } elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
 | |
|             return $matches[0];
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for name.
 | |
|      *    @return string       Cookie key.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getName() {
 | |
|         return $this->_name;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for value. A deleted cookie will
 | |
|      *    have an empty string for this.
 | |
|      *    @return string       Cookie value.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getValue() {
 | |
|         return $this->_value;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for path.
 | |
|      *    @return string       Valid cookie path.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getPath() {
 | |
|         return $this->_path;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Tests a path to see if the cookie applies
 | |
|      *    there. The test path must be longer or
 | |
|      *    equal to the cookie path.
 | |
|      *    @param string $path       Path to test against.
 | |
|      *    @return boolean           True if cookie valid here.
 | |
|      *    @access public
 | |
|      */
 | |
|     function isValidPath($path) {
 | |
|         return (strncmp(
 | |
|                 $this->_fixPath($path),
 | |
|                 $this->getPath(),
 | |
|                 strlen($this->getPath())) == 0);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for expiry.
 | |
|      *    @return string       Expiry string.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getExpiry() {
 | |
|         if (! $this->_expiry) {
 | |
|             return false;
 | |
|         }
 | |
|         return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Test to see if cookie is expired against
 | |
|      *    the cookie format time or timestamp.
 | |
|      *    Will give true for a session cookie.
 | |
|      *    @param integer/string $now  Time to test against. Result
 | |
|      *                                will be false if this time
 | |
|      *                                is later than the cookie expiry.
 | |
|      *                                Can be either a timestamp integer
 | |
|      *                                or a cookie format date.
 | |
|      *    @access public
 | |
|      */
 | |
|     function isExpired($now) {
 | |
|         if (! $this->_expiry) {
 | |
|             return true;
 | |
|         }
 | |
|         if (is_string($now)) {
 | |
|             $now = strtotime($now);
 | |
|         }
 | |
|         return ($this->_expiry < $now);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Ages the cookie by the specified number of
 | |
|      *    seconds.
 | |
|      *    @param integer $interval   In seconds.
 | |
|      *    @public
 | |
|      */
 | |
|     function agePrematurely($interval) {
 | |
|         if ($this->_expiry) {
 | |
|             $this->_expiry -= $interval;
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Accessor for the secure flag.
 | |
|      *    @return boolean       True if cookie needs SSL.
 | |
|      *    @access public
 | |
|      */
 | |
|     function isSecure() {
 | |
|         return $this->_is_secure;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Adds a trailing and leading slash to the path
 | |
|      *    if missing.
 | |
|      *    @param string $path            Path to fix.
 | |
|      *    @access private
 | |
|      */
 | |
|     function _fixPath($path) {
 | |
|         if (substr($path, 0, 1) != '/') {
 | |
|             $path = '/' . $path;
 | |
|         }
 | |
|         if (substr($path, -1, 1) != '/') {
 | |
|             $path .= '/';
 | |
|         }
 | |
|         return $path;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  *    Repository for cookies. This stuff is a
 | |
|  *    tiny bit browser dependent.
 | |
|  *    @package SimpleTest
 | |
|  *    @subpackage WebTester
 | |
|  */
 | |
| class SimpleCookieJar {
 | |
|     var $_cookies;
 | |
|     
 | |
|     /**
 | |
|      *    Constructor. Jar starts empty.
 | |
|      *    @access public
 | |
|      */
 | |
|     function SimpleCookieJar() {
 | |
|         $this->_cookies = array();
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Removes expired and temporary cookies as if
 | |
|      *    the browser was closed and re-opened.
 | |
|      *    @param string/integer $now   Time to test expiry against.
 | |
|      *    @access public
 | |
|      */
 | |
|     function restartSession($date = false) {
 | |
|         $surviving_cookies = array();
 | |
|         for ($i = 0; $i < count($this->_cookies); $i++) {
 | |
|             if (! $this->_cookies[$i]->getValue()) {
 | |
|                 continue;
 | |
|             }
 | |
|             if (! $this->_cookies[$i]->getExpiry()) {
 | |
|                 continue;
 | |
|             }
 | |
|             if ($date && $this->_cookies[$i]->isExpired($date)) {
 | |
|                 continue;
 | |
|             }
 | |
|             $surviving_cookies[] = $this->_cookies[$i];
 | |
|         }
 | |
|         $this->_cookies = $surviving_cookies;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Ages all cookies in the cookie jar.
 | |
|      *    @param integer $interval     The old session is moved
 | |
|      *                                 into the past by this number
 | |
|      *                                 of seconds. Cookies now over
 | |
|      *                                 age will be removed.
 | |
|      *    @access public
 | |
|      */
 | |
|     function agePrematurely($interval) {
 | |
|         for ($i = 0; $i < count($this->_cookies); $i++) {
 | |
|             $this->_cookies[$i]->agePrematurely($interval);
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Sets an additional cookie. If a cookie has
 | |
|      *    the same name and path it is replaced.
 | |
|      *    @param string $name       Cookie key.
 | |
|      *    @param string $value      Value of cookie.
 | |
|      *    @param string $host       Host upon which the cookie is valid.
 | |
|      *    @param string $path       Cookie path if not host wide.
 | |
|      *    @param string $expiry     Expiry date.
 | |
|      *    @access public
 | |
|      */
 | |
|     function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
 | |
|         $cookie = new SimpleCookie($name, $value, $path, $expiry);
 | |
|         if ($host) {
 | |
|             $cookie->setHost($host);
 | |
|         }
 | |
|         $this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Finds a matching cookie to write over or the
 | |
|      *    first empty slot if none.
 | |
|      *    @param SimpleCookie $cookie    Cookie to write into jar.
 | |
|      *    @return integer                Available slot.
 | |
|      *    @access private
 | |
|      */
 | |
|     function _findFirstMatch($cookie) {
 | |
|         for ($i = 0; $i < count($this->_cookies); $i++) {
 | |
|             $is_match = $this->_isMatch(
 | |
|                     $cookie,
 | |
|                     $this->_cookies[$i]->getHost(),
 | |
|                     $this->_cookies[$i]->getPath(),
 | |
|                     $this->_cookies[$i]->getName());
 | |
|             if ($is_match) {
 | |
|                 return $i;
 | |
|             }
 | |
|         }
 | |
|         return count($this->_cookies);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Reads the most specific cookie value from the
 | |
|      *    browser cookies. Looks for the longest path that
 | |
|      *    matches.
 | |
|      *    @param string $host        Host to search.
 | |
|      *    @param string $path        Applicable path.
 | |
|      *    @param string $name        Name of cookie to read.
 | |
|      *    @return string             False if not present, else the
 | |
|      *                               value as a string.
 | |
|      *    @access public
 | |
|      */
 | |
|     function getCookieValue($host, $path, $name) {
 | |
|         $longest_path = '';
 | |
|         foreach ($this->_cookies as $cookie) {
 | |
|             if ($this->_isMatch($cookie, $host, $path, $name)) {
 | |
|                 if (strlen($cookie->getPath()) > strlen($longest_path)) {
 | |
|                     $value = $cookie->getValue();
 | |
|                     $longest_path = $cookie->getPath();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return (isset($value) ? $value : false);
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Tests cookie for matching against search
 | |
|      *    criteria.
 | |
|      *    @param SimpleTest $cookie    Cookie to test.
 | |
|      *    @param string $host          Host must match.
 | |
|      *    @param string $path          Cookie path must be shorter than
 | |
|      *                                 this path.
 | |
|      *    @param string $name          Name must match.
 | |
|      *    @return boolean              True if matched.
 | |
|      *    @access private
 | |
|      */
 | |
|     function _isMatch($cookie, $host, $path, $name) {
 | |
|         if ($cookie->getName() != $name) {
 | |
|             return false;
 | |
|         }
 | |
|         if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
 | |
|             return false;
 | |
|         }
 | |
|         if (! $cookie->isValidPath($path)) {
 | |
|             return false;
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      *    Uses a URL to sift relevant cookies by host and
 | |
|      *    path. Results are list of strings of form "name=value".
 | |
|      *    @param SimpleUrl $url       Url to select by.
 | |
|      *    @return array               Valid name and value pairs.
 | |
|      *    @access public
 | |
|      */
 | |
|     function selectAsPairs($url) {
 | |
|         $pairs = array();
 | |
|         foreach ($this->_cookies as $cookie) {
 | |
|             if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
 | |
|                 $pairs[] = $cookie->getName() . '=' . $cookie->getValue();
 | |
|             }
 | |
|         }
 | |
|         return $pairs;
 | |
|     }
 | |
| }
 | |
| ?>
 |