Loudblog PHP Cross Reference Blogging Systems

Source: /loudblog/inc/magpierss/extlib/Snoopy.class.inc - 900 lines - 27402 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /*************************************************
   4  
   5  Snoopy - the PHP net client
   6  Author: Monte Ohrt <monte@ispi.net>
   7  Copyright (c): 1999-2000 ispi, all rights reserved
   8  Version: 1.0
   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@ispi.net
  26  
  27  Or, write to:
  28  Monte Ohrt
  29  CTO, ispi
  30  237 S. 70th suite 220
  31  Lincoln, NE 68510
  32  
  33  The latest version of Snoopy can be obtained from:
  34  http://snoopy.sourceforge.com
  35  
  36  *************************************************/
  37  
  38  class Snoopy
  39  {
  40      /**** Public variables ****/
  41      
  42      /* user definable vars */
  43  
  44      var $host            =    "www.php.net";        // host name we are connecting to
  45      var $port            =    80;                    // port we are connecting to
  46      var $proxy_host        =    "";                    // proxy host to use
  47      var $proxy_port        =    "";                    // proxy port to use
  48      var $agent            =    "Snoopy v1.0";        // agent we masquerade as
  49      var    $referer        =    "";                    // referer info to pass
  50      var $cookies        =    array();            // array of cookies to pass
  51                                                  // $cookies["username"]="joe";
  52      var    $rawheaders        =    array();            // array of raw headers to send
  53                                                  // $rawheaders["Content-type"]="text/html";
  54  
  55      var $maxredirs        =    5;                    // http redirection depth maximum. 0 = disallow
  56      var $lastredirectaddr    =    "";                // contains address of last redirected address
  57      var    $offsiteok        =    true;                // allows redirection off-site
  58      var $maxframes        =    0;                    // frame content depth maximum. 0 = disallow
  59      var $expandlinks    =    true;                // expand links to fully qualified URLs.
  60                                                  // this only applies to fetchlinks()
  61                                                  // or submitlinks()
  62      var $passcookies    =    true;                // pass set cookies back through redirects
  63                                                  // NOTE: this currently does not respect
  64                                                  // dates, domains or paths.
  65      
  66      var    $user            =    "";                    // user for http authentication
  67      var    $pass            =    "";                    // password for http authentication
  68      
  69      // http accept types
  70      var $accept            =    "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  71      
  72      var $results        =    "";                    // where the content is put
  73          
  74      var $error            =    "";                    // error messages sent here
  75      var    $response_code    =    "";                    // response code returned from server
  76      var    $headers        =    array();            // headers returned from server sent here
  77      var    $maxlength        =    500000;                // max return data length (body)
  78      var $read_timeout    =    0;                    // timeout on read operations, in seconds
  79                                                  // supported only since PHP 4 Beta 4
  80                                                  // set to 0 to disallow timeouts
  81      var $timed_out        =    false;                // if a read operation timed out
  82      var    $status            =    0;                    // http request status
  83      
  84      var    $curl_path        =    "/usr/bin/curl";
  85                                                  // Snoopy will use cURL for fetching
  86                                                  // SSL content if a full system path to
  87                                                  // the cURL binary is supplied here.
  88                                                  // set to false if you do not have
  89                                                  // cURL installed. See http://curl.haxx.se
  90                                                  // for details on installing cURL.
  91                                                  // Snoopy does *not* use the cURL
  92                                                  // library functions built into php,
  93                                                  // as these functions are not stable
  94                                                  // as of this Snoopy release.
  95      
  96      // send Accept-encoding: gzip?
  97      var $use_gzip        = true;    
  98      
  99      /**** Private variables ****/    
 100      
 101      var    $_maxlinelen    =    4096;                // max line length (headers)
 102      
 103      var $_httpmethod    =    "GET";                // default http request method
 104      var $_httpversion    =    "HTTP/1.0";            // default http request version
 105      var $_submit_method    =    "POST";                // default submit method
 106      var $_submit_type    =    "application/x-www-form-urlencoded";    // default submit type
 107      var $_mime_boundary    =   "";                    // MIME boundary for multipart/form-data submit type
 108      var $_redirectaddr    =    false;                // will be set if page fetched is a redirect
 109      var $_redirectdepth    =    0;                    // increments on an http redirect
 110      var $_frameurls        =     array();            // frame src urls
 111      var $_framedepth    =    0;                    // increments on frame depth
 112      
 113      var $_isproxy        =    false;                // set if using a proxy server
 114      var $_fp_timeout    =    30;                    // timeout for socket connection
 115  
 116  /*======================================================================*\
 117      Function:    fetch
 118      Purpose:    fetch the contents of a web page
 119                  (and possibly other protocols in the
 120                  future like ftp, nntp, gopher, etc.)
 121      Input:        $URI    the location of the page to fetch
 122      Output:        $this->results    the output text from the fetch
 123  \*======================================================================*/
 124  
 125  	function fetch($URI)
 126      {
 127      
 128          //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
 129          $URI_PARTS = parse_url($URI);
 130          if (!empty($URI_PARTS["user"]))
 131              $this->user = $URI_PARTS["user"];
 132          if (!empty($URI_PARTS["pass"]))
 133              $this->pass = $URI_PARTS["pass"];
 134                  
 135          switch($URI_PARTS["scheme"])
 136          {
 137              case "http":
 138                  $this->host = $URI_PARTS["host"];
 139                  if(!empty($URI_PARTS["port"]))
 140                      $this->port = $URI_PARTS["port"];
 141                  if($this->_connect($fp))
 142                  {
 143                      if($this->_isproxy)
 144                      {
 145                          // using proxy, send entire URI
 146                          $this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
 147                      }
 148                      else
 149                      {
 150                          $path = $URI_PARTS["path"].(isset($URI_PARTS["query"]) ? "?".$URI_PARTS["query"] : "");
 151                          // no proxy, send only the path
 152                          $this->_httprequest($path, $fp, $URI, $this->_httpmethod);
 153                      }
 154                      
 155                      $this->_disconnect($fp);
 156  
 157                      if($this->_redirectaddr)
 158                      {
 159                          /* url was redirected, check if we've hit the max depth */
 160                          if($this->maxredirs > $this->_redirectdepth)
 161                          {
 162                              // only follow redirect if it's on this site, or offsiteok is true
 163                              if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
 164                              {
 165                                  /* follow the redirect */
 166                                  $this->_redirectdepth++;
 167                                  $this->lastredirectaddr=$this->_redirectaddr;
 168                                  $this->fetch($this->_redirectaddr);
 169                              }
 170                          }
 171                      }
 172  
 173                      if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
 174                      {
 175                          $frameurls = $this->_frameurls;
 176                          $this->_frameurls = array();
 177                          
 178                          while(list(,$frameurl) = each($frameurls))
 179                          {
 180                              if($this->_framedepth < $this->maxframes)
 181                              {
 182                                  $this->fetch($frameurl);
 183                                  $this->_framedepth++;
 184                              }
 185                              else
 186                                  break;
 187                          }
 188                      }                    
 189                  }
 190                  else
 191                  {
 192                      return false;
 193                  }
 194                  return true;                    
 195                  break;
 196              case "https":
 197                  if(!$this->curl_path || (!is_executable($this->curl_path))) {
 198                      $this->error = "Bad curl ($this->curl_path), can't fetch HTTPS \n";
 199                      return false;
 200                  }
 201                  $this->host = $URI_PARTS["host"];
 202                  if(!empty($URI_PARTS["port"]))
 203                      $this->port = $URI_PARTS["port"];
 204                  if($this->_isproxy)
 205                  {
 206                      // using proxy, send entire URI
 207                      $this->_httpsrequest($URI,$URI,$this->_httpmethod);
 208                  }
 209                  else
 210                  {
 211                      $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
 212                      // no proxy, send only the path
 213                      $this->_httpsrequest($path, $URI, $this->_httpmethod);
 214                  }
 215  
 216                  if($this->_redirectaddr)
 217                  {
 218                      /* url was redirected, check if we've hit the max depth */
 219                      if($this->maxredirs > $this->_redirectdepth)
 220                      {
 221                          // only follow redirect if it's on this site, or offsiteok is true
 222                          if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
 223                          {
 224                              /* follow the redirect */
 225                              $this->_redirectdepth++;
 226                              $this->lastredirectaddr=$this->_redirectaddr;
 227                              $this->fetch($this->_redirectaddr);
 228                          }
 229                      }
 230                  }
 231  
 232                  if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
 233                  {
 234                      $frameurls = $this->_frameurls;
 235                      $this->_frameurls = array();
 236  
 237                      while(list(,$frameurl) = each($frameurls))
 238                      {
 239                          if($this->_framedepth < $this->maxframes)
 240                          {
 241                              $this->fetch($frameurl);
 242                              $this->_framedepth++;
 243                          }
 244                          else
 245                              break;
 246                      }
 247                  }                    
 248                  return true;                    
 249                  break;
 250              default:
 251                  // not a valid protocol
 252                  $this->error    =    'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
 253                  return false;
 254                  break;
 255          }        
 256          return true;
 257      }
 258  
 259  
 260  
 261  /*======================================================================*\
 262      Private functions
 263  \*======================================================================*/
 264      
 265      
 266  /*======================================================================*\
 267      Function:    _striplinks
 268      Purpose:    strip the hyperlinks from an html document
 269      Input:        $document    document to strip.
 270      Output:        $match        an array of the links
 271  \*======================================================================*/
 272  
 273  	function _striplinks($document)
 274      {    
 275          preg_match_all("'<\s*a\s+.*href\s*=\s*            # find <a href=
 276                          ([\"\'])?                    # find single or double quote
 277                          (?(1) (.*?)\\1 | ([^\s\>]+))        # if quote found, match up to next matching
 278                                                      # quote, otherwise match up to next space
 279                          'isx",$document,$links);
 280                          
 281  
 282          // catenate the non-empty matches from the conditional subpattern
 283  
 284          while(list($key,$val) = each($links[2]))
 285          {
 286              if(!empty($val))
 287                  $match[] = $val;
 288          }                
 289          
 290          while(list($key,$val) = each($links[3]))
 291          {
 292              if(!empty($val))
 293                  $match[] = $val;
 294          }        
 295          
 296          // return the links
 297          return $match;
 298      }
 299  
 300  /*======================================================================*\
 301      Function:    _stripform
 302      Purpose:    strip the form elements from an html document
 303      Input:        $document    document to strip.
 304      Output:        $match        an array of the links
 305  \*======================================================================*/
 306  
 307  	function _stripform($document)
 308      {    
 309          preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
 310          
 311          // catenate the matches
 312          $match = implode("\r\n",$elements[0]);
 313                  
 314          // return the links
 315          return $match;
 316      }
 317  
 318      
 319      
 320  /*======================================================================*\
 321      Function:    _striptext
 322      Purpose:    strip the text from an html document
 323      Input:        $document    document to strip.
 324      Output:        $text        the resulting text
 325  \*======================================================================*/
 326  
 327  	function _striptext($document)
 328      {
 329          
 330          // I didn't use preg eval (//e) since that is only available in PHP 4.0.
 331          // so, list your entities one by one here. I included some of the
 332          // more common ones.
 333                                  
 334          $search = array("'<script[^>]*?>.*?</script>'si",    // strip out javascript
 335                          "'<[\/\!]*?[^<>]*?>'si",            // strip out html tags
 336                          "'([\r\n])[\s]+'",                    // strip out white space
 337                          "'&(quote|#34);'i",                    // replace html entities
 338                          "'&(amp|#38);'i",
 339                          "'&(lt|#60);'i",
 340                          "'&(gt|#62);'i",
 341                          "'&(nbsp|#160);'i",
 342                          "'&(iexcl|#161);'i",
 343                          "'&(cent|#162);'i",
 344                          "'&(pound|#163);'i",
 345                          "'&(copy|#169);'i"
 346                          );                
 347          $replace = array(    "",
 348                              "",
 349                              "\\1",
 350                              "\"",
 351                              "&",
 352                              "<",
 353                              ">",
 354                              " ",
 355                              chr(161),
 356                              chr(162),
 357                              chr(163),
 358                              chr(169));
 359                      
 360          $text = preg_replace($search,$replace,$document);
 361                                  
 362          return $text;
 363      }
 364  
 365  /*======================================================================*\
 366      Function:    _expandlinks
 367      Purpose:    expand each link into a fully qualified URL
 368      Input:        $links            the links to qualify
 369                  $URI            the full URI to get the base from
 370      Output:        $expandedLinks    the expanded links
 371  \*======================================================================*/
 372  
 373  	function _expandlinks($links,$URI)
 374      {
 375          
 376          preg_match("/^[^\?]+/",$URI,$match);
 377  
 378          $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]);
 379                  
 380          $search = array(     "|^http://".preg_quote($this->host)."|i",
 381                              "|^(?!http://)(\/)?(?!mailto:)|i",
 382                              "|/\./|",
 383                              "|/[^\/]+/\.\./|"
 384                          );
 385                          
 386          $replace = array(    "",
 387                              $match."/",
 388                              "/",
 389                              "/"
 390                          );            
 391                  
 392          $expandedLinks = preg_replace($search,$replace,$links);
 393  
 394          return $expandedLinks;
 395      }
 396  
 397  /*======================================================================*\
 398      Function:    _httprequest
 399      Purpose:    go get the http data from the server
 400      Input:        $url        the url to fetch
 401                  $fp            the current open file pointer
 402                  $URI        the full URI
 403                  $body        body contents to send if any (POST)
 404      Output:        
 405  \*======================================================================*/
 406      
 407  	function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
 408      {
 409          if($this->passcookies && $this->_redirectaddr)
 410              $this->setcookies();
 411              
 412          $URI_PARTS = parse_url($URI);
 413          if(empty($url))
 414              $url = "/";
 415          $headers = $http_method." ".$url." ".$this->_httpversion."\r\n";        
 416          if(!empty($this->agent))
 417              $headers .= "User-Agent: ".$this->agent."\r\n";
 418          if(!empty($this->host) && !isset($this->rawheaders['Host']))
 419              $headers .= "Host: ".$this->host."\r\n";
 420          if(!empty($this->accept))
 421              $headers .= "Accept: ".$this->accept."\r\n";
 422          
 423          if($this->use_gzip) {
 424              // make sure PHP was built with --with-zlib
 425              // and we can handle gzipp'ed data
 426              if ( function_exists(gzinflate) ) {
 427                 $headers .= "Accept-encoding: gzip\r\n";
 428              }
 429              else {
 430                 trigger_error(
 431                     "use_gzip is on, but PHP was built without zlib support.".
 432                  "  Requesting file(s) without gzip encoding.", 
 433                  E_USER_NOTICE);
 434              }
 435          }
 436          
 437          if(!empty($this->referer))
 438              $headers .= "Referer: ".$this->referer."\r\n";
 439          if(!empty($this->cookies))
 440          {            
 441              if(!is_array($this->cookies))
 442                  $this->cookies = (array)$this->cookies;
 443      
 444              reset($this->cookies);
 445              if ( count($this->cookies) > 0 ) {
 446                  $cookie_headers .= 'Cookie: ';
 447                  foreach ( $this->cookies as $cookieKey => $cookieVal ) {
 448                  $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
 449                  }
 450                  $headers .= substr($cookie_headers,0,-2) . "\r\n";
 451              } 
 452          }
 453          if(!empty($this->rawheaders))
 454          {
 455              if(!is_array($this->rawheaders))
 456                  $this->rawheaders = (array)$this->rawheaders;
 457              while(list($headerKey,$headerVal) = each($this->rawheaders))
 458                  $headers .= $headerKey.": ".$headerVal."\r\n";
 459          }
 460          if(!empty($content_type)) {
 461              $headers .= "Content-type: $content_type";
 462              if ($content_type == "multipart/form-data")
 463                  $headers .= "; boundary=".$this->_mime_boundary;
 464              $headers .= "\r\n";
 465          }
 466          if(!empty($body))    
 467              $headers .= "Content-length: ".strlen($body)."\r\n";
 468          if(!empty($this->user) || !empty($this->pass))    
 469              $headers .= "Authorization: BASIC ".base64_encode($this->user.":".$this->pass)."\r\n";
 470  
 471          $headers .= "\r\n";
 472          
 473          // set the read timeout if needed
 474          if ($this->read_timeout > 0)
 475              socket_set_timeout($fp, $this->read_timeout);
 476          $this->timed_out = false;
 477          
 478          fwrite($fp,$headers.$body,strlen($headers.$body));
 479          
 480          $this->_redirectaddr = false;
 481          unset($this->headers);
 482          
 483          // content was returned gzip encoded?
 484          $is_gzipped = false;
 485                          
 486          while($currentHeader = fgets($fp,$this->_maxlinelen))
 487          {
 488              if ($this->read_timeout > 0 && $this->_check_timeout($fp))
 489              {
 490                  $this->status=-100;
 491                  return false;
 492              }
 493                  
 494          //    if($currentHeader == "\r\n")
 495              if(preg_match("/^\r?\n$/", $currentHeader) )
 496                    break;
 497                          
 498              // if a header begins with Location: or URI:, set the redirect
 499              if(preg_match("/^(Location:|URI:)/i",$currentHeader))
 500              {
 501                  // get URL portion of the redirect
 502                  preg_match("/^(Location:|URI:)\s+(.*)/",chop($currentHeader),$matches);
 503                  // look for :// in the Location header to see if hostname is included
 504                  if(!preg_match("|\:\/\/|",$matches[2]))
 505                  {
 506                      // no host in the path, so prepend
 507                      $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
 508                      // eliminate double slash
 509                      if(!preg_match("|^/|",$matches[2]))
 510                              $this->_redirectaddr .= "/".$matches[2];
 511                      else
 512                              $this->_redirectaddr .= $matches[2];
 513                  }
 514                  else
 515                      $this->_redirectaddr = $matches[2];
 516              }
 517          
 518              if(preg_match("|^HTTP/|",$currentHeader))
 519              {
 520                  if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
 521                  {
 522                      $this->status= $status[1];
 523                  }                
 524                  $this->response_code = $currentHeader;
 525              }
 526              
 527              if (preg_match("/Content-Encoding: gzip/", $currentHeader) ) {
 528                  $is_gzipped = true;
 529              }
 530              
 531              $this->headers[] = $currentHeader;
 532          }
 533  
 534          # $results = fread($fp, $this->maxlength);
 535          $results = "";
 536          while ( $data = fread($fp, $this->maxlength) ) {
 537              $results .= $data;
 538              if (
 539                  strlen($results) > $this->maxlength ) {
 540                  break;
 541              }
 542          }
 543          
 544          // gunzip
 545          if ( $is_gzipped ) {
 546              // per http://www.php.net/manual/en/function.gzencode.php
 547              $results = substr($results, 10);
 548              $results = gzinflate($results);
 549          }
 550          
 551          if ($this->read_timeout > 0 && $this->_check_timeout($fp))
 552          {
 553              $this->status=-100;
 554              return false;
 555          }
 556          
 557          // check if there is a a redirect meta tag
 558          
 559          if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
 560          {
 561              $this->_redirectaddr = $this->_expandlinks($match[1],$URI);    
 562          }
 563  
 564          // have we hit our frame depth and is there frame src to fetch?
 565          if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
 566          {
 567              $this->results[] = $results;
 568              for($x=0; $x<count($match[1]); $x++)
 569                  $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
 570          }
 571          // have we already fetched framed content?
 572          elseif(is_array($this->results))
 573              $this->results[] = $results;
 574          // no framed content
 575          else
 576              $this->results = $results;
 577          
 578          return true;
 579      }
 580  
 581  /*======================================================================*\
 582      Function:    _httpsrequest
 583      Purpose:    go get the https data from the server using curl
 584      Input:        $url        the url to fetch
 585                  $URI        the full URI
 586                  $body        body contents to send if any (POST)
 587      Output:        
 588  \*======================================================================*/
 589      
 590  	function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
 591      {
 592          if($this->passcookies && $this->_redirectaddr)
 593              $this->setcookies();
 594  
 595          $headers = array();        
 596                      
 597          $URI_PARTS = parse_url($URI);
 598          if(empty($url))
 599              $url = "/";
 600          // GET ... header not needed for curl
 601          //$headers[] = $http_method." ".$url." ".$this->_httpversion;        
 602          if(!empty($this->agent))
 603              $headers[] = "User-Agent: ".$this->agent;
 604          if(!empty($this->host))
 605              $headers[] = "Host: ".$this->host;
 606          if(!empty($this->accept))
 607              $headers[] = "Accept: ".$this->accept;
 608          if(!empty($this->referer))
 609              $headers[] = "Referer: ".$this->referer;
 610          if(!empty($this->cookies))
 611          {            
 612              if(!is_array($this->cookies))
 613                  $this->cookies = (array)$this->cookies;
 614      
 615              reset($this->cookies);
 616              if ( count($this->cookies) > 0 ) {
 617                  $cookie_str = 'Cookie: ';
 618                  foreach ( $this->cookies as $cookieKey => $cookieVal ) {
 619                  $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; ";
 620                  }
 621                  $headers[] = substr($cookie_str,0,-2);
 622              }
 623          }
 624          if(!empty($this->rawheaders))
 625          {
 626              if(!is_array($this->rawheaders))
 627                  $this->rawheaders = (array)$this->rawheaders;
 628              while(list($headerKey,$headerVal) = each($this->rawheaders))
 629                  $headers[] = $headerKey.": ".$headerVal;
 630          }
 631          if(!empty($content_type)) {
 632              if ($content_type == "multipart/form-data")
 633                  $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary;
 634              else
 635                  $headers[] = "Content-type: $content_type";
 636          }
 637          if(!empty($body))    
 638              $headers[] = "Content-length: ".strlen($body);
 639          if(!empty($this->user) || !empty($this->pass))    
 640              $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
 641              
 642          for($curr_header = 0; $curr_header < count($headers); $curr_header++) {
 643              $cmdline_params .= " -H \"".$headers[$curr_header]."\"";
 644          }
 645                                             
 646          if(!empty($body))
 647              $cmdline_params .= " -d \"$body\"";
 648          
 649          if($this->read_timeout > 0)
 650              $cmdline_params .= " -m ".$this->read_timeout;
 651          
 652          $headerfile = uniqid(time());
 653          
 654          # accept self-signed certs
 655          $cmdline_params .= " -k"; 
 656          exec($this->curl_path." -D \"/tmp/$headerfile\"".escapeshellcmd($cmdline_params)." ".escapeshellcmd($URI),$results,$return);
 657          
 658          if($return)
 659          {
 660              $this->error = "Error: cURL could not retrieve the document, error $return.";
 661              return false;
 662          }
 663              
 664              
 665          $results = implode("\r\n",$results);
 666          
 667          $result_headers = file("/tmp/$headerfile");
 668                          
 669          $this->_redirectaddr = false;
 670          unset($this->headers);
 671                          
 672          for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)
 673          {
 674              
 675              // if a header begins with Location: or URI:, set the redirect
 676              if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
 677              {
 678                  // get URL portion of the redirect
 679                  preg_match("/^(Location: |URI:)(.*)/",chop($result_headers[$currentHeader]),$matches);
 680                  // look for :// in the Location header to see if hostname is included
 681                  if(!preg_match("|\:\/\/|",$matches[2]))
 682                  {
 683                      // no host in the path, so prepend
 684                      $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
 685                      // eliminate double slash
 686                      if(!preg_match("|^/|",$matches[2]))
 687                              $this->_redirectaddr .= "/".$matches[2];
 688                      else
 689                              $this->_redirectaddr .= $matches[2];
 690                  }
 691                  else
 692                      $this->_redirectaddr = $matches[2];
 693              }
 694          
 695              if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
 696              {
 697                  $this->response_code = $result_headers[$currentHeader];
 698                  if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$this->response_code, $match))
 699                  {
 700                  $this->status= $match[1];
 701                          }
 702              }
 703              $this->headers[] = $result_headers[$currentHeader];
 704          }
 705  
 706          // check if there is a a redirect meta tag
 707          
 708          if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
 709          {
 710              $this->_redirectaddr = $this->_expandlinks($match[1],$URI);    
 711          }
 712  
 713          // have we hit our frame depth and is there frame src to fetch?
 714          if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
 715          {
 716              $this->results[] = $results;
 717              for($x=0; $x<count($match[1]); $x++)
 718                  $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
 719          }
 720          // have we already fetched framed content?
 721          elseif(is_array($this->results))
 722              $this->results[] = $results;
 723          // no framed content
 724          else
 725              $this->results = $results;
 726  
 727          unlink("/tmp/$headerfile");
 728          
 729          return true;
 730      }
 731  
 732  /*======================================================================*\
 733      Function:    setcookies()
 734      Purpose:    set cookies for a redirection
 735  \*======================================================================*/
 736      
 737  	function setcookies()
 738      {
 739          for($x=0; $x<count($this->headers); $x++)
 740          {
 741          if(preg_match("/^set-cookie:[\s]+([^=]+)=([^;]+)/i", $this->headers[$x],$match))
 742              $this->cookies[$match[1]] = $match[2];
 743          }
 744      }
 745  
 746      
 747  /*======================================================================*\
 748      Function:    _check_timeout
 749      Purpose:    checks whether timeout has occurred
 750      Input:        $fp    file pointer
 751  \*======================================================================*/
 752  
 753  	function _check_timeout($fp)
 754      {
 755          if ($this->read_timeout > 0) {
 756              $fp_status = socket_get_status($fp);
 757              if ($fp_status["timed_out"]) {
 758                  $this->timed_out = true;
 759                  return true;
 760              }
 761          }
 762          return false;
 763      }
 764  
 765  /*======================================================================*\
 766      Function:    _connect
 767      Purpose:    make a socket connection
 768      Input:        $fp    file pointer
 769  \*======================================================================*/
 770      
 771  	function _connect(&$fp)
 772      {
 773          if(!empty($this->proxy_host) && !empty($this->proxy_port))
 774              {
 775                  $this->_isproxy = true;
 776                  $host = $this->proxy_host;
 777                  $port = $this->proxy_port;
 778              }
 779          else
 780          {
 781              $host = $this->host;
 782              $port = $this->port;
 783          }
 784      
 785          $this->status = 0;
 786          
 787          if($fp = fsockopen(
 788                      $host,
 789                      $port,
 790                      $errno,
 791                      $errstr,
 792                      $this->_fp_timeout
 793                      ))
 794          {
 795              // socket connection succeeded
 796  
 797              return true;
 798          }
 799          else
 800          {
 801              // socket connection failed
 802              $this->status = $errno;
 803              switch($errno)
 804              {
 805                  case -3:
 806                      $this->error="socket creation failed (-3)";
 807                  case -4:
 808                      $this->error="dns lookup failure (-4)";
 809                  case -5:
 810                      $this->error="connection refused or timed out (-5)";
 811                  default:
 812                      $this->error="connection failed (".$errno.")";
 813              }
 814              return false;
 815          }
 816      }
 817  /*======================================================================*\
 818      Function:    _disconnect
 819      Purpose:    disconnect a socket connection
 820      Input:        $fp    file pointer
 821  \*======================================================================*/
 822      
 823  	function _disconnect($fp)
 824      {
 825          return(fclose($fp));
 826      }
 827  
 828      
 829  /*======================================================================*\
 830      Function:    _prepare_post_body
 831      Purpose:    Prepare post body according to encoding type
 832      Input:        $formvars  - form variables
 833                  $formfiles - form upload files
 834      Output:        post body
 835  \*======================================================================*/
 836      
 837  	function _prepare_post_body($formvars, $formfiles)
 838      {
 839          settype($formvars, "array");
 840          settype($formfiles, "array");
 841  
 842          if (count($formvars) == 0 && count($formfiles) == 0)
 843              return;
 844          
 845          switch ($this->_submit_type) {
 846              case "application/x-www-form-urlencoded":
 847                  reset($formvars);
 848                  while(list($key,$val) = each($formvars)) {
 849                      if (is_array($val) || is_object($val)) {
 850                          while (list($cur_key, $cur_val) = each($val)) {
 851                              $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
 852                          }
 853                      } else
 854                          $postdata .= urlencode($key)."=".urlencode($val)."&";
 855                  }
 856                  break;
 857  
 858              case "multipart/form-data":
 859                  $this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));
 860                  
 861                  reset($formvars);
 862                  while(list($key,$val) = each($formvars)) {
 863                      if (is_array($val) || is_object($val)) {
 864                          while (list($cur_key, $cur_val) = each($val)) {
 865                              $postdata .= "--".$this->_mime_boundary."\r\n";
 866                              $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
 867                              $postdata .= "$cur_val\r\n";
 868                          }
 869                      } else {
 870                          $postdata .= "--".$this->_mime_boundary."\r\n";
 871                          $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
 872                          $postdata .= "$val\r\n";
 873                      }
 874                  }
 875                  
 876                  reset($formfiles);
 877                  while (list($field_name, $file_names) = each($formfiles)) {
 878                      settype($file_names, "array");
 879                      while (list(, $file_name) = each($file_names)) {
 880                          if (!is_readable($file_name)) continue;
 881  
 882                          $fp = fopen($file_name, "r");
 883                          $file_content = fread($fp, filesize($file_name));
 884                          fclose($fp);
 885                          $base_name = basename($file_name);
 886  
 887                          $postdata .= "--".$this->_mime_boundary."\r\n";
 888                          $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
 889                          $postdata .= "$file_content\r\n";
 890                      }
 891                  }
 892                  $postdata .= "--".$this->_mime_boundary."--\r\n";
 893                  break;
 894          }
 895  
 896          return $postdata;
 897      }
 898  }
 899  
 900  ?>

title

Description

title

Description

title

Description

title

title

Body