سؤال

I have a WordPress site hosted on the mediatemple grid and I am receiving and error regarding open_basedir when trying to submit a form. On submission, the form creates a new client in freshbooks. Safe mode is turned off so I am quite positive the problem is with open_basedir. The error I receive is:

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

Looking at the mediatemple documentation, they suggest adding a line to the php.ini file. Their example is:

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

I went to my php.ini file and added:

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

After adding this line, the problem is not solved. After adding that line to my php.ini file, my site is not displaying. The only thing that shows up is this error:

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
هل كانت مفيدة؟

المحلول

I hit the same issue. I made a bit of code that'll manually follow redirects. Please make sure you read and understand the code, and are aware of any security issues before you use it in production!

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;
}

Edit: In the HttpClient.php, you should have a function like

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;
    }

You'll need to rewrite this function, something like

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;
    }

This will effectively keep sending the request to their API until it returns something that isn't a redirect. When it's happy it'll just pass that post-redirect URL onto the standard code, which will pick it up and continue on its way.

Oh, the other thing I'd try before going to this effort... What if you just comment out the offending line in HttpClient.php? Does it actually need to follow any redirects?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top