Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
    /**
3
     *	Base include file for SimpleTest
4
     *	@package	SimpleTest
5
     *	@subpackage	WebTester
6
     *	@version	$Id: cookies.php 1398 2006-09-08 19:31:03Z xue $
7
     */
8
 
9
    /**#@+
10
     *	include other SimpleTest class files
11
     */
12
    require_once(dirname(__FILE__) . '/url.php');
13
    /**#@-*/
14
 
15
    /**
16
     *    Cookie data holder. Cookie rules are full of pretty
17
     *    arbitary stuff. I have used...
18
     *    http://wp.netscape.com/newsref/std/cookie_spec.html
19
     *    http://www.cookiecentral.com/faq/
20
	 *    @package SimpleTest
21
	 *    @subpackage WebTester
22
     */
23
    class SimpleCookie {
24
        protected $_host;
25
        protected $_name;
26
        protected $_value;
27
        protected $_path;
28
        protected $_expiry;
29
        protected $_is_secure;
30
 
31
        /**
32
         *    Constructor. Sets the stored values.
33
         *    @param string $name            Cookie key.
34
         *    @param string $value           Value of cookie.
35
         *    @param string $path            Cookie path if not host wide.
36
         *    @param string $expiry          Expiry date as string.
37
         *    @param boolean $is_secure      Currently ignored.
38
         */
39
        function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
40
            $this->_host = false;
41
            $this->_name = $name;
42
            $this->_value = $value;
43
            $this->_path = ($path ? $this->_fixPath($path) : "/");
44
            $this->_expiry = false;
45
            if (is_string($expiry)) {
46
                $this->_expiry = strtotime($expiry);
47
            } elseif (is_integer($expiry)) {
48
                $this->_expiry = $expiry;
49
            }
50
            $this->_is_secure = $is_secure;
51
        }
52
 
53
        /**
54
         *    Sets the host. The cookie rules determine
55
         *    that the first two parts are taken for
56
         *    certain TLDs and three for others. If the
57
         *    new host does not match these rules then the
58
         *    call will fail.
59
         *    @param string $host       New hostname.
60
         *    @return boolean           True if hostname is valid.
61
         *    @access public
62
         */
63
        function setHost($host) {
64
            if ($host = $this->_truncateHost($host)) {
65
                $this->_host = $host;
66
                return true;
67
            }
68
            return false;
69
        }
70
 
71
        /**
72
         *    Accessor for the truncated host to which this
73
         *    cookie applies.
74
         *    @return string       Truncated hostname.
75
         *    @access public
76
         */
77
        function getHost() {
78
            return $this->_host;
79
        }
80
 
81
        /**
82
         *    Test for a cookie being valid for a host name.
83
         *    @param string $host    Host to test against.
84
         *    @return boolean        True if the cookie would be valid
85
         *                           here.
86
         */
87
        function isValidHost($host) {
88
            return ($this->_truncateHost($host) === $this->getHost());
89
        }
90
 
91
        /**
92
         *    Extracts just the domain part that determines a
93
         *    cookie's host validity.
94
         *    @param string $host    Host name to truncate.
95
         *    @return string        Domain or false on a bad host.
96
         *    @access private
97
         */
98
        function _truncateHost($host) {
99
            $tlds = SimpleUrl::getAllTopLevelDomains();
100
            if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
101
                return $matches[0];
102
            } elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
103
                return $matches[0];
104
            }
105
            return false;
106
        }
107
 
108
        /**
109
         *    Accessor for name.
110
         *    @return string       Cookie key.
111
         *    @access public
112
         */
113
        function getName() {
114
            return $this->_name;
115
        }
116
 
117
        /**
118
         *    Accessor for value. A deleted cookie will
119
         *    have an empty string for this.
120
         *    @return string       Cookie value.
121
         *    @access public
122
         */
123
        function getValue() {
124
            return $this->_value;
125
        }
126
 
