mirror of
https://e.coding.net/circlecloud/MinecraftAccount.git
synced 2025-11-26 21:46:09 +00:00
271
ThinkPHP/Library/Org/Net/Http.class.php
Normal file
271
ThinkPHP/Library/Org/Net/Http.class.php
Normal file
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Org\Net;
|
||||
/**
|
||||
* Http 工具类
|
||||
* 提供一系列的Http方法
|
||||
* @author liu21st <liu21st@gmail.com>
|
||||
*/
|
||||
class Http {
|
||||
|
||||
/**
|
||||
* 采集远程文件
|
||||
* @access public
|
||||
* @param string $remote 远程文件名
|
||||
* @param string $local 本地保存文件名
|
||||
* @return mixed
|
||||
*/
|
||||
static public function curlDownload($remote,$local) {
|
||||
$cp = curl_init($remote);
|
||||
$fp = fopen($local,"w");
|
||||
curl_setopt($cp, CURLOPT_FILE, $fp);
|
||||
curl_setopt($cp, CURLOPT_HEADER, 0);
|
||||
curl_exec($cp);
|
||||
curl_close($cp);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 fsockopen 通过 HTTP 协议直接访问(采集)远程文件
|
||||
* 如果主机或服务器没有开启 CURL 扩展可考虑使用
|
||||
* fsockopen 比 CURL 稍慢,但性能稳定
|
||||
* @static
|
||||
* @access public
|
||||
* @param string $url 远程URL
|
||||
* @param array $conf 其他配置信息
|
||||
* int limit 分段读取字符个数
|
||||
* string post post的内容,字符串或数组,key=value&形式
|
||||
* string cookie 携带cookie访问,该参数是cookie内容
|
||||
* string ip 如果该参数传入,$url将不被使用,ip访问优先
|
||||
* int timeout 采集超时时间
|
||||
* bool block 是否阻塞访问,默认为true
|
||||
* @return mixed
|
||||
*/
|
||||
static public function fsockopenDownload($url, $conf = array()) {
|
||||
$return = '';
|
||||
if(!is_array($conf)) return $return;
|
||||
|
||||
$matches = parse_url($url);
|
||||
!isset($matches['host']) && $matches['host'] = '';
|
||||
!isset($matches['path']) && $matches['path'] = '';
|
||||
!isset($matches['query']) && $matches['query'] = '';
|
||||
!isset($matches['port']) && $matches['port'] = '';
|
||||
$host = $matches['host'];
|
||||
$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
|
||||
$port = !empty($matches['port']) ? $matches['port'] : 80;
|
||||
|
||||
$conf_arr = array(
|
||||
'limit' => 0,
|
||||
'post' => '',
|
||||
'cookie' => '',
|
||||
'ip' => '',
|
||||
'timeout' => 15,
|
||||
'block' => TRUE,
|
||||
);
|
||||
|
||||
foreach (array_merge($conf_arr, $conf) as $k=>$v) ${$k} = $v;
|
||||
|
||||
if($post) {
|
||||
if(is_array($post))
|
||||
{
|
||||
$post = http_build_query($post);
|
||||
}
|
||||
$out = "POST $path HTTP/1.0\r\n";
|
||||
$out .= "Accept: */*\r\n";
|
||||
//$out .= "Referer: $boardurl\r\n";
|
||||
$out .= "Accept-Language: zh-cn\r\n";
|
||||
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||
$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
|
||||
$out .= "Host: $host\r\n";
|
||||
$out .= 'Content-Length: '.strlen($post)."\r\n";
|
||||
$out .= "Connection: Close\r\n";
|
||||
$out .= "Cache-Control: no-cache\r\n";
|
||||
$out .= "Cookie: $cookie\r\n\r\n";
|
||||
$out .= $post;
|
||||
} else {
|
||||
$out = "GET $path HTTP/1.0\r\n";
|
||||
$out .= "Accept: */*\r\n";
|
||||
//$out .= "Referer: $boardurl\r\n";
|
||||
$out .= "Accept-Language: zh-cn\r\n";
|
||||
$out .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
|
||||
$out .= "Host: $host\r\n";
|
||||
$out .= "Connection: Close\r\n";
|
||||
$out .= "Cookie: $cookie\r\n\r\n";
|
||||
}
|
||||
$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
|
||||
if(!$fp) {
|
||||
return '';
|
||||
} else {
|
||||
stream_set_blocking($fp, $block);
|
||||
stream_set_timeout($fp, $timeout);
|
||||
@fwrite($fp, $out);
|
||||
$status = stream_get_meta_data($fp);
|
||||
if(!$status['timed_out']) {
|
||||
while (!feof($fp)) {
|
||||
if(($header = @fgets($fp)) && ($header == "\r\n" || $header == "\n")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$stop = false;
|
||||
while(!feof($fp) && !$stop) {
|
||||
$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
|
||||
$return .= $data;
|
||||
if($limit) {
|
||||
$limit -= strlen($data);
|
||||
$stop = $limit <= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@fclose($fp);
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
* 可以指定下载显示的文件名,并自动发送相应的Header信息
|
||||
* 如果指定了content参数,则下载该参数的内容
|
||||
* @static
|
||||
* @access public
|
||||
* @param string $filename 下载文件名
|
||||
* @param string $showname 下载显示的文件名
|
||||
* @param string $content 下载的内容
|
||||
* @param integer $expire 下载内容浏览器缓存时间
|
||||
* @return void
|
||||
*/
|
||||
static public function download ($filename, $showname='',$content='',$expire=180) {
|
||||
if(is_file($filename)) {
|
||||
$length = filesize($filename);
|
||||
}elseif(is_file(UPLOAD_PATH.$filename)) {
|
||||
$filename = UPLOAD_PATH.$filename;
|
||||
$length = filesize($filename);
|
||||
}elseif($content != '') {
|
||||
$length = strlen($content);
|
||||
}else {
|
||||
E($filename.L('下载文件不存在!'));
|
||||
}
|
||||
if(empty($showname)) {
|
||||
$showname = $filename;
|
||||
}
|
||||
$showname = basename($showname);
|
||||
if(!empty($filename)) {
|
||||
$finfo = new \finfo(FILEINFO_MIME);
|
||||
$type = $finfo->file($filename);
|
||||
}else{
|
||||
$type = "application/octet-stream";
|
||||
}
|
||||
//发送Http Header信息 开始下载
|
||||
header("Pragma: public");
|
||||
header("Cache-control: max-age=".$expire);
|
||||
//header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s",time()+$expire) . "GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time()) . "GMT");
|
||||
header("Content-Disposition: attachment; filename=".$showname);
|
||||
header("Content-Length: ".$length);
|
||||
header("Content-type: ".$type);
|
||||
header('Content-Encoding: none');
|
||||
header("Content-Transfer-Encoding: binary" );
|
||||
if($content == '' ) {
|
||||
readfile($filename);
|
||||
}else {
|
||||
echo($content);
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示HTTP Header 信息
|
||||
* @return string
|
||||
*/
|
||||
static function getHeaderInfo($header='',$echo=true) {
|
||||
ob_start();
|
||||
$headers = getallheaders();
|
||||
if(!empty($header)) {
|
||||
$info = $headers[$header];
|
||||
echo($header.':'.$info."\n"); ;
|
||||
}else {
|
||||
foreach($headers as $key=>$val) {
|
||||
echo("$key:$val\n");
|
||||
}
|
||||
}
|
||||
$output = ob_get_clean();
|
||||
if ($echo) {
|
||||
echo (nl2br($output));
|
||||
}else {
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP Protocol defined status codes
|
||||
* @param int $num
|
||||
*/
|
||||
static function sendHttpStatus($code) {
|
||||
static $_status = array(
|
||||
// Informational 1xx
|
||||
100 => 'Continue',
|
||||
101 => 'Switching Protocols',
|
||||
|
||||
// Success 2xx
|
||||
200 => 'OK',
|
||||
201 => 'Created',
|
||||
202 => 'Accepted',
|
||||
203 => 'Non-Authoritative Information',
|
||||
204 => 'No Content',
|
||||
205 => 'Reset Content',
|
||||
206 => 'Partial Content',
|
||||
|
||||
// Redirection 3xx
|
||||
300 => 'Multiple Choices',
|
||||
301 => 'Moved Permanently',
|
||||
302 => 'Found', // 1.1
|
||||
303 => 'See Other',
|
||||
304 => 'Not Modified',
|
||||
305 => 'Use Proxy',
|
||||
// 306 is deprecated but reserved
|
||||
307 => 'Temporary Redirect',
|
||||
|
||||
// Client Error 4xx
|
||||
400 => 'Bad Request',
|
||||
401 => 'Unauthorized',
|
||||
402 => 'Payment Required',
|
||||
403 => 'Forbidden',
|
||||
404 => 'Not Found',
|
||||
405 => 'Method Not Allowed',
|
||||
406 => 'Not Acceptable',
|
||||
407 => 'Proxy Authentication Required',
|
||||
408 => 'Request Timeout',
|
||||
409 => 'Conflict',
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Request Entity Too Large',
|
||||
414 => 'Request-URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Requested Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
|
||||
// Server Error 5xx
|
||||
500 => 'Internal Server Error',
|
||||
501 => 'Not Implemented',
|
||||
502 => 'Bad Gateway',
|
||||
503 => 'Service Unavailable',
|
||||
504 => 'Gateway Timeout',
|
||||
505 => 'HTTP Version Not Supported',
|
||||
509 => 'Bandwidth Limit Exceeded'
|
||||
);
|
||||
if(isset($_status[$code])) {
|
||||
header('HTTP/1.1 '.$code.' '.$_status[$code]);
|
||||
}
|
||||
}
|
||||
}//类定义结束
|
||||
233
ThinkPHP/Library/Org/Net/IpLocation.class.php
Normal file
233
ThinkPHP/Library/Org/Net/IpLocation.class.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace Org\Net;
|
||||
/**
|
||||
* IP 地理位置查询类 修改自 CoolCode.CN
|
||||
* 由于使用UTF8编码 如果使用纯真IP地址库的话 需要对返回结果进行编码转换
|
||||
* @author liu21st <liu21st@gmail.com>
|
||||
*/
|
||||
class IpLocation {
|
||||
/**
|
||||
* QQWry.Dat文件指针
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $fp;
|
||||
|
||||
/**
|
||||
* 第一条IP记录的偏移地址
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $firstip;
|
||||
|
||||
/**
|
||||
* 最后一条IP记录的偏移地址
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $lastip;
|
||||
|
||||
/**
|
||||
* IP记录的总条数(不包含版本信息记录)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $totalip;
|
||||
|
||||
/**
|
||||
* 构造函数,打开 QQWry.Dat 文件并初始化类中的信息
|
||||
*
|
||||
* @param string $filename
|
||||
* @return IpLocation
|
||||
*/
|
||||
public function __construct($filename = "UTFWry.dat") {
|
||||
$this->fp = 0;
|
||||
if (($this->fp = fopen(dirname(__FILE__).'/'.$filename, 'rb')) !== false) {
|
||||
$this->firstip = $this->getlong();
|
||||
$this->lastip = $this->getlong();
|
||||
$this->totalip = ($this->lastip - $this->firstip) / 7;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回读取的长整型数
|
||||
*
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
private function getlong() {
|
||||
//将读取的little-endian编码的4个字节转化为长整型数
|
||||
$result = unpack('Vlong', fread($this->fp, 4));
|
||||
return $result['long'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回读取的3个字节的长整型数
|
||||
*
|
||||
* @access private
|
||||
* @return int
|
||||
*/
|
||||
private function getlong3() {
|
||||
//将读取的little-endian编码的3个字节转化为长整型数
|
||||
$result = unpack('Vlong', fread($this->fp, 3).chr(0));
|
||||
return $result['long'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回压缩后可进行比较的IP地址
|
||||
*
|
||||
* @access private
|
||||
* @param string $ip
|
||||
* @return string
|
||||
*/
|
||||
private function packip($ip) {
|
||||
// 将IP地址转化为长整型数,如果在PHP5中,IP地址错误,则返回False,
|
||||
// 这时intval将Flase转化为整数-1,之后压缩成big-endian编码的字符串
|
||||
return pack('N', intval(ip2long($ip)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回读取的字符串
|
||||
*
|
||||
* @access private
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
private function getstring($data = "") {
|
||||
$char = fread($this->fp, 1);
|
||||
while (ord($char) > 0) { // 字符串按照C格式保存,以\0结束
|
||||
$data .= $char; // 将读取的字符连接到给定字符串之后
|
||||
$char = fread($this->fp, 1);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回地区信息
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
private function getarea() {
|
||||
$byte = fread($this->fp, 1); // 标志字节
|
||||
switch (ord($byte)) {
|
||||
case 0: // 没有区域信息
|
||||
$area = "";
|
||||
break;
|
||||
case 1:
|
||||
case 2: // 标志字节为1或2,表示区域信息被重定向
|
||||
fseek($this->fp, $this->getlong3());
|
||||
$area = $this->getstring();
|
||||
break;
|
||||
default: // 否则,表示区域信息没有被重定向
|
||||
$area = $this->getstring($byte);
|
||||
break;
|
||||
}
|
||||
return $area;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据所给 IP 地址或域名返回所在地区信息
|
||||
*
|
||||
* @access public
|
||||
* @param string $ip
|
||||
* @return array
|
||||
*/
|
||||
public function getlocation($ip='') {
|
||||
if (!$this->fp) return null; // 如果数据文件没有被正确打开,则直接返回空
|
||||
if(empty($ip)) $ip = get_client_ip();
|
||||
$location['ip'] = gethostbyname($ip); // 将输入的域名转化为IP地址
|
||||
$ip = $this->packip($location['ip']); // 将输入的IP地址转化为可比较的IP地址
|
||||
// 不合法的IP地址会被转化为255.255.255.255
|
||||
// 对分搜索
|
||||
$l = 0; // 搜索的下边界
|
||||
$u = $this->totalip; // 搜索的上边界
|
||||
$findip = $this->lastip; // 如果没有找到就返回最后一条IP记录(QQWry.Dat的版本信息)
|
||||
while ($l <= $u) { // 当上边界小于下边界时,查找失败
|
||||
$i = floor(($l + $u) / 2); // 计算近似中间记录
|
||||
fseek($this->fp, $this->firstip + $i * 7);
|
||||
$beginip = strrev(fread($this->fp, 4)); // 获取中间记录的开始IP地址
|
||||
// strrev函数在这里的作用是将little-endian的压缩IP地址转化为big-endian的格式
|
||||
// 以便用于比较,后面相同。
|
||||
if ($ip < $beginip) { // 用户的IP小于中间记录的开始IP地址时
|
||||
$u = $i - 1; // 将搜索的上边界修改为中间记录减一
|
||||
}
|
||||
else {
|
||||
fseek($this->fp, $this->getlong3());
|
||||
$endip = strrev(fread($this->fp, 4)); // 获取中间记录的结束IP地址
|
||||
if ($ip > $endip) { // 用户的IP大于中间记录的结束IP地址时
|
||||
$l = $i + 1; // 将搜索的下边界修改为中间记录加一
|
||||
}
|
||||
else { // 用户的IP在中间记录的IP范围内时
|
||||
$findip = $this->firstip + $i * 7;
|
||||
break; // 则表示找到结果,退出循环
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取查找到的IP地理位置信息
|
||||
fseek($this->fp, $findip);
|
||||
$location['beginip'] = long2ip($this->getlong()); // 用户IP所在范围的开始地址
|
||||
$offset = $this->getlong3();
|
||||
fseek($this->fp, $offset);
|
||||
$location['endip'] = long2ip($this->getlong()); // 用户IP所在范围的结束地址
|
||||
$byte = fread($this->fp, 1); // 标志字节
|
||||
switch (ord($byte)) {
|
||||
case 1: // 标志字节为1,表示国家和区域信息都被同时重定向
|
||||
$countryOffset = $this->getlong3(); // 重定向地址
|
||||
fseek($this->fp, $countryOffset);
|
||||
$byte = fread($this->fp, 1); // 标志字节
|
||||
switch (ord($byte)) {
|
||||
case 2: // 标志字节为2,表示国家信息又被重定向
|
||||
fseek($this->fp, $this->getlong3());
|
||||
$location['country'] = $this->getstring();
|
||||
fseek($this->fp, $countryOffset + 4);
|
||||
$location['area'] = $this->getarea();
|
||||
break;
|
||||
default: // 否则,表示国家信息没有被重定向
|
||||
$location['country'] = $this->getstring($byte);
|
||||
$location['area'] = $this->getarea();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // 标志字节为2,表示国家信息被重定向
|
||||
fseek($this->fp, $this->getlong3());
|
||||
$location['country'] = $this->getstring();
|
||||
fseek($this->fp, $offset + 8);
|
||||
$location['area'] = $this->getarea();
|
||||
break;
|
||||
default: // 否则,表示国家信息没有被重定向
|
||||
$location['country'] = $this->getstring($byte);
|
||||
$location['area'] = $this->getarea();
|
||||
break;
|
||||
}
|
||||
if (trim($location['country']) == 'CZ88.NET') { // CZ88.NET表示没有有效信息
|
||||
$location['country'] = '未知';
|
||||
}
|
||||
if (trim($location['area']) == 'CZ88.NET') {
|
||||
$location['area'] = '';
|
||||
}
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* 析构函数,用于在页面执行结束后自动关闭打开的文件。
|
||||
*
|
||||
*/
|
||||
public function __destruct() {
|
||||
if ($this->fp) {
|
||||
fclose($this->fp);
|
||||
}
|
||||
$this->fp = 0;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user