PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/include/magpierss/extlib/Snoopy.class.inc

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