root/branches/2.6/wp-includes/class-snoopy.php

Revision 1507, 36.6 kB (checked in by donncha, 8 months ago)

WP Merge

  • 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     Function:    fetchlinks
430     Purpose:    fetch the links from a web page
431     Input:        $URI    where you are fetching from
432     Output:        $this->results    an array of the URLs
433 \*======================================================================*/
434
435     function fetchlinks($URI)
436     {
437         if ($this->fetch($URI))
438         {
439             if($this->lastredirectaddr)
440                 $URI = $this->lastredirectaddr;
441             if(is_array($this->results))
442             {
443                 for($x=0;$x<count($this->results);$x++)
444                     $this->results[$x] = $this->_striplinks($this->results[$x]);
445             }
446             else
447                 $this->results = $this->_striplinks($this->results);
448
449             if($this->expandlinks)
450                 $this->results = $this->_expandlinks($this->results, $URI);
451             return true;
452         }
453         else
454             return false;
455     }
456
457 /*======================================================================*\
458     Function:    fetchform
459     Purpose:    fetch the form elements from a web page
460     Input:        $URI    where you are fetching from
461     Output:        $this->results    the resulting html form
462 \*======================================================================*/
463
464     function fetchform($URI)
465     {
466
467         if ($this->fetch($URI))
468         {
469
470             if(is_array($this->results))
471             {
472                 for($x=0;$x<count($this->results);$x++)
473                     $this->results[$x] = $this->_stripform($this->results[$x]);
474             }
475             else
476                 $this->results = $this->_stripform($this->results);
477
478             return true;
479         }
480         else
481             return false;
482     }
483
484
485 /*======================================================================*\
486     Function:    fetchtext
487     Purpose:    fetch the text from a web page, stripping the links
488     Input:        $URI    where you are fetching from
489     Output:        $this->results    the text from the web page
490 \*======================================================================*/
491
492     function fetchtext($URI)
493     {
494         if($this->fetch($URI))
495         {
496             if(is_array($this->results))
497             {
498                 for($x=0;$x<count($this->results);$x++)
499                     $this->results[$x] = $this->_striptext($this->results[$x]);
500             }
501             else
502                 $this->results = $this->_striptext($this->results);
503             return true;
504         }
505         else
506             return false;
507     }
508
509 /*======================================================================*\
510     Function:    submitlinks
511     Purpose:    grab links from a form submission
512     Input:        $URI    where you are submitting from
513     Output:        $this->results    an array of the links from the post
514 \*======================================================================*/
515
516     function submitlinks($URI, $formvars="", $formfiles="")
517     {
518         if($this->submit($URI,$formvars, $formfiles))
519         {
520             if($this->lastredirectaddr)
521                 $URI = $this->lastredirectaddr;
522             if(is_array($this->results))
523             {
524                 for($x=0;$x<count($this->results);$x++)
525                 {
526                     $this->results[$x] = $this->_striplinks($this->results[$x]);
527                     if($this->expandlinks)
528                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
529                 }
530             }
531             else
532             {
533                 $this->results = $this->_striplinks($this->results);
534                 if($this->expandlinks)
535                     $this->results = $this->_expandlinks($this->results,$URI);
536             }
537             return true;
538         }
539         else
540             return false;
541     }
542
543 /*======================================================================*\
544     Function:    submittext
545     Purpose:    grab text from a form submission
546     Input:        $URI    where you are submitting from
547     Output:        $this->results    the text from the web page
548 \*======================================================================*/
549
550     function submittext($URI, $formvars = "", $formfiles = "")
551     {
552         if($this->submit($URI,$formvars, $formfiles))
553         {
554             if($this->lastredirectaddr)
555                 $URI = $this->lastredirectaddr;
556             if(is_array($this->results))
557             {
558                 for($x=0;$x<count($this->results);$x++)
559                 {
560                     $this->results[$x] = $this->_striptext($this->results[$x]);
561                     if($this->expandlinks)
562                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
563                 }
564             }
565             else
566             {
567                 $this->results = $this->_striptext($this->results);
568                 if($this->expandlinks)
569                     $this->results = $this->_expandlinks($this->results,$URI);
570             }
571             return true;
572         }
573         else
574             return false;
575     }
576
577
578
579 /*======================================================================*\
580     Function:    set_submit_multipart
581     Purpose:    Set the form submission content type to
582                 multipart/form-data
583 \*======================================================================*/
584     function set_submit_multipart()
585     {
586         $this->_submit_type = "multipart/form-data";
587     }
588
589
590 /*======================================================================*\
591     Function:    set_submit_normal
592     Purpose:    Set the form submission content type to
593                 application/x-www-form-urlencoded
594 \*======================================================================*/
595     function set_submit_normal()
596     {
597         $this->_submit_type = "application/x-www-form-urlencoded";
598     }
599
600
601
602
603 /*======================================================================*\
604     Private functions
605 \*======================================================================*/
606
607
608 /*======================================================================*\
609     Function:    _striplinks
610     Purpose:    strip the hyperlinks from an html document
611     Input:        $document    document to strip.
612     Output:        $match        an array of the links
613 \*======================================================================*/
614
615     function _striplinks($document)
616     {
617         preg_match_all("'<\s*a\s.*?href\s*=\s*            # find <a href=
618                         ([\"\'])?                    # find single or double quote
619                         (?(1) (.*?)\\1 | ([^\s\>]+))        # if quote found, match up to next matching
620                                                     # quote, otherwise match up to next space
621                         'isx",$document,$links);
622
623
624         // catenate the non-empty matches from the conditional subpattern
625
626         while(list($key,$val) = each($links[2]))
627         {
628             if(!empty($val))
629                 $match[] = $val;
630         }
631
632         while(list($key,$val) = each($links[3]))
633         {
634             if(!empty($val))
635                 $match[] = $val;
636         }
637
638         // return the links
639         return $match;
640     }
641
642 /*======================================================================*\
643     Function:    _stripform
644     Purpose:    strip the form elements from an html document
645     Input:        $document    document to strip.
646     Output:        $match        an array of the links
647 \*======================================================================*/
648
649     function _stripform($document)
650     {
651         preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
652
653         // catenate the matches
654         $match = implode("\r\n",$elements[0]);
655
656         // return the links
657         return $match;
658     }
659
660
661
662 /*======================================================================*\
663     Function:    _striptext
664     Purpose:    strip the text from an html document
665     Input:        $document    document to strip.
666     Output:        $text        the resulting text
667 \*======================================================================*/
668
669     function _striptext($document)
670     {
671
672         // I didn't use preg eval (//e) since that is only available in PHP 4.0.
673         // so, list your entities one by one here. I included some of the
674         // more common ones.
675
676         $search = array("'<script[^>]*?>.*?</script>'si",    // strip out javascript
677                         "'<[\/\!]*?[^<>]*?>'si",            // strip out html tags
678                         "'([\r\n])[\s]+'",                    // strip out white space
679                         "'&(quot|#34|#034|#x22);'i",        // replace html entities
680                         "'&(amp|#38|#038|#x26);'i",            // added hexadecimal values
681                         "'&(lt|#60|#060|#x3c);'i",
682                         "'&(gt|#62|#062|#x3e);'i",
683                         "'&(nbsp|#160|#xa0);'i",
684                         "'&(iexcl|#161);'i",
685                         "'&(cent|#162);'i",
686                         "'&(pound|#163);'i",
687                         "'&(copy|#169);'i",
688                         "'&(reg|#174);'i",
689                         "'&(deg|#176);'i",
690                         "'&(#39|#039|#x27);'",
691                         "'&(euro|#8364);'i",                // europe
692                         "'&a(uml|UML);'",                    // german
693                         "'&o(uml|UML);'",
694                         "'&u(uml|UML);'",
695                         "'&A(uml|UML);'",
696                         "'&O(uml|UML);'",
697                         "'&U(uml|UML);'",
698                         "'&szlig;'i",
699                         );
700         $replace = array(    "",
701                             "",
702                             "\\1",
703                             "\"",
704                             "&",
705                             "<",
706                             ">",
707                             " ",
708                             chr(161),
709                             chr(162),
710                             chr(163),
711                             chr(169),
712                             chr(174),
713                             chr(176),
714                             chr(39),
715                             chr(128),
716                             "�
717                             "�                            "�                    "�,
718                             "�,
719                             "�,
720                             "�,
721                         );
722
723         $text = preg_replace($search,$replace,$document);
724
725         return $text;
726     }
727
728 /*======================================================================*\
729     Function:    _expandlinks
730     Purpose:    expand each link into a fully qualified URL
731     Input:        $links            the links to qualify
732                 $URI            the full URI to get the base from
733     Output:        $expandedLinks    the expanded links
734 \*======================================================================*/
735
736     function _expandlinks($links,$URI)
737     {
738
739         preg_match("/^[^Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0?]+/",$URI,$match);
740
741         $match = preg_replace("|/[^Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0/Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0.]+Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0.[^Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0/Warning: Unexpected character in input:  '\' (ASCII=92) state=1 in Unknown on line 0.]+$|","",$match[0]);
742         $match = preg_replace("|/$|","",$match);
743         $match_part = parse_url($match);
744         $match_root =
745         $match_part["scheme"]."://".$match_part["host"];
746
747         $search = array(     "|^http://".preg_quote($this->host)."|i",
748                             "|^(\/)|i",
749                             "|^(?!http://)(?!mailto:)|i",
750                             "|/\./|",
751                             "|/[^\/]+/\.\./|"
752                         );
753
754         $replace = array(    "",
755                             $match_root."/",
756                             $match."/",
757                             "/",
758                             "/"
759                         );
760
761         $expandedLinks = preg_replace($search,$replace,$links);
762
763         return $expandedLinks;
764     }
765
766 /*======================================================================*\
767     Function:    _httprequest
768     Purpose:    go get the http data from the server
769     Input:        $url        the url to fetch
770                 $fp            the current open file pointer
771                 $URI        the full URI
772                 $body        body contents to send if any (POST)
773     Output:
774 \*======================================================================*/
775
776     function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
777     {
778         $cookie_headers = '';
779         if($this->passcookies && $this->_redirectaddr)
780             $this->setcookies();
781
782         $URI_PARTS = parse_url($URI);
783         if(empty($url))
784             $url = "/";
785         $headers = $http_method." ".$url." ".$this->_httpversion."\r\n";
786         if(!empty($this->agent))
787             $headers .= "User-Agent: ".$this->agent."\r\n";
788         if(!empty($this->host) && !isset($this->rawheaders['Host'])) {
789             $headers .= "Host: ".$this->host;
790             if(!empty($this->port) && $this->port != 80)
791                 $headers .= ":".$this->port;
792             $headers .= "\r\n";
793         }
794         if(!empty($this->accept))
795             $headers .= "Accept: ".$this->accept."\r\n";
796         if(!empty($this->referer))
797             $headers .= "Referer: ".$this->referer."\r\n";
798         if(!empty($this->cookies))
799         {
800             if(!is_array($this->cookies))
801                 $this->cookies = (array)$this->cookies;
802
803             reset($this->cookies);
804             if ( count($this->cookies) > 0 ) {
805                 $cookie_headers .= 'Cookie: ';
806                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
807                 $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
808                 }
809                 $headers .= substr($cookie_headers,0,-2) . "\r\n";
810             }
811         }
812         if(!empty($this->rawheaders))
813         {
814             if(!is_array($this->rawheaders))
815                 $this->rawheaders = (array)$this->rawheaders;
816             while(list($headerKey,$headerVal) = each($this->rawheaders))
817                 $headers .= $headerKey.": ".$headerVal."\r\n";
818         }
819         if(!empty($content_type)) {
820             $headers .= "Content-type: $content_type";
821             if ($content_type == "multipart/form-data")
822                 $headers .= "; boundary=".$this->_mime_boundary;
823             $headers .= "\r\n";
824         }
825         if(!empty($body))
826             $headers .= "Content-length: ".strlen($body)."\r\n";
827         if(!empty($this->user) || !empty($this->pass))
828             $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n";
829
830         //add proxy auth headers
831         if(!empty($this->proxy_user))
832             $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n";
833
834
835         $headers .= "\r\n";
836
837         // set the read timeout if needed
838         if ($this->read_timeout > 0)
839             socket_set_timeout($fp, $this->read_timeout);
840         $this->timed_out = false;
841
842         fwrite($fp,$headers.$body,strlen($headers.$body));
843
844         $this->_redirectaddr = false;
845         unset($this->headers);
846
847         while($currentHeader = fgets($fp,$this->_maxlinelen))
848         {
849             if ($this->read_timeout > 0 && $this->_check_timeout($fp))
850             {
851                 $this->status=-100;
852                 return false;
853             }
854
855             if($currentHeader == "\r\n")
856                 break;
857
858             // if a header begins with Location: or URI:, set the redirect
859             if(preg_match("/^(Location:|URI:)/i",$currentHeader))
860             {
861                 // get URL portion of the redirect
862                 preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches);
863                 // look for :// in the Location header to see if hostname is included
864                 if(!preg_match("|\:\/\/|",$matches[2]))
865                 {
866                     // no host in the path, so prepend
867                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
868                     // eliminate double slash
869                     if(!preg_match("|^/|",$matches[2]))
870                             $this->_redirectaddr .= "/".$matches[2];
871                     else
872                             $this->_redirectaddr .= $matches[2];
873                 }
874                 else
875                     $this->_redirectaddr = $matches[2];
876             }
877
878             if(preg_match("|^HTTP/|",$currentHeader))
879             {
880                 if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
881                 {
882                     $this->status= $status[1];
883                 }
884                 $this->response_code = $currentHeader;
885             }
886
887             $this->headers[] = $currentHeader;
888         }
889
890         $results = '';
891         do {
892             $_data = fread($fp, $this->maxlength);
893             if (strlen($_data) == 0) {
894                 break;
895             }
896             $results .= $_data;
897         } while(true);
898
899         if ($this->read_timeout > 0 && $this->_check_timeout($fp))
900         {
901             $this->status=-100;
902             return false;
903         }
904
905         // check if there is a a redirect meta tag
906
907         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
908
909         {
910             $this->_redirectaddr = $this->_expandlinks($match[1],$URI);
911         }
912
913         // have we hit our frame depth and is there frame src to fetch?
914         if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
915         {
916             $this->results[] = $results;
917             for($x=0; $x<count($match[1]); $x++)
918                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
919         }
920         // have we already fetched framed content?
921         elseif(is_array($this->results))
922             $this->results[] = $results;
923         // no framed content
924         else
925             $this->results = $results;
926
927         return true;
928     }
929
930 /*======================================================================*\
931     Function:    _httpsrequest
932     Purpose:    go get the https data from the server using curl
933     Input:        $url        the url to fetch
934                 $URI        the full URI
935                 $body        body contents to send if any (POST)
936     Output:
937 \*======================================================================*/
938
939     function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
940     {
941         if($this->passcookies && $this->_redirectaddr)
942             $this->setcookies();
943
944         $headers = array();
945
946         $URI_PARTS = parse_url($URI);
947         if(empty($url))
948             $url = "/";
949         // GET ... header not needed for curl
950         //$headers[] = $http_method." ".$url." ".$this->_httpversion;
951         if(!empty($this->agent))
952             $headers[] = "User-Agent: ".$this->agent;
953         if(!empty($this->host))
954             if(!empty($this->port))
955                 $headers[] = "Host: ".$this->host.":".$this->port;
956             else
957                 $headers[] = "Host: ".$this->host;
958         if(!empty($this->accept))
959             $headers[] = "Accept: ".$this->accept;
960         if(!empty($this->referer))
961             $headers[] = "Referer: ".$this->referer;
962         if(!empty($this->cookies))
963         {
964             if(!is_array($this->cookies))
965                 $this->cookies = (array)$this->cookies;
966
967             reset($this->cookies);
968             if ( count($this->cookies) > 0 ) {
969                 $cookie_str = 'Cookie: ';
970                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
971                 $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; ";
972                 }
973                 $headers[] = substr($cookie_str,0,-2);
974             }
975         }
976         if(!empty($this->rawheaders))
977         {
978             if(!is_array($this->rawheaders))
979                 $this->rawheaders = (array)$this->rawheaders;
980             while(list($headerKey,$headerVal) = each($this->rawheaders))
981                 $headers[] = $headerKey.": ".$headerVal;
982         }
983         if(!empty($content_type)) {
984             if ($content_type == "multipart/form-data")
985                 $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary;
986             else
987                 $headers[] = "Content-type: $content_type";
988         }
989         if(!empty($body))
990             $headers[] = "Content-length: ".strlen($body);
991         if(!empty($this->user) || !empty($this->pass))
992             $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
993
994         for($curr_header = 0; $curr_header < count($headers); $curr_header++) {
995             $safer_header = strtr( $headers[$curr_header], "\"", " " );
996             $cmdline_params .= " -H \"".$safer_header."\"";
997         }
998
999         if(!empty($body))
1000             $cmdline_params .= " -d \"$body\"";
1001
1002         if($this->read_timeout > 0)
1003             $cmdline_params .= " -m ".$this->read_timeout;
1004
1005         $headerfile = tempnam($temp_dir, "sno");
1006
1007         exec($this->curl_path." -k -D \"$headerfile\"".$cmdline_params." \"".escapeshellcmd($URI)."\"",$results,$return);
1008
1009         if($return)
1010         {
1011             $this->error = "Error: cURL could not retrieve the document, error $return.";
1012             return false;
1013         }
1014
1015
1016         $results = implode("\r\n",$results);
1017
1018         $result_headers = file("$headerfile");
1019
1020         $this->_redirectaddr = false;
1021         unset($this->headers);
1022
1023         for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)
1024         {
1025
1026             // if a header begins with Location: or URI:, set the redirect
1027             if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
1028             {
1029                 // get URL portion of the redirect
1030                 preg_match("/^(Location: |URI:)\s+(.*)/",chop($result_headers[$currentHeader]),$matches);
1031                 // look for :// in the Location header to see if hostname is included
1032                 if(!preg_match("|\:\/\/|",$matches[2]))
1033                 {
1034                     // no host in the path, so prepend
1035                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
1036                     // eliminate double slash
1037                     if(!preg_match("|^/|",$matches[2]))
1038                             $this->_redirectaddr .= "/".$matches[2];
1039                     else
1040                             $this->_redirectaddr .= $matches[2];
1041                 }
1042                 else
1043                     $this->_redirectaddr = $matches[2];
1044             }
1045
1046             if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
1047                 $this->response_code = $result_headers[$currentHeader];
1048
1049             $this->headers[] = $result_headers[$currentHeader];
1050         }
1051
1052         // check if there is a a redirect meta tag
1053
1054         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
1055         {
1056             $this->_redirectaddr = $this->_expandlinks($match[1],$URI);
1057         }
1058
1059         // have we hit our frame depth and is there frame src to fetch?
1060         if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
1061         {
1062             $this->results[] = $results;
1063             for($x=0; $x<count($match[1]); $x++)
1064                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
1065         }
1066         // have we already fetched framed content?
1067         elseif(is_array($this->results))
1068             $this->results[] = $results;
1069         // no framed content
1070         else
1071             $this->results = $results;
1072
1073         unlink("$headerfile");
1074
1075         return true;
1076     }
1077
1078 /*======================================================================*\
1079     Function:    setcookies()
1080     Purpose:    set cookies for a redirection
1081 \*======================================================================*/
1082
1083     function setcookies()
1084     {
1085         for($x=0; $x<count($this->headers); $x++)
1086         {
1087         if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))
1088             $this->cookies[$match[1]] = urldecode($match[2]);
1089         }
1090     }
1091
1092
1093 /*======================================================================*\
1094     Function:    _check_timeout
1095     Purpose:    checks whether timeout has occurred
1096     Input:        $fp    file pointer
1097 \*======================================================================*/
1098
1099     function _check_timeout($fp)
1100     {
1101         if ($this->read_timeout > 0) {
1102             $fp_status = socket_get_status($fp);
1103             if ($fp_status["timed_out"]) {
1104                 $this->timed_out = true;
1105                 return true;
1106             }
1107         }
1108         return false;
1109     }
1110
1111 /*======================================================================*\
1112     Function:    _connect
1113     Purpose:    make a socket connection
1114     Input:        $fp    file pointer
1115 \*======================================================================*/
1116
1117     function _connect(&$fp)
1118     {
1119         if(!empty($this->proxy_host) && !empty($this->proxy_port))
1120             {
1121                 $this->_isproxy = true;
1122
1123                 $host = $this->proxy_host;
1124                 $port = $this->proxy_port;
1125             }
1126         else
1127         {
1128             $host = $this->host;
1129             $port = $this->port;
1130         }
1131
1132         $this->status = 0;
1133
1134         if($fp = fsockopen(
1135                     $host,
1136                     $port,
1137                     $errno,
1138                     $errstr,
1139                     $this->_fp_timeout
1140                     ))
1141         {
1142             // socket connection succeeded
1143
1144             return true;
1145         }
1146         else
1147         {
1148             // socket connection failed
1149             $this->status = $errno;
1150             switch($errno)
1151             {
1152                 case -3:
1153                     $this->error="socket creation failed (-3)";
1154                 case -4:
1155                     $this->error="dns lookup failure (-4)";
1156                 case -5:
1157                     $this->error="connection refused or timed out (-5)";
1158                 default:
1159                     $this->error="connection failed (".$errno.")";
1160             }
1161             return false;
1162         }
1163     }
1164 /*======================================================================*\
1165     Function:    _disconnect
1166     Purpose:    disconnect a socket connection
1167     Input:        $fp    file pointer
1168 \*======================================================================*/
1169
1170     function _disconnect($fp)
1171     {
1172         return(fclose($fp));
1173     }
1174
1175
1176 /*======================================================================*\
1177     Function:    _prepare_post_body
1178     Purpose:    Prepare post body according to encoding type
1179     Input:        $formvars  - form variables
1180                 $formfiles - form upload files
1181     Output:        post body
1182 \*======================================================================*/
1183
1184     function _prepare_post_body($formvars, $formfiles)
1185     {
1186         settype($formvars, "array");
1187         settype($formfiles, "array");
1188         $postdata = '';
1189
1190         if (count($formvars) == 0 && count($formfiles) == 0)
1191             return;
1192
1193         switch ($this->_submit_type) {
1194             case "application/x-www-form-urlencoded":
1195                 reset($formvars);
1196                 while(list($key,$val) = each($formvars)) {
1197                     if (is_array($val) || is_object($val)) {
1198                         while (list($cur_key, $cur_val) = each($val)) {
1199                             $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
1200                         }
1201                     } else
1202                         $postdata .= urlencode($key)."=".urlencode($val)."&";
1203                 }
1204                 break;
1205
1206             case "multipart/form-data":
1207                 $this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));
1208
1209                 reset($formvars);
1210                 while(list($key,$val) = each($formvars)) {
1211                     if (is_array($val) || is_object($val)) {
1212                         while (list($cur_key, $cur_val) = each($val)) {
1213                             $postdata .= "--".$this->_mime_boundary."\r\n";
1214                             $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
1215                             $postdata .= "$cur_val\r\n";
1216                         }
1217                     } else {
1218                         $postdata .= "--".$this->_mime_boundary."\r\n";
1219                         $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
1220                         $postdata .= "$val\r\n";
1221                     }
1222                 }
1223
1224                 reset($formfiles);
1225                 while (list($field_name, $file_names) = each($formfiles)) {
1226                     settype($file_names, "array");
1227                     while (list(, $file_name) = each($file_names)) {
1228                         if (!is_readable($file_name)) continue;
1229
1230                         $fp = fopen($file_name, "r");
1231                         $file_content = fread($fp, filesize($file_name));
1232                         fclose($fp);
1233                         $base_name = basename($file_name);
1234
1235                         $postdata .= "--".$this->_mime_boundary."\r\n";
1236                         $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
1237                         $postdata .= "$file_content\r\n";
1238                     }
1239                 }
1240                 $postdata .= "--".$this->_mime_boundary."--\r\n";
1241                 break;
1242         }
1243
1244         return $postdata;
1245     }
1246 }
1247 endif;
1248 ?>
1249
Note: See TracBrowser for help on using the browser.