How to get file_get_contents() to work with HTTPS?
Asked Answered
I

11

118

I'm working on setting up credit card processing and needed to use a workaround for CURL. The following code worked fine when I was using the test server (which wasn't calling an SSL URL), but now when I am testing it on the working server with HTTPS, it's failing with the error message "failed to open stream".

function send($packet, $url) {
  $ctx = stream_context_create(
    array(
      'http'=>array(
        'header'=>"Content-type: application/x-www-form-urlencoded",
        'method'=>'POST',
        'content'=>$packet
      )
    )
  );
  return file_get_contents($url, 0, $ctx);
}
Irs answered 29/12, 2009 at 16:23 Comment(0)
J
96

Try the following script to see if there is an https wrapper available for your php scripts.

$w = stream_get_wrappers();
echo 'openssl: ',  extension_loaded  ('openssl') ? 'yes':'no', "\n";
echo 'http wrapper: ', in_array('http', $w) ? 'yes':'no', "\n";
echo 'https wrapper: ', in_array('https', $w) ? 'yes':'no', "\n";
echo 'wrappers: ', var_export($w);

the output should be something like

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
Janiculum answered 29/12, 2009 at 17:58 Comment(5)
@volker That's why I asked for allow_url_fopenBenjaminbenji
Well what is odd is that it says openssl is off, but according to phpinfo() it is compiled with it, unless I am seeing it wrong.Irs
phpinfo() tells you so in the configure-line or is there a whole section called "OpenSSL"?Janiculum
Okay it is just in the configure-line, not a section for it. I guess that is the problem?Irs
I have all that and it still doesn't work. And allow_url_fopen. Only non https urls work from localhost.Shipment
S
120

To allow https wrapper:

  • the php_openssl extension must exist and be enabled
  • allow_url_fopen must be set to on

In the php.ini file you should add this lines if not exists:

extension=php_openssl.dll

allow_url_fopen = On
Slighting answered 21/9, 2011 at 12:11 Comment(1)
Both are set to On in my installation but I still get the SSL error "Warning: file_get_contents(): SSL: Handshake timed out in"Weinberger
J
96

Try the following script to see if there is an https wrapper available for your php scripts.

$w = stream_get_wrappers();
echo 'openssl: ',  extension_loaded  ('openssl') ? 'yes':'no', "\n";
echo 'http wrapper: ', in_array('http', $w) ? 'yes':'no', "\n";
echo 'https wrapper: ', in_array('https', $w) ? 'yes':'no', "\n";
echo 'wrappers: ', var_export($w);

the output should be something like

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
Janiculum answered 29/12, 2009 at 17:58 Comment(5)
@volker That's why I asked for allow_url_fopenBenjaminbenji
Well what is odd is that it says openssl is off, but according to phpinfo() it is compiled with it, unless I am seeing it wrong.Irs
phpinfo() tells you so in the configure-line or is there a whole section called "OpenSSL"?Janiculum
Okay it is just in the configure-line, not a section for it. I guess that is the problem?Irs
I have all that and it still doesn't work. And allow_url_fopen. Only non https urls work from localhost.Shipment
I
68

If you want to be vulnerable to a man-in-the middle attack, try this code:

$url= 'https://example.com';

$arrContextOptions=array(
      "ssl"=>array(
            "verify_peer"=>false,
            "verify_peer_name"=>false,
        ),
    );  

$response = file_get_contents($url, false, stream_context_create($arrContextOptions));

This will allow you to get the content from the url no matter what certificate it presents

