Guest User

daddie

a guest
Feb 3rd, 2010
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 19.45 KB | None | 0 0
  1. <?php
  2. /**
  3.  * phpWebHacks.php 1.5
  4.  * This class is a powerful tool for HTTP scripting with PHP.
  5.  * It simulates a web browser, only that you use it with lines of code
  6.  * rather than mouse and keyboard.
  7.  *
  8.  * See the documentation at http://php-http.com/documentation
  9.  * See the examples at http://php-http.com/examples
  10.  *
  11.  * Author  Nashruddin Amin - me@nashruddin.com
  12.  * License GPL
  13.  * Website http://php-http.com
  14.  */
  15.  
  16. class phpWebHacks
  17. {
  18.     private $_user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052906 Firefox/3.0';
  19.     private $_boundary   = '----PhPWebhACKs-RoCKs--';
  20.     private $_useproxy   = false;
  21.     private $_proxy_host = '';
  22.     private $_proxy_port = '';
  23.     private $_proxy_user = '';
  24.     private $_proxy_pass = '';
  25.     private $_usegzip    = false;
  26.     private $_log        = false;
  27.     private $_debugdir   = '.log';
  28.     private $_debugnum   = 1;
  29.     private $_delay      = 1;
  30.     private $_body       = array();
  31.     private $_cookies    = array();
  32.     private $_addressbar = '';
  33.     private $_multipart  = false;
  34.     private $_timestart  = 0;
  35.     private $_bytes      = 0;
  36.  
  37.     /**
  38.      * Constructor
  39.      */
  40.     public function __construct()
  41.     {
  42.         $this->setDebug(true);
  43.  
  44.         /* check if zlib is available */
  45.         if (function_exists('gzopen')) {
  46.             $this->_usegzip = true;
  47.         }
  48.  
  49.         /* start time */
  50.         $this->_timestart = microtime(true);
  51.     }
  52.  
  53.     /**
  54.      * Destructor
  55.      */
  56.     public function __destruct()
  57.     {
  58.         /* remove temporary file for gzip encoding */
  59.         if (file_exists('tmp.gz')) {
  60.             unlink('tmp.gz');
  61.         }
  62.  
  63.         /* get elapsed time and transferred bytes */
  64.         $time  = sprintf("%02.1f", microtime(true) - $this->_timestart);
  65.         $bytes = sprintf("%d", ceil($this->_bytes / 1024));
  66.  
  67.         /* log */
  68.         if ($this->_log) {
  69.             $fp = fopen("$this->_debugdir/headers.txt", 'a');
  70.             fputs($fp, "------ Transferred " . $bytes . "kb in $time sec ------\r\n");
  71.             fclose($fp);
  72.         }
  73.     }
  74.  
  75.     /**
  76.      * HEAD
  77.      */
  78.     public function head($url)
  79.     {
  80.         return $this->fetch($url, 'HEAD');
  81.     }
  82.  
  83.     /**
  84.      * GET
  85.      */
  86.     public function get($url)
  87.     {
  88.         return $this->fetch($url, 'GET');
  89.     }
  90.  
  91.     /**
  92.      * POST
  93.      */
  94.     public function post($url, $form = array(), $files = array())
  95.     {
  96.         return $this->fetch($url, 'POST', 10, $form, $files);
  97.     }
  98.  
  99.     /**
  100.      * Make HTTP request
  101.      */
  102.     protected function fetch($url, $method, $maxredir = 10, $form = array(), $files = array())
  103.     {
  104.         /* convert to absolute if relative URL */
  105.         $url = $this->getAbsUrl($url, $this->_addressbar);
  106.  
  107.         /* only http or https */
  108.         if (substr($url, 0, 4) != 'http') return '';
  109.  
  110.         /* cache URL */
  111.         $this->_addressbar = $url;
  112.  
  113.         /* build request */
  114.         $reqbody = $this->getReqBody($form, $files);
  115.         $reqhead = $this->getReqHead($url, $method, strlen($reqbody), empty($files) ? false : true);
  116.  
  117.         /* log request */
  118.         if ($this->_log) {
  119.             $this->logHttpStream($url, $reqhead, $reqbody);
  120.         }
  121.  
  122.         /* parse URL and convert to local variables:
  123.            $scheme, $host, $path */
  124.         $parts = parse_url($url);
  125.         if (!$parts) {
  126.             die("Invalid URL!\n");
  127.         } else {
  128.             foreach($parts as $key=>$val) $$key = $val;
  129.         }
  130.  
  131.         /* open connection */
  132.         if ($this->_useproxy) {
  133.             $fp = @fsockopen($this->_proxy_host, $this->_proxy_port);
  134.         } else  {
  135.             $fp = @fsockopen(($scheme=='https' ? "ssl://$host" : $host), $scheme == 'https' ? 443 : 80);
  136.         }
  137.  
  138.         /* always check */
  139.         if (!$fp) {
  140.             die("Cannot connect to $host!\n");
  141.         }
  142.  
  143.         /* send request & read response */
  144.         @fputs($fp, $reqhead.$reqbody);
  145.         for($res=''; !feof($fp); $res.=@fgets($fp, 4096)) {}
  146.         fclose($fp);
  147.  
  148.         /* set delay between requests. behave! */
  149.         sleep($this->_delay);
  150.  
  151.         /* transferred bytes */
  152.         $this->_bytes += (strlen($reqhead)+ strlen($reqbody)+ strlen($res));
  153.  
  154.         /* get response header & body */
  155.         list($reshead, $resbody) = explode("\r\n\r\n", $res, 2);
  156.  
  157.         /* convert header to associative array */
  158.         $head = $this->parseHead($reshead);
  159.  
  160.         /* return immediately if HEAD */
  161.         if ($method == 'HEAD') {
  162.             if ($this->_log) $this->logHttpStream($url, $reshead, null);
  163.             return $head;
  164.         }
  165.  
  166.         /* cookies */
  167.         if (!empty($head['Set-Cookie'])) {
  168.             $this->saveCookies($head['Set-Cookie'], $url);
  169.         }
  170.            
  171.         /* referer */
  172.         if ($head['Status']['Code'] == 200) {
  173.             $this->_referer = $url;
  174.         }
  175.            
  176.         /* transfer-encoding: chunked */
  177.         if ($head['Transfer-Encoding'] == 'chunked') {
  178.             $body = $this->joinChunks($resbody);
  179.         } else {
  180.             $body = $resbody;
  181.         }
  182.  
  183.         /* content-encoding: gzip */
  184.         if ($head['Content-Encoding'] == 'gzip') {
  185.             @file_put_contents('tmp.gz', $body);
  186.             $fp = @gzopen('tmp.gz', 'r');
  187.             for($body = ''; !@gzeof($fp); $body.=@gzgets($fp, 4096)) {}
  188.             @gzclose($fp);
  189.         }
  190.  
  191.         /* log response */
  192.         if ($this->_log) {
  193.             $this->logHttpStream($url, $reshead, $body);
  194.         }
  195.  
  196.         /* cache body */
  197.         array_unshift($this->_body, $body);
  198.  
  199.         /* redirects: 302 */
  200.         if (isset($head['Location']) && $maxredir > 0) {
  201.             $this->fetch($this->getAbsUrl($head['Location'], $url), 'GET', $maxredir--);
  202.         }
  203.  
  204.         /* parse meta tags */
  205.         $meta = $this->parseMetaTags($body);
  206.  
  207.         /* redirects: <meta http-equiv=refresh...> */
  208.         if (isset($meta['http-equiv']['refresh']) && $maxredir > 0) {
  209.             list($delay, $loc) = explode(';', $meta['http-equiv']['refresh'], 2);
  210.             $loc = substr(trim($loc), 4);
  211.             if (!empty($loc) && $loc != $url)
  212.                 $this->fetch($this->getAbsUrl($loc, $url), 'GET', $maxredir--);
  213.         }
  214.  
  215.         /* get body and clear cache */
  216.         $body = $this->_body[0];
  217.         for($i = 1; $i < count($this->_body); $i++) {
  218.             unset($this->_body[$i]);
  219.         }
  220.  
  221.         return $body;
  222.     }
  223.  
  224.     /**
  225.      * Build request header
  226.      */
  227.     protected function getReqHead($url, $method, $bodylen = 0, $sendfile = true)
  228.     {
  229.         /* parse URL elements to local variables:
  230.            $scheme, $host, $path, $query, $user, $pass */
  231.         $parts = parse_url($url);
  232.         foreach($parts as $key=>$val) $$key = $val;
  233.  
  234.         /* setup path */
  235.         $path = empty($path)  ? '/' : $path
  236.               .(empty($query) ? ''  : "?$query");
  237.            
  238.         /* request header */   
  239.         if ($this->_useproxy) {
  240.             $head = "$method $url HTTP/1.1\r\nHost: $this->_proxy_host\r\n";
  241.         } else  {
  242.             $head = "$method $path HTTP/1.1\r\nHost: $host\r\n";
  243.         }
  244.  
  245.         /* cookies */
  246.         $head .= $this->getCookies($url);
  247.  
  248.         /* content-type */
  249.         if ($method == 'POST' && ($sendfile || $this->_multipart)) {
  250.             $head .= "Content-Type: multipart/form-data; boundary=$this->_boundary\r\n";
  251.         } elseif ($method == 'POST') {
  252.             $head .= "Content-Type: application/x-www-form-urlencoded\r\n";
  253.         }
  254.  
  255.         /* set the content length if POST */
  256.         if ($method == 'POST') {
  257.             $head .= "Content-Length: $bodylen\r\n";
  258.         }
  259.  
  260.         /* basic authentication */
  261.         if (!$this->_useproxy && !empty($user) && !empty($pass)) {
  262.             $head .= "Authorization: Basic ". base64_encode("$user:$pass")."\r\n";
  263.         }
  264.  
  265.         /* basic authentication for proxy */
  266.         if ($this->_useproxy && !empty($this->_proxy_user) && !empty($this->_proxy_pass)) {
  267.             $head .= "Authorization: Basic ". base64_encode("$this->_proxy_user:$this->_proxy_pass")."\r\n";
  268.         }
  269.  
  270.         /* gzip */
  271.         if ($this->_usegzip) {
  272.             $head .= "Accept-Encoding: gzip\r\n";
  273.         }
  274.  
  275.         /* make it like real browsers */
  276.         if (!empty($this->_user_agent)) {
  277.             $head .= "User-Agent: $this->_user_agent\r\n";
  278.         }
  279.         if (!empty($this->_referer)) {
  280.             $head .= "Referer: $this->_referer\r\n";
  281.         }
  282.  
  283.         /* no pipelining yet */
  284.         $head .= "Connection: Close\r\n\r\n";
  285.  
  286.         /* request header is ready */
  287.         return $head;
  288.     }
  289.  
  290.     /**
  291.      * Build request body
  292.      */
  293.     protected function getReqBody($form = array(), $files = array())
  294.     {
  295.         /* check for parameters */
  296.         if (empty($form) && empty($files))
  297.             return '';
  298.  
  299.         $body = '';
  300.         $tmp  = array();
  301.  
  302.         /* only form available: x-www-urlencoded */
  303.         if (!empty($form) &&  empty($files) && !$this->_multipart) {
  304.             foreach($form as $key=>$val)
  305.                 $tmp[] = $key .'='. urlencode($val);
  306.             return implode('&', $tmp);
  307.         }
  308.  
  309.         /* form */
  310.         foreach($form as $key=>$val) {
  311.             $body .= "--$this->_boundary\r\nContent-Disposition: form-data; name=\"" . $key ."\"\r\n\r\n" . $val ."\r\n";
  312.         }
  313.  
  314.         /* files */
  315.         foreach($files as $key=>$val) {
  316.             if (!file_exists($val)) continue;
  317.             $body .= "--$this->_boundary\r\n"
  318.                    . "Content-Disposition: form-data; name=\"" . $key . "\"; filename=\"" . basename($val) . "\"\r\n"
  319.                    . "Content-Type: " . $this->getMimeType($val) . "\r\n\r\n"
  320.                    . file_get_contents($val) . "\r\n";
  321.         }
  322.  
  323.         /* request body is ready! */
  324.         return $body."--$this->_boundary--";
  325.     }
  326.  
  327.     /**
  328.      * convert response header to associative array
  329.      */
  330.     protected function parseHead($str)
  331.     {
  332.         $lines = explode("\r\n", $str);
  333.  
  334.         list($ver, $code, $msg) = explode(' ', array_shift($lines), 3);
  335.         $stat = array('Version' => $ver, 'Code' => $code, 'Message' => $msg);
  336.  
  337.         $head = array('Status' => $stat);
  338.  
  339.         foreach($lines as $line) {
  340.             list($key, $val) = explode(':', $line, 2);
  341.             if ($key == 'Set-Cookie') {
  342.                 $head['Set-Cookie'][] = trim($val);
  343.             } else {
  344.                 $head[$key] = trim($val);
  345.             }
  346.         }
  347.  
  348.         return $head;
  349.     }
  350.  
  351.     /**
  352.      * Read chunked pages
  353.      */
  354.     protected function joinChunks($str)
  355.     {
  356.         $CRLF = "\r\n";
  357.         for($tmp = $str, $res = ''; !empty($tmp); $tmp = trim($tmp)) {
  358.             if (($pos = strpos($tmp, $CRLF)) === false) return $str;
  359.             $len = hexdec(substr($tmp, 0, $pos));
  360.             $res.= substr($tmp, $pos + strlen($CRLF), $len);
  361.             $tmp = substr($tmp, $pos + strlen($CRLF) + $len);
  362.         }
  363.         return $res;
  364.     }
  365.  
  366.     /**
  367.      * Save cookies from server
  368.      */
  369.     protected function saveCookies($set_cookies, $url)
  370.     {
  371.         foreach($set_cookies as $str)
  372.         {
  373.             $parts = explode(';', $str);
  374.  
  375.             /* extract cookie parts to local variables:
  376.                $name, $value, $domain, $path, $expires, $secure, $httponly */
  377.             foreach($parts as $part) {
  378.                 list($key, $val) = explode('=', trim($part), 2);
  379.  
  380.                 $k = strtolower($key);
  381.  
  382.                 if ($k == 'secure' || $k == 'httponly') {
  383.                     $$k = true;
  384.                 } elseif ($k == 'domain' || $k == 'path' || $k == 'expires') {
  385.                     $$k = $val;
  386.                 } else {
  387.                     $name  = $key;
  388.                     $value = $val;
  389.                 }
  390.             }
  391.  
  392.             /* cookie's domain */
  393.             if (empty($domain)) {
  394.                 $domain = parse_url($url, PHP_URL_HOST);
  395.             }
  396.  
  397.             /* cookie's path */
  398.             if (empty($path)) {
  399.                 $path = parse_url($url, PHP_URL_PATH);
  400.                 $path = preg_replace('#/[^/]*$#', '', $path);
  401.                 $path = empty($path) ? '/' : $path;
  402.             }
  403.  
  404.             /* cookie's expire time */
  405.             if (!empty($expires)) {
  406.                 $expires = strtotime($expires);
  407.             }
  408.                
  409.             /* setup cookie ID, a simple trick to add/update existing cookie
  410.                and cleanup local variables later */
  411.             $id = md5("$domain;$path;$name");
  412.  
  413.             /* add/update cookie */
  414.             $this->_cookies[$id] = array(
  415.                 'domain'   => substr_count($domain, '.') == 1 ? ".$domain" : $domain,
  416.                 'path'     => $path,
  417.                 'expires'  => $expires,
  418.                 'name'     => $name,
  419.                 'value'    => $value,
  420.                 'secure'   => $secure,
  421.                 'httponly' => $httponly
  422.             );
  423.  
  424.             /* cleanup local variables */
  425.             foreach($this->_cookies[$id] as $key=>$val) unset($$key);
  426.         }
  427.  
  428.         return true;
  429.     }
  430.  
  431.     /**
  432.      * Get cookies for URL
  433.      */
  434.     protected function getCookies($url)
  435.     {
  436.         $tmp = array();
  437.         $res = array();
  438.  
  439.         /* remove expired cookies first */
  440.         foreach($this->_cookies as $id=>$cookie) {
  441.             if (empty($cookie['expires']) || $cookie['expires'] >= time()) {
  442.                 $tmp[$id] = $cookie;
  443.             }
  444.         }
  445.  
  446.         /* cookies ready */
  447.         $this->_cookies = $tmp;
  448.  
  449.         /* parse URL to local variables:
  450.            $scheme, $host, $path, $query */
  451.         $parts = parse_url($url);
  452.         foreach($parts as $key=>$val) $$key = $val;
  453.  
  454.         if (empty($path)) $path = '/';
  455.  
  456.         /* get all cookies for this domain and path */
  457.         foreach($this->_cookies as $cookie) {
  458.             $d = substr($host, -1 * strlen($cookie['domain']));
  459.             $p = substr($path, 0, strlen($cookie['path']));
  460.            
  461.             if (($d == $cookie['domain'] || ".$d" == $cookie['domain']) && $p == $cookie['path']) {
  462.                 if ($cookie['secure'] == true  && $scheme == 'http') {
  463.                     continue;
  464.                 }
  465.                 $res[] = $cookie['name'].'='.$cookie['value'];
  466.             }
  467.         }
  468.  
  469.         /* return the string for HTTP header */
  470.         return (empty($res) ? '' : 'Cookie: '.implode('; ', $res)."\r\n");
  471.     }
  472.  
  473.     /**
  474.      * Convert relative URL to absolute URL
  475.      */
  476.     protected function getAbsUrl($loc, $parent)
  477.     {
  478.         /* parameters is required */
  479.         if (empty($loc) && empty($parent)) return;
  480.  
  481.         $loc = str_replace('&amp;', '&', $loc);
  482.  
  483.         /* return if URL is abolute */
  484.         if (parse_url($loc, PHP_URL_SCHEME) != '') return $loc;
  485.  
  486.         /* handle anchors and query's part */
  487.         $c = substr($loc, 0, 1);
  488.         if ($c == '#' || $c == '&') return "$parent$loc";
  489.  
  490.         /* handle query string */
  491.         if ($c == '?') {
  492.             $pos = strpos($parent, '?');
  493.             if ($pos !== false) $parent = substr($parent, 0, $pos);
  494.             return "$parent$loc";
  495.         }
  496.  
  497.         /* parse URL and convert to local variables:
  498.            $scheme, $host, $path */
  499.         $parts = parse_url($parent);
  500.         foreach ($parts as $key=>$val) $$key = $val;
  501.  
  502.         /* remove non-directory part from path */
  503.         $path = preg_replace('#/[^/]*$#', '', $path);
  504.  
  505.         /* set path to '/' if empty */
  506.         $path = preg_match('#^/#', $loc) ? '/' : $path;
  507.  
  508.         /* dirty absolute URL */
  509.         $abs = "$host$path/$loc";
  510.  
  511.         /* replace '//', '/./', '/foo/../' with '/' */
  512.         while($abs = preg_replace(array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'), '/', $abs, -1, $count))
  513.             if (!$count) break;
  514.  
  515.         /* absolute URL */
  516.         return "$scheme://$abs";
  517.     }
  518.  
  519.     /**
  520.      * Convert meta tags to associative array
  521.      */
  522.     protected function parseMetaTags($html)
  523.     {
  524.         /* extract to </head> */
  525.         if (($pos = strpos(strtolower($html), '</head>')) === false) {
  526.             return array();
  527.         } else {
  528.             $head = substr($html, 0, $pos);
  529.         }
  530.  
  531.         /* get page's title */
  532.         preg_match("/<title>(.+)<\/title>/siU", $head, $m);
  533.         $meta = array('title' => $m[1]);
  534.  
  535.         /* get all <meta...> */
  536.         preg_match_all('/<meta\s+[^>]*name\s*=\s*[\'"][^>]+>/siU', $head, $m);
  537.         foreach($m[0] as $row) {
  538.             preg_match('/name\s*=\s*[\'"](.+)[\'"]/siU', $row, $key);
  539.             preg_match('/content\s*=\s *[\'"](.+)[\'"]/siU', $row, $val);
  540.             if (!empty($key[1]) && !empty($val[1]))
  541.                 $meta[$key[1]] = $val[1];
  542.         }
  543.  
  544.         /* get <meta http-equiv=refresh...> */
  545.         preg_match('/<meta[^>]+http-equiv\s*=\s*[\'"]?refresh[\'"]?[^>]+content\s*=\s*[\'"](.+)[\'"][^>]*>/siU', $head, $m);
  546.         if (!empty($m[1])) {
  547.             $meta['http-equiv']['refresh'] = preg_replace('/&#0?39;/', '', $m[1]);
  548.         }
  549.         return $meta;
  550.     }
  551.  
  552.     /**
  553.      * Convert form to associative array
  554.      */
  555.     public function parseForm($name_or_id, $action = '', $str = '')
  556.     {
  557.         if (empty($str) && empty($this->_body[0]))
  558.             return array();
  559.            
  560.         $body = empty($str) ? $this->_body[0] : $str;
  561.  
  562.         /* extract the form */
  563.         $re = '(<form[^>]+(id|name)\s*=\s*(?(?=[\'"])[\'"]'.$name_or_id.'[\'"]|\b'.$name_or_id.'\b)[^>]*>.+<\/form>)';
  564.         if (!preg_match("/$re/siU", $body, $form))
  565.             return array();
  566.  
  567.         /* check if enctype=multipart/form-data */
  568.         if (preg_match('/<form[^>]+enctype[^>]+multipart\/form-data[^>]*>/siU', $form[1], $a))
  569.             $this->_multipart = true;
  570.         else
  571.             $this->_multipart = false;
  572.            
  573.         /* get form's action */
  574.         preg_match('/<form[^>]+action\s*=\s*(?(?=[\'"])[\'"]([^\'"]+)[\'"]|([^>\s]+))[^>]*>/si', $form[1], $a);
  575.         $action = empty($a[1]) ? html_entity_decode($a[2]) : html_entity_decode($a[1]);
  576.  
  577.         /* select all <select..> with default values */
  578.         $re = '<select[^>]+name\s*=\s*(?(?=[\'"])[\'"]([^>]+)[\'"]|\b([^>]+)\b)[^>]*>'
  579.             . '.+value\s*=\s*(?(?=[\'"])[\'"]([^>]+)[\'"]|\b([^>]+)\b)[^>]+\bselected\b'
  580.             . '.+<\/select>';
  581.         preg_match_all("/$re/siU", $form[1], $a);
  582.  
  583.         foreach($a[1] as $num=>$key) {
  584.             $val = $a[3][$num];
  585.             if ($val == '') $val = $a[4][$num];
  586.             if ($key == '') $key = $a[2][$num];
  587.             $res[$key] = html_entity_decode($val);
  588.         }
  589.  
  590.         /* get all <input...> */
  591.         preg_match_all('/<input([^>]+)\/?>/siU', $form[1], $a);
  592.  
  593.         /* convert to associative array */
  594.         foreach($a[1] as $b) {
  595.             preg_match_all('/([a-z]+)\s*=\s*(?(?=[\'"])[\'"]([^"]+)[\'"]|\b(.+)\b)/siU', trim($b), $c);
  596.            
  597.             $element = array();
  598.            
  599.             foreach($c[1] as $num=>$key) {
  600.                 $val = $c[2][$num];
  601.                 if ($val == '') $val = $c[3][$num];
  602.                 $element[$key] = $val;
  603.             }
  604.            
  605.             $type = strtolower($element['type']);
  606.            
  607.             /* only radio or checkbox with default values */
  608.             if ($type == 'radio' || $type == 'checkbox')
  609.                 if (!preg_match('/\s+\bchecked\b/', $b)) continue;
  610.                
  611.             /* remove buttons and file */  
  612.             if ($type == 'file' || $type == 'submit' || $type == 'reset' || $type == 'button')
  613.                 continue;
  614.            
  615.             /* remove unnamed elements */
  616.             if ($element['name'] == '' && $element['id'] == '')
  617.                 continue;
  618.            
  619.             /* cool */
  620.             $key = $element['name'] == '' ? $element['id'] : $element['name'];
  621.             $res[$key] = html_entity_decode($element['value']);
  622.         }
  623.  
  624.         return $res;
  625.     }
  626.  
  627.     /**
  628.      * Get mime type for a file
  629.      */
  630.     protected function getMimeType($filename)
  631.     {
  632.         /* list of mime type. add more rows to suit your need */
  633.         $mimetypes = array(
  634.             'jpg'  => 'image/jpeg',
  635.             'jpe'  => 'image/jpeg',
  636.             'jpeg' => 'image/jpeg',
  637.             'gif'  => 'image/gif',
  638.             'png'  => 'image/png',
  639.             'tiff' => 'image/tiff',
  640.             'html' => 'text/html',
  641.             'txt'  => 'text/plain',
  642.             'pdf'  => 'application/pdf',
  643.             'zip'  => 'application/zip'
  644.         );
  645.  
  646.         /* get file extension */
  647.         preg_match('#\.([^\.]+)$#', strtolower($filename), $e);
  648.  
  649.         /* get mime type */
  650.         foreach($mimetypes as $ext=>$mime)
  651.             if ($e[1] == $ext) return $mime;
  652.  
  653.         /* this is the default mime type */
  654.         return 'application/octet-stream';
  655.     }
  656.  
  657.     /**
  658.      * Log HTTP request/response
  659.      */
  660.     protected function logHttpStream($url, $head, $body)
  661.     {
  662.         /* open log file */
  663.         if (($fp = @fopen("$this->_debugdir/headers.txt", 'a')) == false) return;
  664.  
  665.         /* get method */
  666.         $m = substr($head, 0, 4);
  667.  
  668.         /* append the requested URL for HEAD, GET and POST */
  669.         if ($m == 'HEAD' || $m == 'GET ' || $m == 'POST')
  670.             $head = str_repeat('-', 90) . "\r\n$url\r\n\r\n" . trim($head);
  671.  
  672.         /* header */
  673.         @fputs($fp, trim($head)."\r\n\r\n");
  674.  
  675.         /* request body */
  676.         if ($m == 'POST' &&  strpos($head, 'Content-Length: ') !== false) {
  677.             /* skip binary contents */
  678.             $find = 'Content-Type: \s*([^\s]+)\r\n\r\n(.+)\r\n';
  679.             $repl = "Content-Type: $1\r\n\r\n <... File contents ...>\r\n";
  680.             $body = preg_replace('/'.$find .'/siU', $repl, $body);
  681.  
  682.             @fputs($fp, "$body\r\n\r\n");
  683.         }
  684.  
  685.         /* response body */
  686.         if (substr($head, 0, 7) == 'HTTP/1.' && strpos($head, 'text/html') !== false && !empty($body)) {
  687.             $tmp = "$this->_debugdir/" . $this->_debugnum++ . '.html';
  688.             @file_put_contents($tmp, $body);
  689.             @fputs($fp, "<... See page contents in $tmp ...>\r\n\r\n");
  690.         }
  691.  
  692.         @fclose($fp);
  693.     }
  694.  
  695.     public function setDebug($bool)
  696.     {
  697.         $this->_log = $bool;
  698.  
  699.         if (!$this->_log) return;
  700.  
  701.         /* create directory */
  702.         if (!is_dir($this->_debugdir)) {
  703.             mkdir($this->_debugdir);
  704.             chmod($this->_debugdir, 0644);
  705.         }
  706.  
  707.         /* empty debug directory */
  708.         $items = scandir($this->_debugdir);
  709.         foreach($items as $item) {
  710.             if ($item == '.' || $item == '..') continue;
  711.             unlink("$this->_debugdir/$item");
  712.         }
  713.     }
  714.  
  715.     /**
  716.      * Set proxy
  717.      */
  718.     public function setProxy($host, $port, $user = '', $pass = '')
  719.     {
  720.         $this->_proxy_host = $host;
  721.         $this->_proxy_port = $port;
  722.         $this->_proxy_user = $user;
  723.         $this->_proxy_pass = $pass;
  724.         $this->_useproxy   = true;
  725.     }
  726.  
  727.     /**
  728.      * Set delay between requests
  729.      */
  730.     public function setInterval($sec)
  731.     {
  732.         if (!preg_match('/^\d+$/', $sec) || $sec <= 0) {
  733.             $this->_delay = 1;
  734.         } else {
  735.             $this->_delay = $sec;
  736.         }
  737.     }
  738.  
  739.     /**
  740.      * Assign a name for this HTTP client
  741.      */
  742.     public function setUserAgent($ua)
  743.     {
  744.         $this->_user_agent = $ua;
  745.     }
  746. }
Add Comment
Please, Sign In to add comment