127
        /**
128
         *    Accessor for path.
129
         *    @return string       Valid cookie path.
130
         *    @access public
131
         */
132
        function getPath() {
133
            return $this->_path;
134
        }
135
 
136
        /**
137
         *    Tests a path to see if the cookie applies
138
         *    there. The test path must be longer or
139
         *    equal to the cookie path.
140
         *    @param string $path       Path to test against.
141
         *    @return boolean           True if cookie valid here.
142
         *    @access public
143
         */
144
        function isValidPath($path) {
145
            return (strncmp(
146
                    $this->_fixPath($path),
147
                    $this->getPath(),
148
                    strlen($this->getPath())) == 0);
149
        }
150
 
151
        /**
152
         *    Accessor for expiry.
153
         *    @return string       Expiry string.
154
         *    @access public
155
         */
156
        function getExpiry() {
157
            if (! $this->_expiry) {
158
                return false;
159
            }
160
            return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
161
        }
162
 
163
        /**
164
         *    Test to see if cookie is expired against
165
         *    the cookie format time or timestamp.
166
         *    Will give true for a session cookie.
167
         *    @param integer/string $now  Time to test against. Result
168
         *                                will be false if this time
169
         *                                is later than the cookie expiry.
170
         *                                Can be either a timestamp integer
171
         *                                or a cookie format date.
172
         *    @access public
173
         */
174
        function isExpired($now) {
175
            if (! $this->_expiry) {
176
                return true;
177
            }
178
            if (is_string($now)) {
179
                $now = strtotime($now);
180
            }
181
            return ($this->_expiry < $now);
182
        }
183
 
184
        /**
185
         *    Ages the cookie by the specified number of
186
         *    seconds.
187
         *    @param integer $interval   In seconds.
188
         *    @public
189
         */
190
        function agePrematurely($interval) {
191
            if ($this->_expiry) {
192
                $this->_expiry -= $interval;
193
            }
194
        }
195
 
196
        /**
197
         *    Accessor for the secure flag.
198
         *    @return boolean       True if cookie needs SSL.
199
         *    @access public
200
         */
201
        function isSecure() {
202
            return $this->_is_secure;
203
        }
204
 
205
        /**
206
         *    Adds a trailing and leading slash to the path
207
         *    if missing.
208
         *    @param string $path            Path to fix.
209
         *    @access private
210
         */
211
        function _fixPath($path) {
212
            if (substr($path, 0, 1) != '/') {
213
                $path = '/' . $path;
214
            }
215
            if (substr($path, -1, 1) != '/') {
216
                $path .= '/';
217
            }
218
            return $path;
219
        }
220
    }
221
 
222
    /**
223
     *    Repository for cookies. This stuff is a
224
     *    tiny bit browser dependent.
225
	 *    @package SimpleTest
226
	 *    @subpackage WebTester
227
     */
228
    class SimpleCookieJar {
229
        protected $_cookies;
230
 
231
        /**
232
         *    Constructor. Jar starts empty.
233
         *    @access public
234
         */
235
        function SimpleCookieJar() {
236
            $this->_cookies = array();
237
        }
238
 
239
        /**
240
         *    Removes expired and temporary cookies as if
241
         *    the browser was closed and re-opened.
242
         *    @param string/integer $now   Time to test expiry against.
243
         *    @access public
244
         */
245
        function restartSession($date = false) {
246
            $surviving_cookies = array();
247
            for ($i = 0; $i < count($this->_cookies); $i++) {
248
                if (! $this->_cookies[$i]->getValue()) {
249
                    continue;
250
                }
251
                if (! $this->_cookies[$i]->getExpiry()) {
252
                    continue;
253
                }
254
                if ($date && $this->_cookies[$i]->isExpired($date)) {
255
                    continue;
256
                }
257
                $surviving_cookies[] = $this->_cookies[$i];
258
            }
259
            $this->_cookies = $surviving_cookies;
260
        }
261
 
262
        /**
263
         *    Ages all cookies in the cookie jar.
264
         *    @param integer $interval     The old session is moved
265
         *                                 into the past by this number
266
         *                                 of seconds. Cookies now over
267
         *                                 age will be removed.
268
         *    @access public
269
         */
270
        function agePrematurely($interval) {
271
            for ($i = 0; $i < count($this->_cookies); $i++) {
272
                $this->_cookies[$i]->agePrematurely($interval);
273
            }
274
        }
275
 
276
        /**
277
         *    Sets an additional cookie. If a cookie has
278
         *    the same name and path it is replaced.
279
         *    @param string $name       Cookie key.
280
         *    @param string $value      Value of cookie.
281
         *    @param string $host       Host upon which the cookie is valid.
282
         *    @param string $path       Cookie path if not host wide.
283
         *    @param string $expiry     Expiry date.
284
         *    @access public
285
         */
286
        function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
287
            $cookie = new SimpleCookie($name, $value, $path, $expiry);
288
            if ($host) {
289
                $cookie->setHost($host);
290
            }
291
            $this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
292
        }
