PHP学会网 php培训网 PHP暑期培训 PHP寒假培训 PHP假期培训 » 入门和基础知识 » 用php实现proxy功能的示范 [已升级至v0.0.2]
本页主题: 用php实现proxy功能的示范 [已升级至v0.0.2] 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

自由的龙

该用户目前不在线
级别: 中级程序员
精华: 1
发帖: 1264
威望: 1267 点
金钱: 12660 PYMB
贡献值: 0 点
在线时间:0(小时)
注册时间:2006-04-16
最后登录:2006-06-27

用php实现proxy功能的示范 [已升级至v0.0.2]


刚刚写的练手的作品。感觉还是有些实用价值的。。放出来给大家试试。
功能:通过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分钟)


CODE:[Copy to clipboard]<?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 格式不正确.
".$mixArgvs;
    }elseif($intError == 2) {
        $this->_strError = "url 错误, 目前尚未支持此协议.
".$mixArgvs;
    }elseif($intError == 3) {
        $this->_strError = "无法打开 ".$this->_arrUrl['host'].':'.$this->_arrUrl['port']."
".$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
";
    foreach($arrRequest as $key=>$val) {
        $strRequest .="$key: $val
";
    }
    $strRequest .="
";
    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=="
") {
          $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));
}
?>
顶端 Posted: 2006-04-16 19:13 | [楼 主]
PHP学会网 php培训网 PHP暑期培训 PHP寒假培训 PHP假期培训 » 入门和基础知识

时:01-09 03:18 Copyright © 2006 phpwhy.com 权
ICP05060669

曳息 -