http_class.php
资源名称:BBWPS.rar [点击查看]
上传用户:yttaitong
上传日期:2009-05-10
资源大小:128k
文件大小:14k
源码类别:
WEB源码(ASP,PHP,...)
开发平台:
PHP
- <?php
- /*
- [BBWPS!] (C)2006-2010 小蜜蜂版权所有.
- This is NOT a freeware, use is subject to license terms
- 时间:2007年12月
- 描述:模拟客户端,实现HTTP协议(翻译)
- */
- class HttpClient {
- var $host; //服务器
- var $port; //端口
- var $path; //路径
- var $method; //请求方式
- var $postdata = ''; //请求数据参数
- var $cookies = array(); //COOKIE
- var $referer; //上一级访问的URL
- var $etag;
- var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
- var $accept_encoding = 'gzip'; //接受的压缩编码
- var $accept_language = 'en-us'; //接受的语言
- var $user_agent = 'HttpClient'; //用户代理
- // 下边的是可选变量
- var $timeout = 20; //请求的时间
- var $use_gzip = true; //是否下载
- var $persist_cookies = true; //是否让COOKIE保持永久有效
- var $persist_referers = true; //是否每次请求都要写上最后一次请求的URL
- var $debug = false; //调试是否开启
- var $handle_redirects = true; //自动跳转URL是否开启
- var $max_redirects = 5; //最大的跳转次数
- var $headers_only = false; //是否只接受头信息
- //基本的授权变量
- var $username; //用户名
- var $password; //密码
- //响应的变量
- var $status; //状态
- var $headers = array(); //头信息
- var $content = ''; //内容
- var $errormsg; //错误
- //跟踪变量
- var $redirect_count = 2; //跳转的次数
- var $cookie_host = ''; //COOKIE服务器
- //构造函数
- function HttpClient($host, $port=80) {
- $this->host = $host;
- $this->port = $port;
- }
- //用GET方法进行请求,data参数是附加的请求时候的参数
- function get($path, $data = false) {
- $this->path = $path;
- $this->method = 'GET';
- if ($data) {
- $this->path .= '?'.$this->buildQueryString($data); //给URL增加了参数
- }
- return $this->doRequest();
- }
- //用POST方法进行请求,data参数的是提交的内容
- function post($path, $data) {
- $this->path = $path;
- $this->method = 'POST';
- $this->postdata = $this->buildQueryString($data); //增加提交参数
- return $this->doRequest();
- }
- //设置请求时候的附加参数
- function buildQueryString($data) {
- $querystring = '';
- if (is_array($data)) {
- //改变参数数组的内容
- foreach ($data as $key => $val) {
- if (is_array($val)) {
- foreach ($val as $val2) {
- //将变量进行URL编码,多个参数用&分开
- $querystring .= urlencode($key).'='.urlencode($val2).'&';
- }
- }
- else {
- $querystring .= urlencode($key).'='.urlencode($val).'&';
- }
- }
- $querystring = substr($querystring, 0, -1); //消除最后边的一个&
- }
- else {
- $querystring = $data;
- }
- return $querystring;
- }
- //HTTP请求
- function doRequest() {
- //创建并打开一个SOCKET
- if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) {
- //判断是不是连接上服务器
- switch($errno) {
- case -3:
- $this->errormsg = 'Socket创建失败(-3)';
- case -4:
- $this->errormsg = 'DNS没有解析到该域名(-4)';
- case -5:
- $this->errormsg = '不能匿名连接或者是超时(-5)';
- default:
- $this->errormsg = '连接失败('.$errno.')';
- $this->errormsg .= ' '.$errstr;
- $this->debug($this->errormsg);
- }
- return false;
- }
- //设置SOCKET的超时时间
- socket_set_timeout($fp, $this->timeout);
- //设置请求的头信息
- $request = $this->buildRequest();
- $this->debug('Request', $request);
- fwrite($fp, $request); //将请求的信息写入SOCKET模拟HTTP请求
- //将所有的变量清空,以等待响应
- $this->headers = array(); //保存响应的头信息
- $this->content = ''; //保存响应的内容
- $this->errormsg = ''; //保存响应的错误编号
- //设置两个标志变量
- $inHeaders = true;
- $atStart = true;
- //现在开始读取响应的信息和读文件的操作是一样的
- while (!feof($fp)) {
- $line = fgets($fp, 4096); //读去一行信息
- if ($atStart) {
- //开始处理信息
- $atStart = false; //设置标志信息进行临界数据保护
- if (!preg_match('/HTTP/(\d\.\d)\s*(\d+)\s*(.*)/is', $line, $m)) { //字符串剖析
- $this->errormsg = "响应的状态不完整: ".htmlentities($line);
- $this->debug($this->errormsg);
- return false;
- }
- $http_version = $m[1]; //保存HTTP协议的版本
- $this->status = $m[2]; //保存响应的状态号
- $status_string = $m[3]; //保存状态信息
- $this->debug(trim($line));
- continue; //读去下一行的内容
- }
- if ($inHeaders) {
- if (trim($line) == '') {
- $inHeaders = false;
- $this->debug('Received Headers', $this->headers);
- if ($this->headers_only) {//判断是否每次请求只是需求头信息
- break; //
- }
- continue;
- }
- if (!preg_match('/([^:]+):\s*(.*)/is', $line, $m)) {
- continue; //读去下一行的内容,本次循环结束
- }
- $key = strtolower(trim($m[1]));
- $val = trim($m[2]);
- //处理头信息,有可能是嵌套
- if (isset($this->headers[$key])) {
- if (is_array($this->headers[$key])) {
- $this->headers[$key][] = $val;
- } else {
- $this->headers[$key] = array($this->headers[$key], $val);
- }
- } else {
- $this->headers[$key] = $val;
- }
- continue;
- }
- //将头信息附加到内容中
- $this->content .= $line;
- }
- fclose($fp);
- //如果数据是被压缩,判断是否可以接受压缩类型的文件
- if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
- $this->debug('接受的内容是压缩类型, 正在解压');
- $this->content = substr($this->content, 10); //
- $this->content = gzinflate($this->content); //解压数据
- }
- $this->etag=$this->headers["etag"];
- //如是需要有长时间的COOKIE有效,把COOKIE的内容保存起来,这里没有关心COOKIE的目录,在实际操作中有可能是无效的,在这里的时候COOKIE的服务器和服务器并不一定相同
- if ($this->persist_cookies && isset($this->headers['set-cookie'])) {
- $cookies = $this->headers['set-cookie'];
- if (!is_array($cookies)) {
- $cookies = array($cookies);
- }
- foreach ($cookies as $cookie) {
- if (preg_match('/([^=]+)=([^;]+);/is', $cookie, $m)) { //原来的代码有点问题,在上面分析之后COOKIE之间就没有了;所以以;结束的话不能找到值
- $this->cookies[$m[1]] = $m[2];
- }
- else{
- if(preg_match('/([^=]+)=([^;]+)/is', $cookie, $m)){
- $this->cookies[$m[1]] = $m[2];
- }
- }
- }
- //记录COOKIE的域,避免混淆和个服务器的COOKIE
- $this->cookie_host = $this->host;
- }
- //为下一次的提交做准备,一般都是没有什么用处的
- if ($this->persist_referers) {
- //$this->debug('Persisting referer: '.$this->getRequestURL());
- //$this->debug('Persisting referer: '.'http://www.yesho.com/');
- $this->referer = $this->getRequestURL();
- }
- //如果支持自动转向的
- if ($this->handle_redirects) {
- if (++$this->redirect_count >= $this->max_redirects) {
- $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
- $this->debug($this->errormsg);
- $this->redirect_count = 0;
- return false;
- }
- //分析转向的地址,并从新发出请求
- $location = isset($this->headers['location']) ? $this->headers['location'] : '';
- $uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
- if ($location || $uri) {
- $url = parse_url($location.$uri);
- $this->host=$url["host"];
- return $this->get($url['path']);
- }
- }
- return true;
- }
- //设置请求的头信息,必须遵守HTTP协议
- function buildRequest() {
- $headers = array();
- //设置HTTP协议的版本
- $headers[] = "{$this->method} {$this->path} HTTP/1.0";
- //设置请求的服务器
- $headers[] = "Host: {$this->host}";
- //设置代理用户,一般有浏览器或者是其他的应用程序,这里就是这个HTTPCLIENT这个程序
- $headers[] = "User-Agent: {$this->user_agent}";
- //设置可以接受的文件类型
- $headers[] = "Accept: {$this->accept}";
- //设置编码
- if ($this->use_gzip) {
- $headers[] = "Accept-encoding: {$this->accept_encoding}";
- }
- //设置语言
- $headers[] = "Accept-language: {$this->accept_language}";
- if ($this->referer) {
- $headers[] = "Referer: {$this->referer}";
- }
- //测试语句
- //$headers[] = "Referer: {http://count.skycn.com/softdownload.php?id=22620&url=http%3A%2F%2Fgztt.driversky.com%2Fdown%2FMOVDemo.exe}";
- //$headers[] = "Etag: {$this->etag}";
- // 设置Cookies
- if ($this->cookies) {
- $cookie = 'Cookie: ';
- foreach ($this->cookies as $key => $value) {
- $cookie .= "$key=$value; ";
- }
- $headers[] = $cookie;
- }
- // 设置基本的授权认可,在一般的WEB服务器都是接受WWW的匿名用户,所以用处不是很大
- if ($this->username && $this->password) {
- $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
- }
- // 如果是POST请求设置内容的类型和长度
- if ($this->postdata) {
- $headers[] = 'Content-Type: application/x-www-form-urlencoded';
- $headers[] = 'Content-Length: '.strlen($this->postdata);
- }
- $request = implode("rn", $headers)."rnrn".$this->postdata;
- return $request;
- }
- //获得请求的状态
- function getStatus() {
- return $this->status;
- }
- //获得请求返回的内容
- function getContent() {
- return $this->content;
- }
- //获得请求返回的头信息
- function getHeaders() {
- return $this->headers;
- }
- //获得某一项的头信息
- function getHeader($header) {
- $header = strtolower($header);
- if (isset($this->headers[$header])) {
- return $this->headers[$header];
- } else {
- return false;
- }
- }
- //获得错误报告
- function getError() {
- return $this->errormsg;
- }
- //获得COOKIE
- function getCookies() {
- return $this->cookies;
- }
- //获得请求的URL
- function getRequestURL() {
- $url = 'http://'.$this->host;
- if ($this->port != 80) {
- $url .= ':'.$this->port;
- }
- $url .= $this->path;
- return $url;
- }
- // 设置用户
- function setUserAgent($string) {
- $this->user_agent = $string;
- }
- //设置证书
- function setAuthorization($username, $password) {
- $this->username = $username;
- $this->password = $password;
- }
- //设置COOKIE
- function setCookies($array) {
- $this->cookies = $array;
- }
- function setHost($string){
- $this->host=$string;
- }
- function setPath($string){
- $this->path=$string;
- }
- //可选
- function useGzip($boolean) {
- $this->use_gzip = $boolean;
- }
- //设置长期保存的COOKIE
- function setPersistCookies($boolean) {
- $this->persist_cookies = $boolean;
- }
- //设置是否保持最后一次的请求
- function setPersistReferers($boolean) {
- $this->persist_referers = $boolean;
- }
- //设置是否重定向
- function setHandleRedirects($boolean) {
- $this->handle_redirects = $boolean;
- }
- //设置重定向的次数
- function setMaxRedirects($num) {
- $this->max_redirects = $num;
- }
- function setHeadersOnly($boolean) {
- $this->headers_only = $boolean;
- }
- //是否打开调试的状态
- function setDebug($boolean) {
- $this->debug = $boolean;
- }
- function setTimePara($time){
- $this->timeout=$time;
- }
- //快速,简单的GET方法请求
- function quickGet($url) {
- $bits = parse_url($url);
- $host = $bits['host'];
- $port = isset($bits['port']) ? $bits['port'] : 80;
- $path = isset($bits['path']) ? $bits['path'] : '/';
- if (isset($bits['query'])) {
- $path .= '?'.$bits['query'];
- }
- $client = new HttpClient($host, $port);
- if (!$client->get($path)) {
- return false;
- } else {
- return $client->getContent();
- }
- }
- //快速,简单的POST方法请求
- function quickPost($url, $data) {
- $bits = parse_url($url);
- $host = $bits['host'];
- $port = isset($bits['port']) ? $bits['port'] : 80;
- $path = isset($bits['path']) ? $bits['path'] : '/';
- $client = new HttpClient($host, $port);
- if (!$client->post($path, $data)) {
- return false;
- } else {
- return $client->getContent();
- }
- }
- //调试代码
- function debug($msg, $object = false) {
- if ($this->debug) {
- print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> '.$msg;
- if ($object) {
- ob_start();
- print_r($object);
- $content = htmlentities(ob_get_contents());
- ob_end_clean();
- print '<pre>'.$content.'</pre>';
- }
- print '</div>';
- }
- }
- }
- ?>