使用mediatemple网格的CURLOPT_FOLLOWLOCATION和open_basedir问题

时间:2014-02-08 22:43:09

标签: php wordpress curl open-basedir

我有一个在mediatemple网格上托管的WordPress网站,我在尝试提交表单时收到有关open_basedir的错误信息。提交时,表单在新手册中创建一个新客户端。安全模式已关闭,所以我非常肯定问题是open_basedir。我收到的错误是:

Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in /nfs/c04/h03/mnt/181950/domains/domain_dir/html/wp-content/plugins/gravityformsfreshbooks/api/HttpClient.php on line 79

查看mediatemple文档,他们建议在php.ini文件中添加一行。他们的例子是:

open_basedir = "/path/to/first/folder:/path/to/second/folder"

我去了我的php.ini文件并添加了:

open_basedir = "/home/domains/domain_dir/html/:/home/181950/data/tmp/"

添加此行后,问题仍未解决。将该行添加到我的php.ini文件后,我的网站没有显示。唯一出现的是这个错误:

Warning: require() [function.require]: open_basedir restriction in effect. File(/nfs/c04/h03/mnt/181950/domains/domain_dir/html/wp-blog-header.php) is not within the allowed path(s): (/home/domains/domain_dir/html/:/home/181950/data/tmp/) in /nfs/c04/h03/mnt/181950/domains/domain_dir/html/index.php on line 17

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。我做了一些手动跟踪重定向的代码。请确保您阅读并理解代码,并在生产中使用之前了解任何安全问题!

function remote_file($f){
    $i = 0;
    do {
        if($i++ > 10) die();
        //Pull the headers and check for redirects
        $cr = curl_init($f);
        curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($cr, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($cr, CURLOPT_BINARYTRANSFER, TRUE);
        curl_setopt($cr, CURLOPT_HEADER, TRUE);
        $curl_ret = curl_exec($cr);
        //echo $curl_ret;
        if(curl_getinfo($cr,CURLINFO_HTTP_CODE)!=200) {
            $matches = preg_match_all('~location: ?(.*)~i',$curl_ret,$output);
            if($matches) {
                $f = $output[1][0];
            }
        } else $matches = 0;
    } while ($matches);

    $cr = curl_init($f);
    curl_setopt($cr, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($cr, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($cr, CURLOPT_BINARYTRANSFER, TRUE);
    //curl_setopt($cr, CURLOPT_FOLLOWLOCATION, TRUE);    //Doesn't work with open_basedir retriction in effect
    $curl_ret = curl_exec($cr);

    curl_close($cr);
    return $curl_ret;
}

编辑:在HttpClient.php中,你应该有一个像

这样的函数
private function _init($url,$token)
    {
            $this->_url = $url;
            $this->_token = $token;
            //init connection
            $this->_curlConn = curl_init($this->_url);
            curl_setopt($this->_curlConn, CURLOPT_HEADER, false);
            curl_setopt($this->_curlConn, CURLOPT_NOBODY, false);
            curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($this->_curlConn, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
            curl_setopt($this->_curlConn, CURLOPT_TIMEOUT, 4);
            curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE); // Validate SSL certificate
            curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");
            return $this;
    }

您需要重写此功能,例如

private function _init($url,$token)
    {
            $this->_url = $url;
            $this->_token = $token;
            //init connection

            $i = 0;
            do {
                if($i++ > 10) die();
                //Pull the headers and check for redirects
                $this->_curlConn = curl_init($this->_url);
                curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, TRUE);
                curl_setopt($this->_curlConn, CURLOPT_BINARYTRANSFER, TRUE);
                curl_setopt($this->_curlConn, CURLOPT_HEADER, TRUE);
                curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
                curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");

                $curl_ret = curl_exec($cr);
                //echo $curl_ret;
                if(curl_getinfo($cr,CURLINFO_HTTP_CODE)!=200) {
                    $matches = preg_match_all('~location: ?(.*)~i',$curl_ret,$output);
                    if($matches) {
                        $this->_url = $output[1][0];
                    }
                } else $matches = 0;
            } while ($matches);

            $this->_curlConn = curl_init($this->_url);
            curl_setopt($this->_curlConn, CURLOPT_HEADER, false);
            curl_setopt($this->_curlConn, CURLOPT_NOBODY, false);
            curl_setopt($this->_curlConn, CURLOPT_RETURNTRANSFER, true);
            //curl_setopt($this->_curlConn, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($this->_curlConn, CURLOPT_USERPWD, $this->_token);
            curl_setopt($this->_curlConn, CURLOPT_TIMEOUT, 4);
            curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYPEER, FALSE); // Validate SSL certificate
            curl_setopt($this->_curlConn, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($this->_curlConn, CURLOPT_USERAGENT, "FreshBooks API AJAX tester 1.0");
            return $this;
    }

这将有效地继续将请求发送到他们的API,直到它返回不是重定向的内容。如果它很高兴它只会将重定向后的URL传递给标准代码,标准代码会将其提取并继续运行。

哦,在我努力之前我会尝试的另一件事......如果你只是在HttpClient.php中注释掉有问题的行怎么办?它确实需要遵循任何重定向吗?