Intertexture answered 2/8, 2016 at 12:25 Comment(6)
Thanks! This worked on my end. Been trying to call FB Open Graph API :)Lagena
I was trying to access a domain of mine with invalid certificate just for test purposes and even though this disables SSL validation, it was what I needed.Delaunay
Great! I have been trying for 5 days to download an airbnb calendar on my XAMPP test site using file_get_contents, this solved the problem, thanks.Neonate
Worked for me trying to connect to Vagrant test box without a valid HTTP certificate over https. Link to PHP SSL Context options being set here: php.net/manual/en/context.ssl.php ; verify peer = Require verification of SSL certificate used; verify_peer_name=Require verification of peer name.Ex
isn't this breaking SSL certification and is a security hole?Mitzvah
This is a bad Solution, youre basically disabling the SSL certification verification which allows for MITM attacks. read more MITMCommunitarian
D
58

Try the following.

function getSslPage($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

Note: This disables SSL verification, meaning the security offered by HTTPS is lost. Only use this code for testing / local development, never on the internet or other public-facing networks. If this code works, it means the SSL certificate isn't trusted or can't be verified, which you should look into fixing as a separate issue.

Discontent answered 16/9, 2012 at 12:34 Comment(2)
Why would you disable ssl verification when dealing with credit card processing?Marniemaro
Thank you, the trick is in here: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);Greggrega
V
6

Just add two lines in your php.ini file.

extension=php_openssl.dll

allow_url_include = On

its working for me.

Venetic answered 9/3, 2013 at 22:12 Comment(1)
You probably mean allow_url_fopen since question concerns url opening, not including.Berley
B
5

HTTPS is supported starting from PHP 4.3.0, if you have compiled in support for OpenSSL. Also, make sure the target server has a valid certificate, the firewall allows outbound connections and allow_url_fopen in php.ini is set to true.

Benjaminbenji answered 29/12, 2009 at 16:26 Comment(6)
I have PHP 5.2.8 with OpenSSL support. I am getting the same error with this, and the target server has a valid certificate.Irs
is the firewall configured to allow outbound https connections? Usually, webserver running https do not run on port 80. is there anything else in the error apart from 'failed to open stream'?Benjaminbenji
As far as I know it does, this is the entire error: Warning: fopen(https://...) [function.fopen]: failed to open stream: No such file or directory in /home/user/public_html/test.php on line 993Irs
and allow_url_fopen in php.ini is set to what?Benjaminbenji
That's odd. Can you do a GET on an HTTP and an HTTPS url to see if that works? without the stream context?Benjaminbenji
GET gives the same error as POST (going to the URL in the browser works fine).Irs
R
5

I had the same error. Setting allow_url_include = On in php.ini fixed it for me.

Rural answered 28/1, 2011 at 23:25 Comment(0)
S
4

use the following code:

$homepage = file_get_contents("https://www.google.com",false,
                             stream_context_create([
                                'ssl'  => [
                                    'verify_peer'      => false,
                                    'verify_peer_name' => false,
                                ]
                            ])
            );
    
 echo $homepage;
Stefanstefanac answered 5/1, 2021 at 7:26 Comment(2)
simple, flexible and it works!Decathlon
It works for that URL from Google, but unfortunately it doesn't for mine (from the same page where the code is executed).Philippians
S
3

In my case, the issue was due to WAMP using a different php.ini for CLI than Apache, so your settings made through the WAMP menu don't apply to CLI. Just modify the CLI php.ini and it works.

Sarco answered 3/1, 2013 at 16:22 Comment(0)
E
1

Sometimes a server will choose not to respond based on what it sees or doesn't see in the http request headers (such as an appropriate user agent). If you can connect with a browser, grab the headers it sends and mimic them in your stream context.

Epicurean answered 29/12, 2009 at 18:27 Comment(0)
C
0

I was stuck with non functional https on IIS. Solved with:

file_get_contents('https.. ) wouldn't load.

  • download https://curl.haxx.se/docs/caextract.html
  • install under ..phpN.N/extras/ssl
  • edit php.ini with:

    curl.cainfo = "C:\Program Files\PHP\v7.3\extras\ssl\cacert.pem" openssl.cafile="C:\Program Files\PHP\v7.3\extras\ssl\cacert.pem"

finally!

Chlamydeous answered 25/11, 2019 at 17:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.