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: user_agent.php 1398 2006-09-08 19:31:03Z xue $
7
     */
8
 
9
    /**#@+
10
     *	include other SimpleTest class files
11
     */
12
    require_once(dirname(__FILE__) . '/cookies.php');
13
    require_once(dirname(__FILE__) . '/http.php');
14
    require_once(dirname(__FILE__) . '/encoding.php');
15
    require_once(dirname(__FILE__) . '/authentication.php');
16
    /**#@-*/
17
 
18
    if (! defined('DEFAULT_MAX_REDIRECTS')) {
19
        define('DEFAULT_MAX_REDIRECTS', 3);
20
    }
21
 
22
    if (! defined('DEFAULT_CONNECTION_TIMEOUT')) {
23
        define('DEFAULT_CONNECTION_TIMEOUT', 15);
24
    }
25
 
26
    /**
27
     *    Fetches web pages whilst keeping track of
28
     *    cookies and authentication.
29
	 *    @package SimpleTest
30
	 *    @subpackage WebTester
31
     */
32
    class SimpleUserAgent {
33
        protected $_cookie_jar;
34
        protected $_cookies_enabled = true;
35
        protected $_authenticator;
36
        protected $_max_redirects = DEFAULT_MAX_REDIRECTS;
37
        protected $_proxy = false;
38
        protected $_proxy_username = false;
39
        protected $_proxy_password = false;
40
        protected $_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
41
        protected $_additional_headers = array();
42
 
43
        /**
44
         *    Starts with no cookies, realms or proxies.
45
         *    @access public
46
         */
47
        function SimpleUserAgent() {
48
            $this->_cookie_jar = new SimpleCookieJar();
49
            $this->_authenticator = new SimpleAuthenticator();
50
        }
51
 
52
        /**
53
         *    Removes expired and temporary cookies as if
54
         *    the browser was closed and re-opened. Authorisation
55
         *    has to be obtained again as well.
56
         *    @param string/integer $date   Time when session restarted.
57
         *                                  If omitted then all persistent
58
         *                                  cookies are kept.
59
         *    @access public
60
         */
61
        function restart($date = false) {
62
            $this->_cookie_jar->restartSession($date);
63
            $this->_authenticator->restartSession();
64
        }
65
 
66
        /**
67
         *    Adds a header to every fetch.
68
         *    @param string $header       Header line to add to every
69
         *                                request until cleared.
70
         *    @access public
71
         */
72
        function addHeader($header) {
73
            $this->_additional_headers[] = $header;
74
        }
75
 
76
        /**
77
         *    Ages the cookies by the specified time.
78
         *    @param integer $interval    Amount in seconds.
79
         *    @access public
80
         */
81
        function ageCookies($interval) {
82
            $this->_cookie_jar->agePrematurely($interval);
83
        }
84
 
85
        /**
86
         *    Sets an additional cookie. If a cookie has
87
         *    the same name and path it is replaced.
88
         *    @param string $name            Cookie key.
89
         *    @param string $value           Value of cookie.
90
         *    @param string $host            Host upon which the cookie is valid.
91
         *    @param string $path            Cookie path if not host wide.
92
         *    @param string $expiry          Expiry date.
93
         *    @access public
94
         */
95
        function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
96
            $this->_cookie_jar->setCookie($name, $value, $host, $path, $expiry);
97
        }
98
 
99
        /**
100
         *    Reads the most specific cookie value from the
101
         *    browser cookies.
102
         *    @param string $host        Host to search.
103
         *    @param string $path        Applicable path.
104
         *    @param string $name        Name of cookie to read.
105
         *    @return string             False if not present, else the
106
         *                               value as a string.
107
         *    @access public
108
         */
109
        function getCookieValue($host, $path, $name) {
110
            return $this->_cookie_jar->getCookieValue($host, $path, $name);
111
        }
112
 
