discuzX3* 开启 https 后 UCenter应用通信失败解决

今天遇到一个问题,discuzX3* 升级成https 的时候发现UCenter 一直通信失败,查找了一下目前大家的解决方案基本都是通用的方法 、

打开Discuz论坛目录下的uc_server/model/misc.php 文件,找到 (大约69行左右),插入下面代码。

       if(substr($url,0,5)=='https'){
            //var_dump($url);
            $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_VERIFYHOST, FALSE);
            return curl_exec($ch);
        }

此方法我用了以后并不生效,仔细查看代码后发现,问题出在最后curl 与 https 的上面。当请求https的数据时,会要求证书,这时候,加上下面这两个参数,规避ssl的证书检查,

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // https请求 不验证hosts

发现上述代码缺少了不验证host 。添加上以后果断好使。。

完整代码

<?php

/*
	[UCenter] (C)2001-2099 Comsenz Inc.
	This is NOT a freeware, use is subject to license terms

	$Id: misc.php 1127 2011-12-14 04:24:58Z svn_project_zhangjie $
*/

!defined('IN_UC') && exit('Access Denied');

define('UC_ARRAY_SEP_1', 'UC_ARRAY_SEP_1');
define('UC_ARRAY_SEP_2', 'UC_ARRAY_SEP_2');

class miscmodel
{

    var $db;
    var $base;

    function __construct(&$base)
    {
        $this->miscmodel($base);
    }

    function miscmodel(&$base)
    {
        $this->base = $base;
        $this->db = $base->db;
    }

    function get_host_by_url($url)
    {
        $m = parse_url($url);
        if (!$m['host']) {
            return -1;
        }
        if (!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $m['host'])) {
            $ip = @gethostbyname($m['host']);
            if (!$ip || $ip == $m['host']) {
                return -2;
            }
            return $ip;
        } else {
            return $m['host'];
        }
    }

    function check_url($url)
    {
        return preg_match("/(https?){1}:\/\/|www\.([^\[\"']+?)?/i", $url);
    }

    function check_ip($url)
    {
        return preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $url);
    }

    function dfopen2($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 $this->dfopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype);
    }

    function dfopen($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);
//本段解决,UC通信失败,https
        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_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            return curl_exec($ch);
        }
        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;
        }
    }

    function array2string($arr)
    {
        $s = $sep = '';
        if ($arr && is_array($arr)) {
            foreach ($arr as $k => $v) {
                $s .= $sep . addslashes($k) . UC_ARRAY_SEP_1 . $v;
                $sep = UC_ARRAY_SEP_2;
            }
        }
        return $s;
    }

    function string2array($s)
    {
        $arr = explode(UC_ARRAY_SEP_2, $s);
        $arr2 = array();
        foreach ($arr as $k => $v) {
            list($key, $val) = explode(UC_ARRAY_SEP_1, $v);
            $arr2[$key] = $val;
        }
        return $arr2;
    }
}

?>

证明了如果论坛是域名的情况下,https curl 通信要规避一下host 否则无法验证通过,IP的情况没有实验,应该没有此问题。

猜你喜欢

转载自my.oschina.net/u/3338945/blog/1797776
今日推荐