293
 
294
        /**
295
         *    Finds a matching cookie to write over or the
296
         *    first empty slot if none.
297
         *    @param SimpleCookie $cookie    Cookie to write into jar.
298
         *    @return integer                Available slot.
299
         *    @access private
300
         */
301
        function _findFirstMatch($cookie) {
302
            for ($i = 0; $i < count($this->_cookies); $i++) {
303
                $is_match = $this->_isMatch(
304
                        $cookie,
305
                        $this->_cookies[$i]->getHost(),
306
                        $this->_cookies[$i]->getPath(),
307
                        $this->_cookies[$i]->getName());
308
                if ($is_match) {
309
                    return $i;
310
                }
311
            }
312
            return count($this->_cookies);
313
        }
314
 
315
        /**
316
         *    Reads the most specific cookie value from the
317
         *    browser cookies. Looks for the longest path that
318
         *    matches.
319
         *    @param string $host        Host to search.
320
         *    @param string $path        Applicable path.
321
         *    @param string $name        Name of cookie to read.
322
         *    @return string             False if not present, else the
323
         *                               value as a string.
324
         *    @access public
325
         */
326
        function getCookieValue($host, $path, $name) {
327
            $longest_path = '';
328
            foreach ($this->_cookies as $cookie) {
329
                if ($this->_isMatch($cookie, $host, $path, $name)) {
330
                    if (strlen($cookie->getPath()) > strlen($longest_path)) {
331
                        $value = $cookie->getValue();
332
                        $longest_path = $cookie->getPath();
333
                    }
334
                }
335
            }
336
            return (isset($value) ? $value : false);
337
        }
338
 
339
        /**
340
         *    Tests cookie for matching against search
341
         *    criteria.
342
         *    @param SimpleTest $cookie    Cookie to test.
343
         *    @param string $host          Host must match.
344
         *    @param string $path          Cookie path must be shorter than
345
         *                                 this path.
346
         *    @param string $name          Name must match.
347
         *    @return boolean              True if matched.
348
         *    @access private
349
         */
350
        function _isMatch($cookie, $host, $path, $name) {
351
            if ($cookie->getName() != $name) {
352
                return false;
353
            }
354
            if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
355
                return false;
356
            }
357
            if (! $cookie->isValidPath($path)) {
358
                return false;
359
            }
360
            return true;
361
        }
362
 
363
        /**
364
         *    Uses a URL to sift relevant cookies by host and
365
         *    path. Results are list of strings of form "name=value".
366
         *    @param SimpleUrl $url       Url to select by.
367
         *    @return array               Valid name and value pairs.
368
         *    @access public
369
         */
370
        function selectAsPairs($url) {
371
            $pairs = array();
372
            foreach ($this->_cookies as $cookie) {
373
                if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
374
                    $pairs[] = $cookie->getName() . '=' . $cookie->getValue();
375
                }
376
            }
377
            return $pairs;
378
        }
379
    }
380
?>