<?php
/**
 * LRG
 *
 * Linear-Recursive Grabber
 *
 * @descr        CLI Only
 * @package        LRG
 * @author        HSDN Team
 * @copyright    Copyright (c) 2010 Information Networks Ltd.
 * @link        http://www.hsdn.org
 * @since        Version 1.1
 */

// ------------------------------------------------------------------------

/**
 * Класс Satellite
 *
 * @category    Tasks
 * @author        HSDN Team
 */
class Proxy
{
    
/*
     * Инстанция класса базы данных
     *
     * @access    private
     */
    
private $db;

    
/*
     * Инстанция класса отладки
     *
     * @access    private
     */
    
private $debug;

    
/*
     * Инстанция класса хранения
     *
     * @access    private
     */
    
private $Storage;

    
/*
     * Инстанция класса коллектора
     *
     * @access    private
     */
    
private $Collector;

    
/*
     * Инстанция класса операций
     *
     * @access    private
     */
    
private $Operation;

    
/*
     * Массив данных
     *
     * @access    private
     */
    
private $data;

    
/*
     * Массив временных данных
     *
     * @access    private
     */
    
private $temp;

    
/*
     * 
     *
     * @access    private
     */
    
private $page_limit 10;

    
/*
     * Название таблицы хранения в БД
     *
     * @access    private
     */
    
private $table 'ibapi_function_proxy';

    
/*
     *
     *
     * @access    private
     */
    
private $my_ip '88.147.254.98';

    
/**
     * Конструктор
     *
     * @access    public
     * @return    void
     */
    
public function __construct()
    {
        
$this->db = new Database();
        
$this->Storage = new Storage();
        
$this->Collector = new Collector();
        
$this->Operation = new Operation();
        
$this->Http = new Http();
        
$this->debug = new Debug();

        
$this->get_proxies();
        
$this->check_proxies();
        
$this->inject();
    }

    
/**
     * 
     *
     * @access    public
     * @return    void
     */
    
private function get_proxies()
    {
        for (
$page 0$page $this->page_limit$page++)
        {
            if (!
$this->get_page($page))
            {
                break;
            }
        }
    }

    
/**
     * 
     *
     * @access    public
     * @return    void
     */
    
private function check_proxies()
    {
        
$headers = array
        (
            
'Host' => 'www.networkcenter.info',
            
'Proxy-Connection' => 'close'
        
);

        if (
sizeof($this->temp) == 0)
        {
            return;
        }

        foreach (
$this->temp as $check_summ => $data)
        {
            
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" checking...');
            
            
$start microtime(TRUE);
            
            if ((
$socket $this->Http->open_proxy($data['ip'], $data['port'], 'www.networkcenter.info'80FALSEFALSE$data['type'], 5)) === FALSE)
            {
                
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" failed: '.$this->Http->errstr);
                continue;
            }

            
$request $this->Http->generate_request('GET''http://www.networkcenter.info/detect.php'$headers);
            
$this->Http->write($socket$request);
            
$this->Http->set_timeout($socket5);
            
$content $this->Http->get_content($socket);
            
$this->Http->close($socket);

            
$stop microtime(TRUE);

            if (!
$this->Http->validate_content($content200) OR
                
$content['body'] != 'nc_proxy:OK'."\r\n")
            {
                
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" failed: Invalid content');
                continue;
            }

            
$transparent FALSE;
            
$ditected FALSE;
            
$differend_ip FALSE;

            foreach (
$content['headers'] as $header => $value)
            {
                if (
preg_match("#^X-NC-#i"$header))
                {
                    if (
preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#'$value$ips))
                    {
                        if (
in_array($this->my_ip$ips[0]))
                        {
                            
$transparent TRUE;
                            break;
                        }
                    }
                }
                else if (
preg_match("#^X-Cache#i"$header) OR $header == 'Via')
                {
                    
$ditected TRUE;
                }
            }

            if (isset(
$content['headers']['X-NC-IP-Proxy']) AND ($content['headers']['X-NC-IP-Proxy'] != $data['ip']))
            {
                
$differend_ip TRUE;
            }

            
$this->data['ip'][] = $data['ip'];
            
$this->data['port'][] = $data['port'];
            
$this->data['type'][] = $data['type'];
            
$this->data['country'][] = $data['country'];
            
$this->data['differend_ip'][] = $differend_ip;
            
$this->data['date'][] = time();
            
$this->data['time_connect'][] = $stop $start;

            
$time_connect number_format($stop $start4);

            if (
$transparent === TRUE)
            {
                
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" OK: Transparent ( '.$time_connect.' )');

                
$this->data['anonymous'][] = 'Transparent';
            }
            else if (
$transparent === FALSE AND $ditected === TRUE)
            {
                
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" OK: Anonymous ( '.$time_connect.' )');
                
                
$this->data['anonymous'][] = 'Anonymous';
            }
            else
            {
                
$this->debug->print_ok(__METHOD__.': proxy "'.$data['ip'].':'.$data['port'].'" OK: Hi Anonymous ( '.$time_connect.' )');
                
                
$this->data['anonymous'][] = 'Hi Anonymous';
            }
        }
    }

    
/**
     * T
     *
     * @access    public
     * @return    void
     */
    
private function get_page_hidemyass($page)
    {
        
$structure = array
        (
            
'ip' => array(),
            
'port' => array(),
            
'country' => array(),
            
'type' => array(),
        );

        
$pattern =    
            
"|<tr[^>]+>.*".
            
"<td><span>([^<]+)</span></td>.*".
            
"<td>([^<]+)</td>.*".
            
"<td rel=\"([^\"]+)\">.*</td>.*".
            
"<td>([^<]+)</td>.*".
            
"</tr>|isU";

        
$data $this->Collector->multiply('http://hidemyass.com/proxy-list/'.$page$pattern$structure);

        foreach (
$data['ip'] as $key => $ip)
        {
            
$this->temp[crc32($ip.$data['port'][$key])] = array
            (
                
'ip' => trim($ip),
                
'port' => trim($data['port'][$key]),
                
'type' => str_replace('socks4/5''SOCKS5'trim($data['type'][$key])),
                
'country' => strtoupper(trim($data['country'][$key])),
            );
        }

        return 
TRUE;
    }

    
/**
     * 
     *
     * @access    public
     * @return    void
     */
    
private function get_page($page)
    {
        
$this->db->query("SELECT * FROM `ibapi_function_proxy` ORDER BY `time_connect` ASC LIMIT 15");

        if (
$this->db->error())
        {
            return 
FALSE;
        }

        
$array = array();

        if (
$this->db->num_rows() != 0)
        {
            while (
$row $this->db->fetch_row())
            {
                if ((
$data $this->get_page_data($row['ip'], $row['port'], $row['type'], $page)) !== FALSE)
                {
                    
$this->debug->print_ok(__METHOD__.': page: '.$page.', using proxy: "'.$row['ip'].':'.$row['port']);
                    break;
                }

                
$this->debug->print_ok(__METHOD__.': page: '.$page.', proxy is bad: "'.$row['ip'].':'.$row['port'].', skip');
            }
        }
        else
        {
            
$data $this->get_page_data('10.64.16.2''8080''HTTP'$page);
        }

        
$js_vars explode(';'$data['script']);
        
$js_array = array();

        foreach (
$js_vars as $js_var)
        {
            if (
$js_var)
            {
                
$js_kv explode('='$js_var);
                
$js_exp explode('^'$js_kv[1]);

                
$js_array[$js_kv[0]] = isset($js_exp[1]) ? $js_exp[0] + $js_array[$js_exp[1]] : $js_kv[1];
            }
        }

        
$pattern =    
            
"|<tr.*><td.*>".
            
"<font.*>\d+</font> ".
            
"<font.*>(\S+)<script.*>document.write\((.*)\)</script></font></td><td.*><font.*>(.*)</font></td><td.*>.*</td><td.*>.*</td><td.*>(.*)</td>.*</tr>|isU";

        if (!@
preg_match_all($pattern$data['data'], $listPREG_SET_ORDER))
        {
            return 
FALSE;
        }

        foreach (
$list as $elements)
        {
            if (!isset(
$elements[2]))
            {
                continue;
            }
            
            
$js_list_split explode('+'$elements[2]);
            
$js_return '';

            foreach (
$js_list_split as $js_list_element)
            {
                
$js_list_element str_replace(array('('')'), ''$js_list_element);
                
$js_list_element explode('^'$js_list_element);

                if (isset(
$js_array[$js_list_element[0]]) AND isset($js_array[$js_list_element[1]]))
                {
                    
$js_return .= $js_array[$js_list_element[0]] - $js_array[$js_list_element[1]];
                }
            }
            
            if (
$js_return != '')
            {
                
$this->temp[crc32($elements[1].$js_return)] = array
                (
                    
'ip' => $elements[1],
                    
'port' => $js_return,
                    
'type' => $elements[3],
                    
'country' => trim(str_replace('!'''strip_tags($elements[4]))),
                );
            }
        }

        return 
TRUE;
    }

    
/**
     * 
     *
     * @access    public
     * @return    void
     */
    
private function get_page_data($ip$port$type$page)
    {
        
$socket $this->Http->open_proxy($ip$port'spys.ru'80FALSEFALSE$type5);

        
$headers = array
        (
            
'Host' => 'spys.ru',
            
'User-Agent' => 'Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1',
            
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            
'Accept-Language' => 'ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3',
            
'Accept-Charset' => 'windows-1251,utf-8;q=0.7,*;q=0.7',
            
'Connection' => 'close'
        
);

        
$page = ($page == 0) ? '' $page;

        
$request $this->Http->generate_request('GET''http://spys.ru/proxies'.$page.'/'$headers);
        
$this->Http->write($socket$request);
        
$this->Http->set_timeout($socket5);
        
$content $this->Http->get_content($socket);
        
$this->Http->close($socket);

        if (!isset(
$content['body']) OR $content['code'] != 200)
        {
            return 
FALSE;
        }

        if (!@
preg_match("|<script type=\"text/javascript\">([0-9a-z\=\;\^]+)</script>(.*)$|isU"$content['body'], $list))
        {
            return 
FALSE;
        }

        return array
        (
            
'script' => $list[1],
            
'data' => $list[2]
        );
    }

    
/**
     * Загрузка данных в БД
     *
     * @access    private
     * @return    void
     */
    
private function inject()
    {
        if (
sizeof($this->data['ip']) > 0)
        {
            
$this->Storage->clear($this->table);

            
$structure = array
            (
                
'ip',
                
'port',
                
'type',
                
'anonymous',
                
'differend_ip',
                
'country',
                
'date',
                
'time_connect'
            
);

            
$this->Storage->injection($this->data$structure$this->table);
        }
    }
}

/* EOF Satellite.class.php */