撸了个差量更新,但无法正常运行,求指导

2015-03-22 09:37:07 +08:00
 liujiantao

自己做了个差量更新下来,但无法正常使用

问题描述

就是为了给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

3063 次点击
所在节点    PHP
11 条回复
Actrace
2015-03-22 10:00:08 +08:00
你确定目录可读写。。。?
yangff
2015-03-22 10:07:41 +08:00
你是部署在VPS/独服还是xx云(比如bae、sae)上的?
liujiantao
2015-03-22 10:43:04 +08:00
@yangff VPS上,都是在VPS
liujiantao
2015-03-22 10:43:33 +08:00
@Actrace 可以的,利用其他思路的可以正常更新:**下载zip,解压**
Actrace
2015-03-22 10:48:05 +08:00
如果是诊断为无法下载,那么你得根据debug日志来做调整了。
另外我是不建议在文件输出环节做太多操作,直接一个echo file()来输出内容就可以了。
接受端则是file_get_contents.
liujiantao
2015-03-22 10:51:38 +08:00
@Actrace 我是利用服务端updata.php比对文件MD5值,程序端在进行比对,找出不同的进行下载更新,可就是不知道为什么能正常检测更新就是没法回传回来,我直接通过URL是可以正常下载文件的,不知道是不是程序端代码有什么问题
haiyang416
2015-03-22 11:06:15 +08:00
代码太乱了,就不看了。
直接在 _download_file 方法里下断言,就知道问题出在哪里了。
kookxiang
2015-03-22 15:00:28 +08:00
本来就有差量更新,何必重复造轮子

记得r是读不了php的,就算能读,你程序也有严重漏洞,文件名没过滤直接读到服务器上的任意文件
liujiantao
2015-03-22 16:14:34 +08:00
@kookxiang 知道有差量更新,可我们没有服务器端的文件,怎么做呢,漏洞找个时间修复
branchzero
2015-03-23 05:38:44 +08:00
咦,KK已经出现了233333,代码有点乱。。。还是自己设置断点来追踪吧
liujiantao
2015-03-24 13:14:41 +08:00
@branchzero 啊哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/178562

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX