15

So I keep getting this annoying error on multiple servers(its a warning, so I'd ignore it, but I need the function)

Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in /home/xxx/public_html/xxx.php on line 56

How would I go about fixing this via SSH?

hakre
  • 193,403
  • 52
  • 435
  • 836
Saulius Antanavicius
  • 1,371
  • 6
  • 25
  • 55
  • What's your setup (safe mode and/or open basedir enabled?) and what are you trying to achieve? – aefxx Aug 02 '11 at 21:10

5 Answers5

14

Set safe_mode = Off in your php.ini file (it's usually in /etc/ on the server). If that's already off, then look around for the open_basedir stuff in the php.ini file, and change it accordingly.

Basically, the follow location option has been disabled as a security measure, but PHP's built-in security features are usually more annoying than secure. In fact, safe_mode is deprecated in PHP 5.3.

Flambino
  • 18,507
  • 2
  • 39
  • 58
  • 2
    @Flambine: Depricated means it still exists and works as expected, but that it is highly discouraged. It can and often is enabled on older shared hosting platforms. I concur that safe_mode is annoying at best. – Wrikken Aug 02 '11 at 21:30
  • @Wrikken: You're right, sorry. But safe_mode will be completely gone in PHP 6, I believe. Not that that's any help now. Still, I got the two mixed up. – Flambino Aug 02 '11 at 21:45
  • 2
    btw: according to http://www.php.net/releases/NEWS_5_4_0_alpha1.txt safe_mode is removed in PHP 5.4 – Floern Aug 02 '11 at 21:59
  • If you are on a shared server this is not an option to be able to modify the php.ini, is there any other solutions? – Joseph Astrahan Mar 27 '14 at 05:02
  • @JosephAstrahan For one, I'd say get a better hosting provider. But [another answer to this question](http://stackoverflow.com/a/6918742/167996) has a possible workaround. No idea if it'll work, though – Flambino Mar 27 '14 at 20:48
12

Try this, If a redirect is required and safemode is enabled it will follow the link based on the header (If your grabbing images though this will not work as it adds the header to the return), this is a workaround to your specific problem, I had the same problem when a customer installed one of my script so had to come up with this.. It will also log errors to: curl.error.log.. useful eh

<?php 
function geturl($url) {
    (function_exists('curl_init')) ? '' : die('cURL Must be installed for geturl function to work. Ask your host to enable it or uncomment extension=php_curl.dll in php.ini');

    $curl = curl_init();
    $header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,";
    $header[0] .= "text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
    $header[] = "Cache-Control: max-age=0";
    $header[] = "Connection: keep-alive";
    $header[] = "Keep-Alive: 300";
    $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
    $header[] = "Accept-Language: en-us,en;q=0.5";
    $header[] = "Pragma: ";

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 Firefox/5.0');
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_HEADER, true);
    curl_setopt($curl, CURLOPT_REFERER, $url);
    curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
    curl_setopt($curl, CURLOPT_AUTOREFERER, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //CURLOPT_FOLLOWLOCATION Disabled...
    curl_setopt($curl, CURLOPT_TIMEOUT, 60);

    $html = curl_exec($curl);

    $status = curl_getinfo($curl);
    curl_close($curl);

    if ($status['http_code'] != 200) {
        if ($status['http_code'] == 301 || $status['http_code'] == 302) {
            list($header) = explode("\r\n\r\n", $html, 2);
            $matches = array();
            preg_match("/(Location:|URI:)[^(\n)]*/", $header, $matches);
            $url = trim(str_replace($matches[1],"",$matches[0]));
            $url_parsed = parse_url($url);
            return isset($url_parsed) ? geturl($url) : '';
        }

        $oline='';
        foreach ($status as $key => $eline) {
            $oline .= '['.$key.']'.$eline.' ';
        }
        $line = $oline." \r\n ".$url."\r\n-----------------\r\n";

        $handle = @fopen('./curl.error.log', 'a');
        fwrite($handle, $line);
        return false;
    }
    return $html;
}
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
  • You "might" wan't to add a check that the new url isn't a file:// url. Which could expose the contents of "file:///myproject/database.php" etc. Which is disallowed by cURL by default since 7.19.4 (see CURLOPT_REDIR_PROTOCOLS). Lower version of curl didn't have that restriction, that's why CURLOPT_FOLLOWLOCATION isn't allowed in safe mode. – Bob Fanger Oct 15 '12 at 22:22
  • Undefined variable: referer –  Nov 12 '13 at 11:05
  • Nice, I was googling exactly for such a workaround! – Antony Harder Jan 12 '14 at 03:30
  • Thank you so much for this. I was trying to use http://benalman.com/projects/php-simple-proxy/ and `//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //CURLOPT_FOLLOWLOCATION Disabled...` was the way to go on the server. – beam022 Oct 04 '14 at 03:36
2

About safe mode and open_basedir option:

http://www.php.net/manual/en/features.safe-mode.php

http://www.php.net/manual/en/ini.core.php#ini.open-basedir

Timur
  • 6,668
  • 1
  • 28
  • 37
2

To solve this problem, simply put safe_mode = Off and clear open_base_dir at php.ini file.

  • 3
    This is not an option if you are on a shared server where you have no access to the php.ini. – Paul Jan 27 '15 at 19:06
1

Simply, as long as either open_basedir or safe_mode is enabled in the php.ini file, the CURLOPT_FOLLOWLOCATION configuration cannot be used. To change those settings, I can only give general notes:

  1. SSH to the server
  2. cd to the directory (usually /etc/php5 on linux, depends on your distribution or OS) that contains php.ini
  3. sudo to edit (eg, sudo nano php.ini).
  4. edit the lines that specify open_basedir or safe_mode and either turn them off.

Remember to restart your httpd afterwards!

Sajid
  • 4,381
  • 20
  • 14