2010-01-30 3 views
5

Sto provando a scrivere uno strumento per verificare se un server proxy è attivo e disponibile per l'uso. Finora, ho trovato due metodi nella classe qui sotto (ho rimosso setter e getter che sono superflui a questa domanda).Qual è il modo migliore per rilevare se è disponibile un server proxy?

Il primo metodo utilizza cURL e tenta di richiedere una pagina tramite il proxy, il secondo strumento utilizza fsockopen e tenta semplicemente di aprire una connessione al 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; 
    } 
} 

Finora, preferisco il metodo cURL in quanto permette di fare il check grandi lotti di deleghe in parallelo, che è malvagio veloce, invece di uno in un momento come fsockopen.

Non ho lavorato molto con i proxy, quindi è difficile per me dire se uno di questi metodi è sufficiente per convalidare che il proxy è disponibile, o se c'è un metodo migliore che mi manca.

+0

Wow amico, bella foto! –

+0

Haha, grazie uomo –

risposta

1

Hm. Cercando di stabilire una connessione a un URL sicuro (molto probabilmente disponibile) attraverso il proxy e controllando la presenza di errori, suona o.k. per me.

Per la massima sicurezza, potresti voler aggiungere un'altra chiamata a un altro URL di convalida (ad esempio qualcosa su Google) o effettuare due chiamate, per ogni evenienza.

+0

Un secondo controllo di disponibilità sembra una buona idea, ma più richieste vengono fatte, maggiore è il livello di prestazioni. –

+0

Vero. Dipende dall'uso previsto, immagino. –

1

cURL è il modo preferito, a causa del multi_exec.

Non mi preoccuperei di fare due controlli, ma faccio subito la chiamata a google (o Proxyjudge). I proxy a volte possono consentire i socket, ma semplicemente non recuperano nulla: quindi il tuo metodo cURL sarebbe sicuro e non così lento.

Come menzionato da Pekka sopra: dipende dall'uso previsto.

Hai usato Charon e raccolto un carico di proxy, vorrei che venissero confrontati con un proxyjudge e vorrei sapere i tempi di consegna (per evitare i proxy lenti) e l'anonimato.

Se si desidera utilizzarlo come sistema di monitoraggio per i proxy aziendali, vorrei solo assicurarmi che possa recuperare una pagina.

a (caotico) Esempio di controllo di un proxy tramite il recupero di un URL con cURL.

TLDR: utilizzare il cURL, può gestire richieste parallele ed è il più stabile senza essere lento (non eseguendo il doppio controllo). http://www.oooff.com/php-affiliate-seo-blog/php-automation-coding/easy-php-proxy-checker-writing-tutorial/