Как лучше всего определить, доступен ли прокси-сервер? - PullRequest
5 голосов
/ 30 января 2010

Я пытаюсь написать инструмент, чтобы проверить, работает ли прокси-сервер и доступен ли он для использования. До сих пор я придумал два метода из приведенного ниже класса (я удалил сеттеры и геттеры, лишние этого вопроса).

Первый метод использует cURL и пытается запросить страницу через прокси, второй инструмент использует fsockopen и просто пытается открыть соединение с прокси.

class ProxyList {
    /**
     * You could set this to localhost, depending on your environment
     * @var string The URL that the proxy validation method will use to check proxies agains
     * @see ProxyList::validate()
     */
    const VALIDATION_URL = "http://m.www.yahoo.com/robots.txt";
    const TIMEOUT        = 3;

    private static $valid = array(); // Checked and valid proxies
    private $proxies      = array(); // An array of proxies to check

    public function validate($useCache=true) {
        $mh       = curl_multi_init();
        $ch       = null;
        $handles  = array();
        $delay    = count($this->proxies) * 10000;
        $running  = null;
        $proxies  = array();
        $response = null;

        foreach ( $this->proxies as $p ) {
            // Using the cache and the proxy already exists?  Skip the rest of this crap
            if ( $useCache && !empty(self::$valid[$p]) ) {
                $proxies[] = $p;
                continue;
            }

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_HTTP_VERSION,    CURL_HTTP_VERSION_1_1);
            curl_setopt($ch, CURLOPT_URL,             self::VALIDATION_URL);
            curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true);
            curl_setopt($ch, CURLOPT_PROXY,           $p);
            curl_setopt($ch, CURLOPT_NOBODY,          true); // Also sets request method to HEAD
            curl_setopt($ch, CURLOPT_HEADER,          false);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION,  true);
            curl_setopt($ch, CURLOPT_TIMEOUT,         self::TIMEOUT);

            curl_multi_add_handle($mh, $ch);
            $handles[$p] = $ch;
        }

        // Execute the multi-handle
        do {
            curl_multi_exec($mh, $running);
            usleep($delay);
        } while ( $running );

        // Get the results of the requests
        foreach ( $handles as $proxy => $ch ) {
            $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);

            // Great success
            if ( $status >= 200 && $status < 300 ) {
                self::$valid[$proxy] = true;
                $proxies[] = $proxy;
            }
            else {
                self::$valid[$proxy] = false;
            }

            // Cleanup individual handle
            curl_multi_remove_handle($mh, $ch);
        }

        // Cleanup multiple handle
        curl_multi_close($mh);

        return $this->proxies = $proxies;
    }

    public function validate2($useCache=true) {
        $proxies = array();

        foreach ( $this->proxies as $proxy ) {
            // Using the cache and the proxy already exists?  Skip the rest of this crap
            if ( $useCache && !empty(self::$valid[$proxy]) ) {
                $proxies[] = $proxy;
                continue;
            }

            list($host, $post) = explode(":", $proxy);

            if ( $conn = @fsockopen($host, $post, $errno, $error, self::TIMEOUT) ) {
                self::$valid[$proxy] = true;
                $proxies[] = $proxy;
                fclose($conn);
            } else {
                self::$valid[$proxy] = false;
            }
        }

        return $this->proxies = $proxies;
    }
}

Пока что я предпочитаю метод cURL, так как он позволяет мне параллельно проверять большие партии прокси-серверов, что очень быстро, а не по одному за раз, как fsockopen.

Я не проделал большую работу с прокси, поэтому мне сложно сказать, достаточно ли одного из этих методов для проверки доступности прокси или есть какой-то лучший метод, который мне не хватает.

Ответы [ 2 ]

1 голос
/ 04 февраля 2010

cURL является предпочтительным способом из-за multi_exec.

Я бы не стал делать две проверки, но немедленно позвонил бы в Google (или Proxyjudge). Прокси иногда могут разрешать сокеты, но просто ничего не получат: поэтому ваш метод cURL будет безопасным и не таким медленным.

Как упоминает Пекка выше: это зависит от предполагаемого использования.

Использовали ли вы Харон и собрали множество прокси-серверов, я бы хотел, чтобы они проверялись на наличие прокси-сервера, и я хотел бы знать время оборота (чтобы избежать медленных прокси) и анонимность.

Если вы хотите использовать его в качестве системы мониторинга для корпоративных прокси-серверов, я бы просто хотел убедиться, что он может извлечь страницу.

a (хаотично) Пример проверки прокси через выборку URL с помощью cURL.

TLDR: используйте cURL, он может обрабатывать параллельные запросы и является наиболее стабильным без замедления (без двойной проверки). http://www.oooff.com/php-affiliate-seo-blog/php-automation-coding/easy-php-proxy-checker-writing-tutorial/

1 голос
/ 30 января 2010

Hm. Попытка установить соединение с безопасным (наиболее вероятно доступным) URL-адресом через прокси-сервер и проверка на наличие ошибок звучит нормально. для меня.

Для обеспечения максимальной безопасности вы, возможно, захотите добавить еще один вызов к другому URL-адресу проверки (например, в Google) или сделать два вызова на всякий случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...