. */ /* * Good doc : http://findproxyforurl.com/pac_functions_explained.html */ /* * Strings for replacement */ $fstring['shexp'] = 'shExpMatch(url, \'%s\')'; $fstring['innet'] = 'isInNet(host, \'%s\', \'%s\')'; $fstring['protocol'] = 'url.substring(0, %s)=="%s"'; $fstring['others'] = '%s'; $strings = array('innet', 'shexp', 'protocol', 'others'); /* * Load configuration */ if(is_readable('wpad.conf.php')) { $include = 'wpad.conf.php'; } else if(is_readable('/etc/wpad.conf.php')) { $include = '/etc/wpad.conf.php'; } else if(is_readable(getenv('WPADCONF'))) { $include = getenv('WPADCONF'); } include($include); /* * if $_wpad wasn't set we just tell to always run direct */ $conf_loaded = true; if(!isset($_wpad)) { $conf_loaded = false; } /* * Check an URL to see if proxy is alive. The file must contain OK */ function checkProxyIsAlive($proxy, $url) { $ret = false; $fp = fsockopen($proxy[0], $proxy[1], $errno, $errstr); if($fp) { fwrite($fp, 'GET ' . "$url\r\n"); $data = ''; while(!feof($fp)) { $data .= fgets($fp, 128); } fclose($fp); if($data == 'OK') $ret = true; } return $ret; } /* * Proxy Round Robin selection. Each time this script is ran, change order for * each proxy in the list. This will load-balance proxies. */ function getProxyRR($file, $sem, $maxProxy) { $ret = 0; $s = sem_get($sem); sem_acquire($s); $fp = fopen($file, 'r'); if($fp) { $last = fgets($fp); if(intval($last) >= $maxProxy - 1) { $next = 0; } else { $next = intval($last)+1; } fclose($fp); $fp = fopen($file, 'w'); if($fp) { fwrite($fp, $next); fclose($fp); } $ret = $next; } sem_release($s); return $next; } /* * Prepare time and expire time */ $now = time(); if($conf_loaded) { $expire = $now + $_wpad['expire']; $max_age = $_wpad['expire']; } else { $expire = $now + 3600; // default to 1 h $max_age = 3600; } /* * Expire now in debug mode */ if($_wpad['debug'] == true) { $expire = $now; $max_age = 0; } /* * Header for wpad.dat * Firefox doesn't follow max-age and expire and I haven't try with others * In debug mode we send text/plain */ if($_wpad['debug'] == true) { header('Content-Type: text/plain; charset=utf-8'); } else { header('Content-Type: application/x-ns-proxy-autoconfig'); } header('Cache-Control: must-revalidate, max-age=' . $max_age ); /* * Thanks http://ch.php.net/manual/en/function.gmdate.php#25031 */ header('Date: '. gmdate('D, d M Y H:i:s \G\M\T', $now)); header('Last-Modified: '. gmdate('D, d M Y H:i:s \G\M\T', $now)); header('Expires: '. gmdate('D, d M Y H:i:s \G\M\T', $expire)); $wpad_txt = 'function FindProxyForURL(url, host) {' . "\n"; $wpad_txt .= "\t" . 'var direct="DIRECT";' . "\n"; if(!$conf_loaded) { $wpad_txt .= "\t" . 'return direct;' . "\n"; } else { /* * Our proxies list */ $proxies = $_wpad['proxies']; $av = array(); foreach($proxies as $proxy) { if(checkProxyIsAlive($proxy, $_wpad['proxy_check_url'])) $av[] = $proxy; } $proxiesNum = count($av); /* * Generate list of proxies for wpad.pac, do round-robin selection of the * first proxy in the list. */ $wpad_txt .= "\t" . 'var proxies = "'; if($proxiesNum > 0) { $proxyFirst = getProxyRR($_wpad['proxyrr_file'], $_wpad['semkey'], $proxiesNum); for($i = $proxyFirst; $i < $proxiesNum; $i++) { $wpad_txt .= 'PROXY ' . $av[$i][0] . ':' . $av[$i][1] .'; '; } for($i = 0; $i < $proxyFirst; $i++) { $wpad_txt .= 'PROXY ' . $av[$i][0] . ':' . $av[$i][1] .'; '; } } $wpad_txt .= 'DIRECT";' . "\n\n"; /* * Prepare the protocol replacement array */ $protocol = array(); if(count($_wpad['protocol'])) { foreach($_wpad['protocol'] as $p) { $protocol[] = array(strval(strlen($p)), $p); } } $_wpad['protocol'] = $protocol; /* * Goes through each seaction and generate conditions for it */ foreach($strings as $s) { if(count($_wpad[$s])>0) { $wpad_txt .= "\t" . 'if('; $first=true; foreach($_wpad[$s] as $exp) { if(!$first) { $wpad_txt .= "\n\t " . '|| '; } if(is_array($exp)) { $wpad_txt .= vsprintf($fstring[$s], $exp); } else { $wpad_txt .= sprintf($fstring[$s], $exp); } $first=false; } $wpad_txt .= ")\n\t{\n\t\treturn direct;\n\t}\n\n"; } } } $wpad_txt .= "\n\t" . 'return proxies;'. "\n". '}' . "\n"; /* * Here we are */ echo $wpad_txt; exit(0); ?>