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;
 | 
						|
    }
 | 
						|
}
 | 
						|
?>
 |