就是为了给KK的云签服务的,服务端是直接检测文件MD5值,然后程序端这边检测,下载。
现在问题来了,可以正常检测到文件差异,但更新不下来或者说是(无法下载文件)可是是利用其他思路的可以正常下载文件,说明服务器本身没有问题,请各位大神帮我看下程序上有没有什么问题。
<?php
define('UPDATA_SOURCE', './Tieba'); //这个目录就是用来检查差异文件的
chdir(UPDATA_SOURCE);
if($_GET['action'] == 'filelist') {
$dirs = array('./');
$rt = array();
do {
$dir = array_pop($dirs);
$tmp = scandir($dir);
foreach($tmp as $f) {
if($f == '.' || $f == '..')
continue;
$path = $dir . $f;
if(is_dir($path)) {
array_push($dirs, $path . '/');
} elseif (is_file($path)) {
$rt [] = $path;
}
}
} while($dirs);
foreach($rt as $file){
$str[$file] = md5_file($file);
}
echo json_encode($str);
exit();
} elseif($_GET['action'] == 'getfile') {
if (!file_exists($_GET['path'])){
header("Content-type: text/html; charset=utf-8");
echo "File not found!";
exit;
} else {
$file = fopen($_GET['path'], "r");
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Accept-Length: " . filesize($_GET['path']));
header("Content-Disposition: attachment; filename=" . array_pop(explode('/', $_GET['path'])));
echo fread($file, filesize($_GET['path']));
fclose($file);
exit;
}
}
?>
<?php
if(!defined('IN_KKFRAME')) exit('Access Denied');
class Updater{
const UPDATE_URL = 'http://update.liujiantao.me/';
public static function init(){
global $_config;
if($_config['version']){
$current_version = $_config['version'];
} else {
$current_version = getSetting('version');
}
if ($current_version == VERSION) return;
$version = $current_version;
while($version){
$filepath = SYSTEM_ROOT."./function/updater/{$version}.php";
if(file_exists($filepath)){
include $filepath;
exit();
} else{
$version = substr($version, 0, strrpos($version, '.'));
}
}
include SYSTEM_ROOT.'./function/updater/fallback.php';
exit();
}
public static function check(){
$data = kk_fetch_url(self::UPDATE_URL."updata.php?action=filelist");
saveSetting('new_version', 0);
if (!$data) return -1;
$file_list = json_decode($data);
if (!$file_list) return -2;
$err_file = $list = array();
foreach($file_list as $path => $hash) {
$file_hash = md5_file(ROOT."./{$path}");
if ($file_hash != $hash){
$err_file[] = array($path, $hash);
$list[] = $path;
}
}
if(!$list) return 0;
saveSetting('new_version', 1);
sort($list);
sort($err_file);
CACHE::save('kk_updater', $err_file);
CACHE::save('need_download', $err_file);
DB::query('DELETE FROM download');
return $list;
}
public static function loop(){
if(defined('IN_XAE')) return array('status' => -3);
$file_list = CACHE::get('need_download');
list($path, $hash) = array_pop($file_list);
if(!$path) return array('status' => 1);
$ret = self::_download_file($path, $hash);
if ($ret<0) return array('status' => $ret, 'file' => $path);
CACHE::save('need_download', $file_list);
$max = sizeof(CACHE::get('kk_updater'));
$current = $max - sizeof($file_list);
return array('status' => 0, 'precent' => round($current / $max * 100), 'file' => $path);
}
public static function write_file(){
$err_file = $files = array();
$query = DB::query('SELECT * FROM download ORDER BY path ASC');
while($file = DB::fetch($query)){
list($part, $path) = explode('|', $file['path'], 2);
if(!$files[ $path ]){
$file['content'] = pack('H*', $file['content']);
$files[ $path ] = $file;
} else {
$files[ $path ]['content'] .= pack('H*', $file['content']);
}
}
if(!$files) return array('status' => -255);
foreach($files as $path => $file) {
if(!self::_is_writable(ROOT.$path)) $err_file[] = $path;
}
if($err_file) array('status' => -1, 'files' => $err_file);
foreach($files as $path => $file) {
self::_write(ROOT.$path, $file['content']);
if(md5_file(ROOT.$path) != md5($file['content'])) return array('status' => -2, 'file' => $path);
}
DB::query('DELETE FROM download');
saveSetting('new_version', 0);
return array('status' => 0);
}
private static function _write($path, $content){
$fp = @fopen($path, 'wb');
if(!$fp) return false;
fwrite($fp, $content);
fclose($fp);
return true;
}
private static function _is_writable($path){
if(!file_exists($path)){
if(!file_exists(dirname($path))) @mkdir(dirname($path), 0777, true);
@touch($path);
@chmod($path, 0777);
}else{
if(!is_writable($path)) @chmod($path, 0777);
}
return is_writable($path);
}
private static function _download_file($path, $hash, $try = 1) {
$content = kk_fetch_url(self::UPDATE_URL."updata.php?action=getfile&path={$path}");
if (!$content) {
if ($try == 3) {
return -1;
} else {
return self::_download_file($path, $hash, $try + 1);
}
}
if (md5($content) != $hash) {
if ($try == 3) {
return -2;
} else {
return self::_download_file($path, $hash, $try + 1);
}
}
$length = $part = 0;
while($length < strlen($content)){
$part++;
$part_length = strlen($content) - $length > 8192 ? 8192 : strlen($content) - $length;
$_countent = substr($content, $length, $part_length);
$length += $part_length;
$_part = str_pad($part, 4, "0", STR_PAD_LEFT);
DB::insert('download', array('path' => "{$_part}|".$path, 'content' => bin2hex($_countent)));
}
return 0;
}
private static function _getPluginList(){
$pluginList = array();
$list_dir = dir(ROOT.'./plugins/');
while($dirName = $list_dir->read()){
if($dirName == '.' || $dirName == '..' || !is_dir(ROOT."./plugins/{$dirName}")) continue;
$pluginList[] = $dirName;
}
return $pluginList;
}
}
?>
点击后显示更新成功,但文件无改动
程序端完整代码在这里: https://github.com/liujiantaoliu/Tieba_Sign
服务端代码就是上面的
还请各位大神帮忙看下,感激不尽!
联系方式:QQ:3720-753-00
1
Actrace 2015-03-22 10:00:08 +08:00
你确定目录可读写。。。?
|
2
yangff 2015-03-22 10:07:41 +08:00 via Android
你是部署在VPS/独服还是xx云(比如bae、sae)上的?
|
3
liujiantao OP @yangff VPS上,都是在VPS
|
4
liujiantao OP @Actrace 可以的,利用其他思路的可以正常更新:**下载zip,解压**
|
5
Actrace 2015-03-22 10:48:05 +08:00
如果是诊断为无法下载,那么你得根据debug日志来做调整了。
另外我是不建议在文件输出环节做太多操作,直接一个echo file()来输出内容就可以了。 接受端则是file_get_contents. |
6
liujiantao OP @Actrace 我是利用服务端updata.php比对文件MD5值,程序端在进行比对,找出不同的进行下载更新,可就是不知道为什么能正常检测更新就是没法回传回来,我直接通过URL是可以正常下载文件的,不知道是不是程序端代码有什么问题
|
7
haiyang416 2015-03-22 11:06:15 +08:00
代码太乱了,就不看了。
直接在 _download_file 方法里下断言,就知道问题出在哪里了。 |
8
kookxiang 2015-03-22 15:00:28 +08:00 via Android
本来就有差量更新,何必重复造轮子
记得r是读不了php的,就算能读,你程序也有严重漏洞,文件名没过滤直接读到服务器上的任意文件 |
9
liujiantao OP @kookxiang 知道有差量更新,可我们没有服务器端的文件,怎么做呢,漏洞找个时间修复
|
10
branchzero 2015-03-23 05:38:44 +08:00
咦,KK已经出现了233333,代码有点乱。。。还是自己设置断点来追踪吧
|
11
liujiantao OP @branchzero 啊哈
|