用php實現proxy功能的示範 [已升級至v0.0.2] - 中國WEB開發者網絡 (http://www.webasp.net) -- 技術教程 (http://www.webasp.net/article/) --- 用php實現proxy功能的示範 [已升級至v0.0.2] (http://www.webasp.net/article/17/16937.htm) |
| -- 作者:未知 -- 發佈日期: 2005-03-10 |
| 剛剛寫的練手的作品。感覺還是有些實用價值的。。放出來給大家試試。
功能:通過php實現代理功能 適用用戶:在家下載較慢。且懶得找proxy。且有高速主機,且主機有php,且主機支持socket。 使用方法: 1。把本程序傳到主機上 2。通過瀏覽器瀏覽主機上的此文件 3。在url中填入欲下載的文件地址(如果有必要,可以填入referer) 4。點擊get proxy url 5。新打開的頁面中的鏈接即為通過proxy下載的鏈接 注意: 1。支持多線程下載,斷點續傳 2。僅支持http協議 3。不支持服務器端header重定向 4。不支持http auth 5。下載較大的文件時,可以修改程序中set_time_limit的值,以減少斷線的現象(默認為180,即3分鐘) PHP代碼:-------------------------------------------------------------------------------- <?php /***************************************/ /* */ /* Php Http Proxy */ /* version: 0.0.2 */ /* last modify: 2005.1.12 */ /* author: q3boy<q3boy@sina.com> */ /* */ /***************************************/ set_time_limit(180); define('PP_ERROR_CODE',1); define('PP_ERROR_MESSAGE',2); define('PP_ERROR_ALL',3); define('PP_RETURN_STRING',1); define('PP_RETURN_ARRAY',2); define('PP_RETURN_ALL',3); class CPhpProxy { var $_strUrl; var $_arrArgv; var $_strRef; var $_arrUrl; var $_resSocket; var $_intError; var $_strError; var $_arrDefaultArrayUrl; var $_arrDefaultPort; function CPhpProxy($strUrl = null, $arrArgv = array()) { $this->init(); is_null($strUrl)?'':$this->setUrl($strUrl); is_null($arrArgv['refer'])?'':$this->setRef($arrArgv['refer']); $this->proxy($strUrl,$arrArgv); } function setError($intError,$mixArgv=null) { $this->_intError = $intError; if($intError==1001) { $this->_strError = "調用 $mixArgv 方法時參數傳遞出錯, 枚舉值不存在"; }elseif($intError==1) { $this->_strError = "url 錯誤, url 格式不正確.\n".$mixArgvs; }elseif($intError == 2) { $this->_strError = "url 錯誤, 目前尚未支持此協議.\n".$mixArgvs; }elseif($intError == 3) { $this->_strError = "無法打開 ".$this->_arrUrl['host'].':'.$this->_arrUrl['port']."\n".$mixArgv[0].': '.$mixArgv[1]; } Return false; } function getError($enumReturnType=PP_ERROR_CODE) { if($enumReturnType==PP_ERROR_ALL) { Return array(str_pad($this->_intError,5,'0',STR_PAD_LEFT),$this->_strError); }elseif($enumReturnType==PP_ERROR_MESSAGE) { Return $this->_strError; }elseif($enumReturnType==PP_ERROR_CODE) { Return $this->_intError; }else { Return false; } } function init() { $this->_strUrl = null; $this->_arrArgv = array(); $this->_strRef = null; $this->_arrUrl = array(); $this->_resSocket = null; $this->_intError = 0; $this->_strError = 'there is no error'; //arrurl 默認值 $this->_arrDefaultArrayUrl = array('protocol'=>'http','file'=>'index.htm'); //默認端口 $this->_arrDefaultPort =array('http'=>'80'); Return true; } function setUrl($strUrl) { $strUrl = trim($strUrl); //正則 $reg = "/^(([\w]+):\/\/)?([^:|\/|@]*:)?([^:|\/|@]*@)?([\w|\-|\.]+)(:\d+)?(\/[^\?|#]*)?(\?[^#]*)?(#.*)?$/is"; if(!preg_match($reg,$strUrl,$arrUrl)) { Return $this->setError(1,$strUrl); }else { //拆解匹配數組 list($tmp, $tmp, $arr['protocol'], $arr['user'], $arr['pass'], $arr['host'], $arr['port'], $arr['path'], $arr['query'], $arr['anchor']) = $arrUrl; //默認協議 if(!$arr['protocol']) { $arrUrl[1] = $this->_arrDefaultArrayUrl['protocol'].'://'; } //設 filename $arr['file'] = basename($arr['path']); //默認值 foreach($this->_arrDefaultArrayUrl as $key=>$val) { if($arr[$key] == '') { $arr[$key] = $val; } } //默認端口 if(is_null($this->_arrDefaultPort[$arr['protocol']])) { Return $this->setError(2,$arr['protocol']); }elseif(!$arr['port']) { $arr['port'] = $this->_arrDefaultPort[$arr['protocol']]; } //設 uri $arr['uri'] = ($arr['path']?$arr['path']:'/') . ($arr['query']?'?'.$arr['query']:'') . ($arr['anchor']?'#'.$arr['anchor']:''); //設 url unset($arrUrl[0]); unset($arrUrl[2]); $this->_strUrl = implode('',$arrUrl); //設 arrurl $this->_arrUrl = $arr; Return true; } } function getUrl($enumReturnType = PP_RETURN_ARRAY) { if($enumReturnType==PP_RETURN_STRING) { Return $this->_strUrl; }elseif($enumReturnType==PP_RETURN_ARRAY) { Return $this->_arrUrl; }if($enumReturnType==PP_RETURN_ALL) { Return array($this->_strUrl,$this->_arrUrl); }else { Return $this->setError(1001); } } function setRefer($strRef) { $this->_strRef = trim($strRef); Return true; } function getRefer() { Return $this->_strRef; } function getProxyUrl() { global $_SERVER; list($strProcotol) = explode('/',strtolower(trim($_SERVER['SERVER_PROTOCOL']))); $str = $strProcotol.'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']. '?u='.urlencode($this->getUrl(PP_RETURN_STRING)). ($this->getRefer()?('&r='.urlencode($this->getRefer())):''); Return $str; } function openSocket() { $arr = $this->getUrl(); $this->_resSocket = @fsockopen($arr['host'],$arr['port'],$intError, $strError, 30); if(!$this->_resSocket) { $this->_resSocket = null; Return $this->setError(3,array($intError, $strError)); }else { Return true; } } function getRequest() { Return $this->{'get'.ucfirst($this->_arrUrl['protocol']).'Request'}(); } function sendRequest() { Return fwrite($this->_resSocket,$this->getRequest()); } function flushResponse() { Return $this->{'flush'.ucfirst($this->_arrUrl['protocol']).'Response'}(); } function getHttpRequest() { $arr = $this->getUrl(); $arrRequest = getallheaders(); $arrRequest['Host'] = $arr['host']; $strRequest = "GET ".$arr['uri']." HTTP/1.1\r\n"; foreach($arrRequest as $key=>$val) { $strRequest .="$key: $val\r\n"; } $strRequest .="\r\n"; Return $strRequest; } function flushHttpResponse() { $bolHeader=true; while (!feof($this->_resSocket)) { $str = fgets($this->_resSocket, 4096); if($bolHeader) { @header($str); }else { echo($str); } if($bolHeader && $str=="\r\n") { $bolHeader=false; @header("Content-type: application/gzip"); @header('Content-Disposition: attachment; filename="'.$this->_arrUrl['file'].'"'); } } Return true; } function close() { fclose($this->_resSocket); $this->_resSocket = null; Return true; } function proxy($strUrl = null,$arrArgv = array()) { if(!is_null($this->getUrl(PP_RETURN_STRING)) && $this->openSocket() && $this->sendRequest() && $this->flushResponse()) { echo(123); $this->close(); }else { Return false; } } } if(sizeof($_GET)) { $strGetArrayName = '_GET'; }elseif(sizeof($HTTP_GET_VARS)) { $strGetArrayName = 'HTTP_GET_VARS'; }else { die('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html"> <title>PhpProxy</title> <style type="text/css"> <!--body,td {font-family: verdana; font-size: 12px;}th,input {font-family: verdana;}--> </style> </head> <body> <form name="form1" method="get" action="'.$_SERVER['PHP_SELF'].'"> <table width="500" border="1" align="center" cellpadding="5" cellspacing="1"> <tr> <th colspan="2">PhpProxy</th> </tr> <tr> <td width="39" nowrap>URL:</td> <td width="432"><input name="u" type="text" id="u" size="60"></td> </tr> <tr> <td nowrap>REFERER:</td> <td><input name="r" type="text" id="r" size="60"></td> </tr> <tr> <td colspan="2" align="center"><input name="act" value="make" type="hidden"> <input type="submit" value="Get Proxy Url"> <input type="reset" value="Reset"></td> </tr> </table> </form> </body> </html>'); } $strUrl = trim(${$strGetArrayName}['u']); if($strUrl=='') { die('請輸入 url 地址.'); } //get referer $strRefTmp = trim(${$strGetArrayName}['r']); //初始化 proxy 類 $objProxy = new CPhpProxy(); //設置 url 和 refer $objProxy->setUrl($strUrl); $objProxy->setRefer($strRef); //錯誤輸出 if($objProxy->getError()) { die($objProxy->getError(PP_ERROR_MESSAGE)); } //echo url for download if(${$strGetArrayName}['act']=='make') { die("<center><h4><a href='".$objProxy->getProxyUrl()."'>點擊此處通過 PhpProxy 下載文件</a></h2></center>"); } //取文件 $objProxy->proxy(); //錯誤處理 if($objProxy->getError()) { die($objProxy->getError(PP_ERROR_MESSAGE)); } ?> |
| webasp.net |