I need to be able to test a webservice with a lot of different setups, so I wrote this a few minutes ago. I just thought I would post it to see if anyone saw any potential bugs.
Code:<?php
class Proxies {
const PROXY_HTTP = 'HTTP';
const PROXY_HTTPS = 'HTTPS';
const PROXY_ANONYMOUS = 'high';
const PROXY_NOT_ANONYMOUS = 'low';
const PROXY_UP = 0;
const PROXY_DOWN = 1;
const PROXY_UNKNOWN = 2;
const MAX_LAG = 3;
private static $_COUNTRIES = array(
'KOREA',
'ITALY',
'RUSSIA',
'IRAN',
'BRAZIL',
'COLUMBIA',
'INDONESIA',
'SWEDEN',
'USA',
'NETHERLANDS',
'IRELAND',
'JAPAN',
'GERMANY',
'PORTUGAL',
'UKRAINE',
'CHINA',
'SLOVAKIA',
'VIETNAM'
);
private static $_isup;
private static $_countries = array();
private static $_secure = array();
private static $_anon = array();
private static $_lag = array();
/**
* Will return the ip:port tuple of a proxy that fits the filter criteria
* This might return null
* It records all of the information from the proxies, and will not try the same one twice,
* if a proxy has already been used, it will check to see that it is still up, then return that one, if
* more than one proxy has been used before, it will take the fastest one (if it's still up)
*/
public static function getProxy($protocol = null, $anon = null, $country = null){
if (is_string($protocol)){
switch (strtoupper($protocol)){
case 'PAROS':
return 'localhost:8080';
case 'FIDDLER':
return 'localhost:8888';
}
}
self::_seed();
return self::_getUpProxy(self::_filterProxies($protocol, $anon, $country));
}
/**
* Does nothing but seeds the arrays (if necessary)
*/
private static function _seed(){
if (!isset(self::$_isup)){
self::$_isup = array();
self::_addNewProxy('58.150.182.76', '8080', 'Korea', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('151.8.65.5', '80', 'Italy', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('89.222.205.63', '3128', 'Russia', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('78.111.8.44', '80', 'Iran', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('187.4.128.10', '3128', 'Brazil', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('200.75.42.66', '3128', 'Columbia', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('201.76.212.250', '8080', 'Brazil', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('202.146.129.131', '80', 'Indonesia', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('202.146.129.133', '8080', 'Indonesia', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('95.143.192.173', '80', 'Sweden', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('189.11.196.220', '3128', 'Brazil', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('95.143.192.28', '80', 'Sweden', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('66.71.246.181', '3128', 'USA', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('109.235.49.143', '80', 'Netherlands', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('210.101.131.232', '8080', 'Korea', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('78.111.8.233', '80', 'Iran', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('217.219.97.11', '3128', 'Iran', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('211.222.202.60', '80', 'Korea', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('65.172.48.18', '8081', 'USA', self::PROXY_HTTP, self::PROXY_NOT_ANONYMOUS);
self::_addNewProxy('128.179.150.70', '3127', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('128.187.223.211', '3127', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('128.208.04.198', '2124', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('134.226.52.35', '3124', 'Ireland', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('210.123.39.103', '3124', 'Korea', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.178.133.03', '3127', 'Japan', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('210.123.39.103', '3124', 'Korea', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.178.133.03', '3127', 'Japan', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('198.133.224.147', '3128', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('131.247.2.247', '3127', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('210.125.84.41', '3127', 'Korea', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('130.83.166.245', '3127', 'Germany', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('193.136.124.226', '3127', 'Portugal', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('131.247.2.245', '3128', 'USA', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('193.136.124.228', '3128', 'Portugal', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.178.133.002', '3127', 'Japan', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('193.136.124.226', '3124', 'Portugal', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.178.133.02', '3127', 'Japan', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('192.26.179.68', '3128', 'Germany', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('192.26.179.69', '3128', 'Germany', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('91.143.58.1', '9000', 'Russia', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('210.123.39.102', '3124', 'Korea', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('210.123.39.103', '3128', 'Korea', self::PROXY_HTTP, self::PROXY_ANONYMOUS);
self::_addNewProxy('212.115.237.55', '54321', 'Ukraine', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('187.84.226.147', '8000', 'Brazil', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('213.248.47.88', '8888', 'Russia', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('194.12.67.252', '8090', 'Ukraine', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('221.1.96.22', '443', 'China', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('193.87.164.122', '8080', 'Slovakia', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('87.117.135.86', '8080', 'Russia', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.162.163.79', '80', 'Vietnam', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('216.240.138.76', '5555', 'USA', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('78.111.8.101', '80', 'Iran', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('203.171.227.226', '3128', 'China', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('211.95.79.134', '80', 'China', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('219.101.138.4', '80', 'Japan', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('187.95.38.71', '3128', 'Brazil', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('66.71.246.181', '3128', 'USA', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('67.164.171.156', '3128', 'USA', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('208.92.39.31', '3128', 'USA', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
self::_addNewProxy('65.172.48.18', '8080', 'USA', self::PROXY_HTTPS, self::PROXY_ANONYMOUS);
}
}
/**
* Adds a proxy to the list
*/
private static function _addNewProxy($ip, $port, $country, $secure, $anon){
if (!in_array(strtoupper($country), self::$_COUNTRIES)){
trigger_error('bad country name');
}
$ipport = $ip . ':' . $port;
self::$_isup[$ipport] = self::PROXY_UNKNOWN;
self::$_COUNTRIES[$ipport] = $country;
self::$_secure[$ipport] = $secure;
self::$_anon[$ipport] = $anon;
self::$_lag[$ipport] = self::MAX_LAG;
}
/**
* Checks to make sure that the proxy is up or not
* @return bool
*/
private static function _isUp($proxy){
$splited = explode(':',$proxy); // Separate IP and port
echo '.';
$timer = microtime(true);
if($con = @fsockopen($splited[0], $splited[1], $eroare, $eroare_str, self::MAX_LAG)) {
$timer = microtime(true) - $timer;
echo '.';
@fclose($con); // Close the socket handle
echo '.';
self::$_isup[$proxy] = PROXY_UP;
if (self::$_lag[$proxy] === self::MAX_LAG){ //record time it took
self::$_lag[$proxy] = $timer;
} else {
self::$_lag[$proxy] += $timer; //use a rolling average
self::$_lag[$proxy] /= 2;
}
echo ' Success with ' . round($timer, 2) . ' second lag' . PHP_EOL;
return true;
}
self::$_isup[$proxy] = PROXY_DOWN;
echo '.. Failed (' . $eroare_str . ')' . PHP_EOL;
return false;
}
/**
* Gets a proxy that is up
* @return ip
*/
private static function _getUpProxy(array & $proxies){
//first check that we already know are up, check fastest first
asort(self::$_lag);
foreach(self::$_lag as $key => $lag){
if (isset($proxies[$key])){
if (self::$_isup[$key] === PROXY_UP){
echo 'Checking that proxy ' . $key . ' using ' . self::$_secure[$key] . ' with ' . self::$_anon[$key] . ' animosity in ' . self::$_COUNTRIES[$key] . ' and average lag of ' . round(self::$_lag[$key], 2) . ' is still up';
if (self::_isUp($key)){
return $key;
}
unset($proxies[$key]);
}
}
}
//none know to be up, trying others
foreach($proxies as $proxy){
echo 'Trying to connect to proxy ' . $proxy . ' using ' . self::$_secure[$proxy] . ' with ' . self::$_anon[$proxy] . ' animosity in ' . self::$_COUNTRIES[$proxy];
if (self::_isUp($proxy)){
return $proxy;
}
}
//Tell the user that they need more proxies
echo 'Out of proxies, add more from www.hidemyass.com/proxy-list' . PHP_EOL;
}
/**
* Fliters out proxies that don't match the criteria
* @return array<ip, ip>
*/
private static function _filterProxies($secure, $anon, $country){
$afterfilter = array();
$outstring = array();
//first take out the ones flagged as down
foreach(self::$_isup as $key => $value){
if ($value != PROXY_DOWN){
$afterfilter[] = $key;
}
}
//then take out those that dont use the right protocol
if (!is_null($secure)){
$outstring[] = $secure . ' protocol';
foreach($afterfilter as $key => $ip){
if (self::$_secure[$ip] != $secure){
unset($afterfilter[$key]);
}
}
} else {
$outstring[] = 'HTTP or HTTPS protocol';
}
//then take out the ones with the wrong level of animosity
if (!is_null($anon)){
$outstring[] = $anon . ' animosity';
foreach($afterfilter as $key => $ip){
if (self::$_anon[$ip] != $anon){
unset($afterfilter[$key]);
}
}
} else {
$outstring[] = 'high or low animosity';
}
//then take out the ones in the wrong countries
if (!is_null($country)){
//take out those in the coutry you want to exclude
if (strtoupper(substr($country, 0, 4)) === 'NOT '){
$country = substr($country, 4);
$outstring[] = 'and not in ' . $country;
$country = strtoupper($country);
foreach($afterfilter as $key => $ip){
if (strtoupper(self::$_COUNTRIES[$ip]) == $country){
unset($afterfilter[$key]);
}
}
//take out those in countries not the one you want
} else {
$outstring[] = 'and in ' . $country;
$country = strtoupper($country);
if (!in_array($country, self::$_COUNTRIES)){
trigger_error('bad country name');
}
foreach($afterfilter as $key => $ip){
if (strtoupper(self::$_COUNTRIES[$ip]) != $country){
unset($afterfilter[$key]);
}
}
}
} else {
$outstring[] = 'and in any country';
}
shuffle($afterfilter);
echo 'There are ' . count($afterfilter) . ' proxies that match: ' . implode($outstring, ', ') . PHP_EOL;
//index them
$result = array();
foreach($afterfilter as $proxy){
$result[$proxy] = $proxy;
}
return $result;
}
}
echo(Proxies::getProxy(Proxies::PROXY_HTTPS, Proxies::PROXY_ANONYMOUS, 'not USA') . PHP_EOL);
echo(Proxies::getProxy(Proxies::PROXY_HTTP, Proxies::PROXY_ANONYMOUS, 'not USA') . PHP_EOL);
echo(Proxies::getProxy(Proxies::PROXY_HTTP, Proxies::PROXY_ANONYMOUS, 'USA') . PHP_EOL);
echo(Proxies::getProxy(Proxies::PROXY_HTTPS, Proxies::PROXY_ANONYMOUS) . PHP_EOL);
echo(Proxies::getProxy(null, null, 'China') . PHP_EOL);