113
        /**
114
         *    Reads the current cookies within the base URL.
115
         *    @param string $name     Key of cookie to find.
116
         *    @param SimpleUrl $base  Base URL to search from.
117
         *    @return string/boolean  Null if there is no base URL, false
118
         *                            if the cookie is not set.
119
         *    @access public
120
         */
121
        function getBaseCookieValue($name, $base) {
122
            if (! $base) {
123
                return null;
124
            }
125
            return $this->getCookieValue($base->getHost(), $base->getPath(), $name);
126
        }
127
 
128
        /**
129
         *    Switches off cookie sending and recieving.
130
         *    @access public
131
         */
132
        function ignoreCookies() {
133
            $this->_cookies_enabled = false;
134
        }
135
 
136
        /**
137
         *    Switches back on the cookie sending and recieving.
138
         *    @access public
139
         */
140
        function useCookies() {
141
            $this->_cookies_enabled = true;
142
        }
143
 
144
        /**
145
         *    Sets the socket timeout for opening a connection.
146
         *    @param integer $timeout      Maximum time in seconds.
147
         *    @access public
148
         */
149
        function setConnectionTimeout($timeout) {
150
            $this->_connection_timeout = $timeout;
151
        }
152
 
153
        /**
154
         *    Sets the maximum number of redirects before
155
         *    a page will be loaded anyway.
156
         *    @param integer $max        Most hops allowed.
157
         *    @access public
158
         */
159
        function setMaximumRedirects($max) {
160
            $this->_max_redirects = $max;
161
        }
162
 
163
        /**
164
         *    Sets proxy to use on all requests for when
165
         *    testing from behind a firewall. Set URL
166
         *    to false to disable.
167
         *    @param string $proxy        Proxy URL.
168
         *    @param string $username     Proxy username for authentication.
169
         *    @param string $password     Proxy password for authentication.
170
         *    @access public
171
         */
172
        function useProxy($proxy, $username, $password) {
173
            if (! $proxy) {
174
                $this->_proxy = false;
175
                return;
176
            }
177
            if ((strncmp($proxy, 'http://', 7) != 0) && (strncmp($proxy, 'https://', 8) != 0)) {
178
                $proxy = 'http://'. $proxy;
179
            }
180
            $this->_proxy = new SimpleUrl($proxy);
181
            $this->_proxy_username = $username;
182
            $this->_proxy_password = $password;
183
        }
184
 
185
        /**
186
         *    Test to see if the redirect limit is passed.
187
         *    @param integer $redirects        Count so far.
188
         *    @return boolean                  True if over.
189
         *    @access private
190
         */
191
        function _isTooManyRedirects($redirects) {
192
            return ($redirects > $this->_max_redirects);
193
        }
194
 
195
        /**
196
         *    Sets the identity for the current realm.
197
         *    @param string $host        Host to which realm applies.
198
         *    @param string $realm       Full name of realm.
199
         *    @param string $username    Username for realm.
200
         *    @param string $password    Password for realm.
201
         *    @access public
202
         */
203
        function setIdentity($host, $realm, $username, $password) {
204
            $this->_authenticator->setIdentityForRealm($host, $realm, $username, $password);
205
        }
206
 
207
        /**
208
         *    Fetches a URL as a response object. Will keep trying if redirected.
209
         *    It will also collect authentication realm information.
210
         *    @param string/SimpleUrl $url      Target to fetch.
211
         *    @param SimpleEncoding $encoding   Additional parameters for request.
212
         *    @return SimpleHttpResponse        Hopefully the target page.
213
         *    @access public
214
         */
215
        function &fetchResponse($url, $encoding) {
216
            if ($encoding->getMethod() != 'POST') {
217
                $url->addRequestParameters($encoding);
218
                $encoding->clear();
219
            }
220
            $response = $this->_fetchWhileRedirected($url, $encoding);
221
            if ($headers = $response->getHeaders()) {
222
                if ($headers->isChallenge()) {
223
                    $this->_authenticator->addRealm(
224
                            $url,
225
                            $headers->getAuthentication(),
226
                            $headers->getRealm());
227
                }
228
            }
229
            return $response;
230
        }
