PHP CURL & HTTPS

PhpCurlHttps

Php Problem Overview


I found this function that does an AWESOME job (IMHO): http://nadeausoftware.com/articles/2007/06/php_tip_how_get_web_page_using_curl

/**
 * Get a web file (HTML, XHTML, XML, image, etc.) from a URL.  Return an
 * array containing the HTTP server response header fields and content.
 */
function get_web_page( $url )
{
    $options = array(
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_USERAGENT      => "spider", // who am i
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
    );

    $ch      = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    curl_close( $ch );

    $header['errno']   = $err;
    $header['errmsg']  = $errmsg;
    $header['content'] = $content;
    return $header;
}

The only problem I have is that it doesn't work for https://. Anny ideas what I need to do to make this work for https? Thanks!

Php Solutions


Solution 1 - Php

Quick fix, add this in your options:

curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false)

Now you have no idea what host you're actually connecting to, because cURL will not verify the certificate in any way. Hope you enjoy man-in-the-middle attacks!

Or just add it to your current function:

/**
 * Get a web file (HTML, XHTML, XML, image, etc.) from a URL.  Return an
 * array containing the HTTP server response header fields and content.
 */
function get_web_page( $url )
{
    $options = array(
        CURLOPT_RETURNTRANSFER => true,     // return web page
        CURLOPT_HEADER         => false,    // don't return headers
        CURLOPT_FOLLOWLOCATION => true,     // follow redirects
        CURLOPT_ENCODING       => "",       // handle all encodings
        CURLOPT_USERAGENT      => "spider", // who am i
        CURLOPT_AUTOREFERER    => true,     // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120,      // timeout on connect
        CURLOPT_TIMEOUT        => 120,      // timeout on response
        CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
        CURLOPT_SSL_VERIFYPEER => false     // Disabled SSL Cert checks
    );

    $ch      = curl_init( $url );
    curl_setopt_array( $ch, $options );
    $content = curl_exec( $ch );
    $err     = curl_errno( $ch );
    $errmsg  = curl_error( $ch );
    $header  = curl_getinfo( $ch );
    curl_close( $ch );

    $header['errno']   = $err;
    $header['errmsg']  = $errmsg;
    $header['content'] = $content;
    return $header;
}

Solution 2 - Php

I was trying to use CURL to do some https API calls with php and ran into this problem. I noticed a recommendation on the php site which got me up and running: http://php.net/manual/en/function.curl-setopt.php#110457

> Please everyone, stop setting CURLOPT_SSL_VERIFYPEER to false or 0. If > your PHP installation doesn't have an up-to-date CA root certificate > bundle, download the one at the curl website and save it on your > server: > > http://curl.haxx.se/docs/caextract.html > > Then set a path to it in your php.ini file, e.g. on Windows: > > curl.cainfo=c:\php\cacert.pem > > Turning off CURLOPT_SSL_VERIFYPEER allows man in the middle (MITM) > attacks, which you don't want!

Solution 3 - Php

Another option like Gavin Palmer answer is to use the .pem file but with a curl option

  1. download the last updated .pem file from https://curl.haxx.se/docs/caextract.html and save it somewhere on your server(outside the public folder)

  2. set the option in your code instead of the php.ini file.

In your code

curl_setopt($ch, CURLOPT_CAINFO, $_SERVER['DOCUMENT_ROOT'] .  "/../cacert-2017-09-20.pem");

NOTE: setting the cainfo in the php.ini like @Gavin Palmer did is better than setting it in your code like I did, because it will save a disk IO every time the function is called, I just make it like this in case you want to test the cainfo file on the fly instead of changing the php.ini while testing your function.

Solution 4 - Php

One important note, the solution mentioned above will not work on local host, you have to upload your code to server and then it will work. I was getting no error, than bad request, the problem was I was using localhost (test.dev,myproject.git). Both solution above work, the solution that uses SSL cert is recommended.

  1. Go to https://curl.haxx.se/docs/caextract.html, download the latest cacert.pem. Store is somewhere (not in public folder - but will work regardless)

  2. Use this code

> > $user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) > AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 > Safari/537.36"; $ch = curl_init(); curl_setopt($ch, > CURLOPT_POST,1); > > curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, > CURLOPT_USERAGENT, $user_agent); curl_setopt($ch, > CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, > true); curl_setopt($ch, CURLOPT_CAINFO, $_SERVER['DOCUMENT_ROOT'] . > "/ssl/cacert.pem"); > > $result=curl_exec ($ch); curl_close ($ch); > > echo "Results:
".$result; > > //echo "
Path:".$_SERVER['DOCUMENT_ROOT'] . "/ssl/cacert.pem"; > // this is for troubleshooting only ?>

  1. Upload the code to live server and test.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStackOverflowNewbieView Question on Stackoverflow
Solution 1 - PhpSystemX17View Answer on Stackoverflow
Solution 2 - PhpGavin PalmerView Answer on Stackoverflow
Solution 3 - PhpAccountant مView Answer on Stackoverflow
Solution 4 - PhpHammad KhanView Answer on Stackoverflow