2010-01-30 9 views
5

Próbuję napisać narzędzie, aby sprawdzić, czy serwer proxy jest gotowy do użycia. Do tej pory znalazłem dwie metody w klasie poniżej (usunąłem settery i pobierające, które są zbędne dla tego pytania).Jaki jest najlepszy sposób na wykrycie, czy serwer proxy jest dostępny?

Pierwsza metoda używa cURL i próbuje zażądać strony za pośrednictwem serwera proxy, drugie narzędzie korzysta z fsockopen i próbuje otworzyć połączenie z serwerem proxy.

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; 
    } 
} 

Jak dotąd, wolę metodę cURL ponieważ pozwala mi sprawdzić dużych partii proxy równolegle, co jest niegodziwy szybko, zamiast jednego w takiej chwili fsockopen.

Nie współpracowałem z serwerami proxy, więc trudno mi stwierdzić, czy któraś z tych metod jest wystarczająca do sprawdzenia, czy serwer proxy jest dostępny, czy też istnieje lepsza metoda, której mi brakuje.

+0

Wow koleś, ładne zdjęcie! –

+0

Haha, dzięki człowieku –

Odpowiedz

1

Hm. Próbując nawiązać połączenie z bezpiecznym (najprawdopodobniej dostępnym) adresem URL za pośrednictwem serwera proxy i sprawdzając błędy, dźwięki o.k. Dla mnie.

Aby uzyskać absolutnie maksymalne bezpieczeństwo, może być konieczne dodanie innego połączenia do innego adresu URL sprawdzania oryginalności (np. Do Google) lub na dwa połączenia, tak na wszelki wypadek.

+0

Drugi test dostępności brzmi jak dobry pomysł, ale im więcej żądań, tym większa wydajność staje się problemem. –

+0

Prawda. To chyba zależy od przeznaczenia. –

1

cURL jest preferowanym sposobem, ze względu na multi_exec.

Nie zawracałbym sobie głowy robieniem dwóch czeków, ale natychmiast zadzwoń do google (lub Proxyjudge). Serwery proxy mogą czasami zezwalać na gniazda, ale po prostu nic nie przyniosą: dlatego metoda cURL będzie bezpieczna, a nie powolna.

Jak wspomina Pekka: zależy to od zamierzonego zastosowania.

Użyłeś Charona i zebrałeś mnóstwo serwerów proxy, chciałbym, żeby sprawdzili się przeciwko proksyjnemu i chciałbym wiedzieć czas realizacji (aby uniknąć powolnych proxy) i anonimowość.

Jeśli chcesz używać go jako systemu monitorowania korporacyjnych serwerów proxy, chciałbym tylko upewnić się, że może pobrać stronę.

a (chaotyczna) Przykład sprawdzania proxy przy użyciu adresu URL z cURL.

TLDR: użyj cURL, może obsługiwać żądania równoległe i jest najbardziej stabilny bez spowolnienia (nie wykonując podwójnego testu). http://www.oooff.com/php-affiliate-seo-blog/php-automation-coding/easy-php-proxy-checker-writing-tutorial/