HDwiki+discuz在启用https下的整合问题

简介:

这几天在折腾HDwiki+discuz,系统环境是FreeBSD 10.4, PHP 5.6(HDwiki要求),PHP-PDO_MYSQL,PHP-GD,PHP-XML等,MYSQL 5.7

HDwiki 5.1(6.0安装成功后打开前台,提示http 500错误,找不到原因)
discuz X3.4

因为宽带运营商关闭了80端口,443端口有开,所以就直接用上https,结果问题一大堆。

首先,discuz和ucenter在https下通信失败,后来找到修改方法:

DISCUZ 开启https后ucenter通信失败解决方法,一般是做完301重定向https后通信失败的,下面是具体解决方法:

打开目录 uc_server/model/misc.php 文件;找到69行,插入下面代码:

......
$port = !empty($matches['port']) ? $matches['port'] : ($matches['scheme'] == 'https' ? 443 : 80);

//以下为插入代码
if(substr($url,0,5)=='https'){
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if($post){
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if($cookie){
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
return curl_exec($ch);
}
//插入代码结束

if($post) {
            $out = "POST $path HTTP/1.0\r\n";
......

接下来设置HDwiki和ucenter,问题比较多了。
一开始,只要设置https,就提示“您输入的URL地址不正确!”
网上也没有任何资料,经过调试,发现要修改HDwiki目录下的control/admin_setting.php的659行

原来长这样:

if(empty($ucapi) || !preg_match("/^(http:\/\/)/i", $ucapi)) {


修改成这样:

if(empty($ucapi) || !preg_match("/^((http:|https:)\/\/)/i", $ucapi)) {

这个问题解决后,出现的是“uc_url_unreachable”错误。走了不少弯路后,发现还是https的问题。
admin_setting.php调用了api/uc_client/client.php里的uc_fopen(),而这个函数使用fsockopen模拟浏览器进行访问。
并且只有拼接了http协议的情况。对这个接口文件的分析,见这篇文章http://blog.csdn.net/yanhui_wei/article/details/17919645

综合这些分析,比较一下discuz的uc_server/model/misc.php和HDwiki下的api/uc_client/client.php,会发现:

discuz的uc_server/model/misc.php里的function dfopen2()和 function dfopen()与HDwiki下的api/uc_client/client.php的uc_fopen2()和uc_fopen()基本上是类似的。

所以解决方法如下:
1、拷贝discuz下的uc_client目录,替换HDwiki下的api/uc_client目录
2、修改api/uc_client/client.php文件,重点在于用function dfopen2()和 function dfopen()的内容替换uc_fopen2()和uc_fopen(),修改完成的结果如下:

function uc_fopen2($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE') {
        $__times__ = isset($_GET['__times__']) ? intval($_GET['__times__']) + 1 : 1;
        if($__times__ > 2) {
            return '';
        }
        $url .= (strpos($url, '?') === FALSE ? '?' : '&')."__times__=$__times__";
        return uc_fopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype);
    }

function uc_fopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE    , $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE') {
        $return = '';
        $matches = parse_url($url);
        $scheme = $matches['scheme'];
        $host = $matches['host'];
        $path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
        $port = !empty($matches['port']) ? $matches['port'] : ($matches['scheme'] == 'https' ? 443 : 80);
        /*
        //以下内容可以不需要
        if($scheme=='https'){
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            if($post) {
                curl_setopt($curl, CURLOPT_POST, 1);
                curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
            }
            if($cookie) {
                curl_setopt($curl, CURLOPT_COOKIE, $cookie);
            }
            curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $return = curl_exec($curl);
            if (curl_errno($curl)) {
                echo '<pre><b>错误:</b><br />'.curl_error($curl); 
            }
            curl_close($curl);
            return $return;
        }

        // 结束
        */
 
        if($post) {
            $out = "POST $path HTTP/1.0\r\n";
            $header = "Accept: */*\r\n";
            $header .= "Accept-Language: zh-cn\r\n";
            $boundary = $encodetype == 'URLENCODE' ? '' : ';'.substr($post, 0, trim(strpos($post, "\n")));
            $header .= $encodetype == 'URLENCODE' ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data$boundary\r\n";
            $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
            $header .= "Host: $host:$port\r\n";
            $header .= 'Content-Length: '.strlen($post)."\r\n";
            $header .= "Connection: Close\r\n";
            $header .= "Cache-Control: no-cache\r\n";
            $header .= "Cookie: $cookie\r\n\r\n";
            $out .= $header.$post;
        } else {
            $out = "GET $path HTTP/1.0\r\n";
            $header = "Accept: */*\r\n";
            $header .= "Accept-Language: zh-cn\r\n";
            $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
            $header .= "Host: $host:$port\r\n";
            $header .= "Connection: Close\r\n";
            $header .= "Cookie: $cookie\r\n\r\n";
            $out .= $header;
        }

        $fpflag = 0;
        if(!$fp = @fsocketopen(($scheme == 'https' ? 'ssl' : $scheme).'://'.($scheme == 'https' ? $host : ($ip ? $ip : $host)), $port, $errno, $errstr, $timeout)) {
            $context = array(
                'http' => array(
                    'method' => $post ? 'POST' : 'GET',
                    'header' => $header,
                    'content' => $post,
                    'timeout' => $timeout,
                ),
            );
            $context = stream_context_create($context);
            $fp = @fopen($scheme.'://'.($scheme == 'https' ? $host : ($ip ? $ip : $host)).':'.$port.$path, 'b', false, $context);
            $fpflag = 1;
        }

        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) && !$fpflag) {
                    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;
        }
    }
....
//找到同步登录登出代码,修改成以下内容
/**
 * 进入同步登录代码
 *
 * @param int $uid        用户ID
 * @return string         HTML代码
 */
function uc_user_synlogin($uid) {
    $uid = intval($uid);
    $return = uc_api_post('user', 'synlogin', array('uid'=>$uid));
    return $return;
}

/**
 * 进入同步登出代码
 *
 * @return string         HTML代码
 */
function uc_user_synlogout() {
    $return = uc_api_post('user', 'synlogout', array());
    return $return;
}
....


然后就可以看到一切都正常了。
另外需要注意的是,必须保证ssl证书在有效期内,因为这个,浪费了2天的时间。

目录
相关文章
|
关系型数据库 MySQL PHP
|
2月前
|
前端开发
webpack如何设置devServer启动项目为https协议
webpack如何设置devServer启动项目为https协议
181 0
|
4月前
|
Web App开发 移动开发 JavaScript
Python网络编程(三),HTTP协议
Python网络编程(三),HTTP协议
65 0
|
5月前
|
网络协议
【计算机网络-应用层】HTTP协议
【计算机网络-应用层】HTTP协议
|
5天前
|
存储 算法 安全
[计算机网络]---Https协议
[计算机网络]---Https协议
|
12天前
|
安全 网络协议 算法
【计算机网络】http协议的原理与应用,https是如何保证安全传输的
【计算机网络】http协议的原理与应用,https是如何保证安全传输的
|
12天前
|
网络协议 安全 算法
HTTP协议与HTTPS协议
HTTP协议与HTTPS协议
|
13天前
|
网络协议 安全
【专栏】`curl`是广泛用于网络编程和自动化脚本的命令行工具,支持HTTP、HTTPS等协议
【4月更文挑战第28天】`curl`是广泛用于网络编程和自动化脚本的命令行工具,支持HTTP、HTTPS等协议。在处理大文件或慢速服务器时,设置超时参数至关重要。本文介绍了`curl`的超时参数,如`-m`(最大操作时间)、`-c`(连接超时)、`--dns-timeout`(DNS解析超时)和`-t`(时间条件)。通过示例展示了如何设置这些超时,并提到了一些高级技巧和注意事项,如错误处理和带宽限制。合理设置超时能提高效率和可靠性,对编写健壮的自动化脚本非常有用。
|
22天前
|
安全 网络安全 数据安全/隐私保护
HTTPS协议
HTTPS协议
22 0
|
1月前
|
安全 网络安全 数据安全/隐私保护
HTTPS协议详解
HTTPS协议详解
16 1