root/trunk/wp-includes/class-snoopy.php

Revision 1518, 36.6 kB (checked in by donncha, 3 weeks ago)

WP 2.6.3 security fix

  • Property svn:eol-style set to native
Line 
1 <?php
2 if ( !in_array('Snoopy', get_declared_classes() ) ) :
3 /*************************************************
4
5 Snoopy - the PHP net client
6 Author: Monte Ohrt <monte@ispi.net>
7 Copyright (c): 1999-2008 New Digital Group, all rights reserved
8 Version: 1.2.4
9
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24 You may contact the author of Snoopy by e-mail at:
25 monte@ohrt.com
26
27 The latest version of Snoopy can be obtained from:
28 http://snoopy.sourceforge.net/
29
30 *************************************************/
31
32 class Snoopy
33 {
34     /**** Public variables ****/
35
36     /* user definable vars */
37
38     var $host            =    "www.php.net";        // host name we are connecting to
39     var $port            =    80;                    // port we are connecting to
40     var $proxy_host        =    "";                    // proxy host to use
41     var $proxy_port        =    "";                    // proxy port to use
42     var $proxy_user        =    "";                    // proxy user to use
43     var $proxy_pass        =    "";                    // proxy password to use
44
45     var $agent            =    "Snoopy v1.2.4";    // agent we masquerade as
46     var    $referer        =    "";                    // referer info to pass
47     var $cookies        =    array();            // array of cookies to pass
48                                                 // $cookies["username"]="joe";
49     var    $rawheaders        =    array();            // array of raw headers to send
50                                                 // $rawheaders["Content-type"]="text/html";
51
52     var $maxredirs        =    5;                    // http redirection depth maximum. 0 = disallow
53     var $lastredirectaddr    =    "";                // contains address of last redirected address
54     var    $offsiteok        =    true;                // allows redirection off-site
55     var $maxframes        =    0;                    // frame content depth maximum. 0 = disallow
56     var $expandlinks    =    true;                // expand links to fully qualified URLs.
57                                                 // this only applies to fetchlinks()
58                                                 // submitlinks(), and submittext()
59     var $passcookies    =    true;                // pass set cookies back through redirects
60                                                 // NOTE: this currently does not respect
61                                                 // dates, domains or paths.
62
63     var    $user            =    "";                    // user for http authentication
64     var    $pass            =    "";                    // password for http authentication
65
66     // http accept types
67     var $accept            =    "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
68
69     var $results        =    "";                    // where the content is put
70
71     var $error            =    "";                    // error messages sent here
72     var    $response_code    =    "";                    // response code returned from server
73     var    $headers        =    array();            // headers returned from server sent here
74     var    $maxlength        =    500000;                // max return data length (body)
75     var $read_timeout    =    0;                    // timeout on read operations, in seconds
76                                                 // supported only since PHP 4 Beta 4
77                                                 // set to 0 to disallow timeouts
78     var $timed_out        =    false;                // if a read operation timed out
79     var    $status            =    0;                    // http request status
80
81     var $temp_dir        =    "/tmp";                // temporary directory that the webserver
82                                                 // has permission to write to.
83                                                 // under Windows, this should be C:\temp
84
85     var    $curl_path        =    "/usr/local/bin/curl";
86                                                 // Snoopy will use cURL for fetching
87                                                 // SSL content if a full system path to
88                                                 // the cURL binary is supplied here.
89                                                 // set to false if you do not have
90                                                 // cURL installed. See http://curl.haxx.se
91                                                 // for details on installing cURL.
92                                                 // Snoopy does *not* use the cURL
93                                                 // library functions built into php,
94                                                 // as these functions are not stable
95                                                 // as of this Snoopy release.
96
97     /**** Private variables ****/
98
99     var    $_maxlinelen    =    4096;                // max line length (headers)
100
101     var $_httpmethod    =    "GET";                // default http request method
102     var $_httpversion    =    "HTTP/1.0";            // default http request version
103     var $_submit_method    =    "POST";                // default submit method
104     var $_submit_type    =    "application/x-www-form-urlencoded";    // default submit type
105     var $_mime_boundary    =   "";                    // MIME boundary for multipart/form-data submit type
106     var $_redirectaddr    =    false;                // will be set if page fetched is a redirect
107     var $_redirectdepth    =    0;                    // increments on an http redirect
108     var $_frameurls        =     array();            // frame src urls
109     var $_framedepth    =    0;                    // increments on frame depth
110
111     var $_isproxy        =    false;                // set if using a proxy server
112     var $_fp_timeout    =    30;                    // timeout for socket connection
113
114 /*======================================================================*\
115     Function:    fetch
116     Purpose:    fetch the contents of a web page
117                 (and possibly other protocols in the
118                 future like ftp, nntp, gopher, etc.)
119     Input:        $URI    the location of the page to fetch
120     Output:        $this->results    the output text from the fetch
121 \*======================================================================*/
122
123     function fetch($URI)
124     {
125
126         //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
127         $URI_PARTS = parse_url($URI);
128         if (!empty($URI_PARTS["user"]))
129             $this->user = $URI_PARTS["user"];
130         if (!empty($URI_PARTS["pass"]))
131             $this->pass = $URI_PARTS["pass"];
132         if (empty($URI_PARTS["query"]))
133             $URI_PARTS["query"] = '';
134         if (empty($URI_PARTS["path"]))
135             $URI_PARTS["path"] = '';
136
137         switch(strtolower($URI_PARTS["scheme"]))
138         {
139             case "http":
140                 $this->host = $URI_PARTS["host"];
141                 if(!empty($URI_PARTS["port"]))
142                     $this->port = $URI_PARTS["port"];
143                 if($this->_connect($fp))
144                 {
145                     if($this->_isproxy)
146                     {
147                         // using proxy, send entire URI
148                         $this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
149                     }
150                     else
151                     {
152                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
153                         // no proxy, send only the path
154                         $this->_httprequest($path, $fp, $URI, $this->_httpmethod);
155                     }
156
157                     $this->_disconnect($fp);
158
159                     if($this->_redirectaddr)
160                     {
161                         /* url was redirected, check if we've hit the max depth */
162                         if($this->maxredirs > $this->_redirectdepth)
163                         {
164                             // only follow redirect if it's on this site, or offsiteok is true
165                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
166                             {
167                                 /* follow the redirect */
168                                 $this->_redirectdepth++;
169                                 $this->lastredirectaddr=$this->_redirectaddr;
170                                 $this->fetch($this->_redirectaddr);
171                             }
172                         }
173                     }
174
175                     if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
176                     {
177                         $frameurls = $this->_frameurls;
178                         $this->_frameurls = array();
179
180                         while(list(,$frameurl) = each($frameurls))
181                         {
182                             if($this->_framedepth < $this->maxframes)
183                             {
184                                 $this->fetch($frameurl);
185                                 $this->_framedepth++;
186                             }
187                             else
188                                 break;
189                         }
190                     }
191                 }
192                 else
193                 {
194                     return false;
195                 }
196                 return true;
197                 break;
198             case "https":
199                 if(!$this->curl_path)
200                     return false;
201                 if(function_exists("is_executable"))
202                     if (!is_executable($this->curl_path))
203                         return false;
204                 $this->host = $URI_PARTS["host"];
205                 if(!empty($URI_PARTS["port"]))
206                     $this->port = $URI_PARTS["port"];
207                 if($this->_isproxy)
208                 {
209                     // using proxy, send entire URI
210                     $this->_httpsrequest($URI,$URI,$this->_httpmethod);
211                 }
212                 else
213                 {
214                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
215                     // no proxy, send only the path
216                     $this->_httpsrequest($path, $URI, $this->_httpmethod);
217                 }
218
219                 if($this->_redirectaddr)
220                 {
221                     /* url was redirected, check if we've hit the max depth */
222                     if($this->maxredirs > $this->_redirectdepth)
223                     {
224                         // only follow redirect if it's on this site, or offsiteok is true
225                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
226                         {
227                             /* follow the redirect */
228                             $this->_redirectdepth++;
229                             $this->lastredirectaddr=$this->_redirectaddr;
230                             $this->fetch($this->_redirectaddr);
231                         }
232                     }
233                 }
234
235                 if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
236                 {
237                     $frameurls = $this->_frameurls;
238                     $this->_frameurls = array();
239
240                     while(list(,$frameurl) = each($frameurls))
241                     {
242                         if($this->_framedepth < $this->maxframes)
243                         {
244                             $this->fetch($frameurl);
245                             $this->_framedepth++;
246                         }
247                         else
248                             break;
249                     }
250                 }
251                 return true;
252                 break;
253             default:
254                 // not a valid protocol
255                 $this->error    =    'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
256                 return false;
257                 break;
258         }
259         return true;
260     }
261
262 /*======================================================================*\
263     Function:    submit
264     Purpose:    submit an http form
265     Input:        $URI    the location to post the data
266                 $formvars    the formvars to use.
267                     format: $formvars["var"] = "val";
268                 $formfiles  an array of files to submit
269                     format: $formfiles["var"] = "/dir/filename.ext";
270     Output:        $this->results    the text output from the post
271 \*======================================================================*/
272
273     function submit($URI, $formvars="", $formfiles="")
274     {
275         unset($postdata);
276
277         $postdata = $this->_prepare_post_body($formvars, $formfiles);
278
279         $URI_PARTS = parse_url($URI);
280         if (!empty($URI_PARTS["user"]))
281             $this->user = $URI_PARTS["user"];
282         if (!empty($URI_PARTS["pass"]))
283             $this->pass = $URI_PARTS["pass"];
284         if (empty($URI_PARTS["query"]))
285             $URI_PARTS["query"] = '';
286         if (empty($URI_PARTS["path"]))
287             $URI_PARTS["path"] = '';
288
289         switch(strtolower($URI_PARTS["scheme"]))
290         {
291             case "http":
292                 $this->host = $URI_PARTS["host"];
293                 if(!empty($URI_PARTS["port"]))
294                     $this->port = $URI_PARTS["port"];
295                 if($this->_connect($fp))
296                 {
297                     if($this->_isproxy)
298                     {
299                         // using proxy, send entire URI
300                         $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata);
301                     }
302                     else
303                     {
304                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
305                         // no proxy, send only the path
306                         $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
307                     }
308
309                     $this->_disconnect($fp);
310
311                     if($this->_redirectaddr)
312                     {
313                         /* url was redirected, check if we've hit the max depth */
314                         if($this->maxredirs > $this->_redirectdepth)
315                         {
316                             if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
317                                 $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);
318
319                             // only follow redirect if it's on this site, or offsiteok is true
320                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
321                             {
322                                 /* follow the redirect */
323                                 $this->_redirectdepth++;
324                                 $this->lastredirectaddr=$this->_redirectaddr;
325                                 if( strpos( $this->_redirectaddr, "?" ) > 0 )
326                                     $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
327                                 else
328                                     $this->submit($this->_redirectaddr,$formvars, $formfiles);
329                             }
330                         }
331                     }
332
333                     if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
334                     {
335                         $frameurls = $this->_frameurls;
336                         $this->_frameurls = array();
337
338                         while(list(,$frameurl) = each($frameurls))
339                         {
340                             if($this->_framedepth < $this->maxframes)
341                             {
342                                 $this->fetch($frameurl);
343                                 $this->_framedepth++;
344                             }
345                             else
346                                 break;
347                         }
348                     }
349
350                 }
351                 else
352                 {
353                     return false;
354                 }
355                 return true;
356                 break;
357             case "https":
358                 if(!$this->curl_path)
359                     return false;
360                 if(function_exists("is_executable"))
361                     if (!is_executable($this->curl_path))
362                         return false;
363                 $this->host = $URI_PARTS["host"];
364                 if(!empty($URI_PARTS["port"]))
365                     $this->port = $URI_PARTS["port"];
366                 if($this->_isproxy)
367                 {
368                     // using proxy, send entire URI
369                     $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);
370                 }
371                 else
372                 {
373                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
374                     // no proxy, send only the path
375                     $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);
376                 }
377
378                 if($this->_redirectaddr)
379                 {
380                     /* url was redirected, check if we've hit the max depth */
381                     if($this->maxredirs > $this->_redirectdepth)
382                     {
383                         if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
384                             $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);
385
386                         // only follow redirect if it's on this site, or offsiteok is true
387                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
388                         {
389                             /* follow the redirect */
390                             $this->_redirectdepth++;
391                             $this->lastredirectaddr=$this->_redirectaddr;
392                             if( strpos( $this->_redirectaddr, "?" ) > 0 )
393                                 $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
394                             else
395                                 $this->submit($this->_redirectaddr,$formvars, $formfiles);
396                         }
397                     }
398                 }
399
400                 if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
401                 {
402                     $frameurls = $this->_frameurls;
403                     $this->_frameurls = array();
404
405                     while(list(,$frameurl) = each($frameurls))
406                     {
407                         if($this->_framedepth < $this->maxframes)
408                         {
409                             $this->fetch($frameurl);
410                             $this->_framedepth++;
411                         }
412                         else
413                             break;
414                     }
415                 }
416                 return true;
417                 break;
418
419             default:
420                 // not a valid protocol
421                 $this->error    =    'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
422                 return false;
423                 break;
424         }
425         return true;
426     }
427
428 /*======================================================================*\
429