Proxy
剛剛寫的練手的作品。感覺還是有些實用價值的。。放出來給大家試試。
功能:通過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 Http Proxy */
/* version: 0.0.2 */
/* last modify: 2005.1.12 */
/* author: q3boy */
/* */
/***************************************/
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('
PhpProxy
');
}
$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("
getProxyUrl()."'>點擊此處通過 PhpProxy 下載檔案
");
}
//取檔案
$objProxy->proxy();
//錯誤處理
if($objProxy->getError()) {
die($objProxy->getError(PP_ERROR_MESSAGE));
}
?>