231
 
232
        /**
233
         *    Fetches the page until no longer redirected or
234
         *    until the redirect limit runs out.
235
         *    @param SimpleUrl $url                  Target to fetch.
236
         *    @param SimpelFormEncoding $encoding    Additional parameters for request.
237
         *    @return SimpleHttpResponse             Hopefully the target page.
238
         *    @access private
239
         */
240
        function &_fetchWhileRedirected($url, $encoding) {
241
            $redirects = 0;
242
            do {
243
                $response = $this->_fetch($url, $encoding);
244
                if ($response->isError()) {
245
                    return $response;
246
                }
247
                $headers = $response->getHeaders();
248
                $location = new SimpleUrl($headers->getLocation());
249
                $url = $location->makeAbsolute($url);
250
                if ($this->_cookies_enabled) {
251
                    $headers->writeCookiesToJar($this->_cookie_jar, $url);
252
                }
253
                if (! $headers->isRedirect()) {
254
                    break;
255
                }
256
                $encoding = new SimpleGetEncoding();
257
            } while (! $this->_isTooManyRedirects(++$redirects));
258
            return $response;
259
        }
260
 
261
        /**
262
         *    Actually make the web request.
263
         *    @param SimpleUrl $url                   Target to fetch.
264
         *    @param SimpleFormEncoding $encoding     Additional parameters for request.
265
         *    @return SimpleHttpResponse              Headers and hopefully content.
266
         *    @access protected
267
         */
268
        function &_fetch($url, $encoding) {
269
            $request = $this->_createRequest($url, $encoding);
270
            $response = $request->fetch($this->_connection_timeout);
271
            return $response;
272
        }
273
 
274
        /**
275
         *    Creates a full page request.
276
         *    @param SimpleUrl $url                 Target to fetch as url object.
277
         *    @param SimpleFormEncoding $encoding   POST/GET parameters.
278
         *    @return SimpleHttpRequest             New request.
279
         *    @access private
280
         */
281
        function &_createRequest($url, $encoding) {
282
            $request = $this->_createHttpRequest($url, $encoding);
283
            $this->_addAdditionalHeaders($request);
284
            if ($this->_cookies_enabled) {
285
                $request->readCookiesFromJar($this->_cookie_jar, $url);
286
            }
287
            $this->_authenticator->addHeaders($request, $url);
288
            return $request;
289
        }
290
 
291
        /**
292
         *    Builds the appropriate HTTP request object.
293
         *    @param SimpleUrl $url                  Target to fetch as url object.
294
         *    @param SimpleFormEncoding $parameters  POST/GET parameters.
295
         *    @return SimpleHttpRequest              New request object.
296
         *    @access protected
297
         */
298
        function &_createHttpRequest($url, $encoding) {
299
            $request = new SimpleHttpRequest($this->_createRoute($url), $encoding);
300
            return $request;
301
        }
302
 
303
        /**
304
         *    Sets up either a direct route or via a proxy.
305
         *    @param SimpleUrl $url   Target to fetch as url object.
306
         *    @return SimpleRoute     Route to take to fetch URL.
307
         *    @access protected
308
         */
309
        function &_createRoute($url) {
310
            if ($this->_proxy) {
311
                $route = new SimpleProxyRoute(
312
                        $url,
313
                        $this->_proxy,
314
                        $this->_proxy_username,
315
                        $this->_proxy_password);
316
            } else {
317
                $route = new SimpleRoute($url);
318
            }
319
            return $route;
320
        }
321
 
322
        /**
323
         *    Adds additional manual headers.
324
         *    @param SimpleHttpRequest $request    Outgoing request.
325
         *    @access private
326
         */
327
        function _addAdditionalHeaders($request) {
328
            foreach ($this->_additional_headers as $header) {
329
                $request->addHeaderLine($header);
330
            }
331
        }
332
    }
333
?>