views:

1460

answers:

4

I'm working on setting up credit card processing and needed to use a workaround for CURL, and 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 doesn't work ("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);
}
+5  A: 

This is probably due to your target server not having a valid SSL certificate.

Emil Vikström
The requesting server need not have an SSL certificate.
ceejayoz
I didn't say the requesting server, I said the target server.
Emil Vikström
That'll teach me to skim. Heh! Please accept my apologies and upvote.
ceejayoz
The target server does have a valid SSL cert.
James Simpson
@ceejayoz, no hard feelings :-) I know it can get tricky when PHP is usually run on "a server". But it is actually a client in this context.
Emil Vikström
@James, do you get an error if you try connecting with cURL instead? Or is that absolutely impossible to try?
Emil Vikström
btw to get this kind of error you must explicitly tell the ssl wrapper to verify the other side's certificate by setting the `verify_peer` and `cafile/capath` context option. And the warning message would tell you that the certificate is an issue.
VolkerK
curl isn't compiled with PHP on the server.
James Simpson
+1  A: 

Taken from the comments in the PHP manual for stream_context_create

edit: removed code as it was not helpful

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.

Gordon
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.
James Simpson
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'?
Gordon
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 993
James Simpson
and allow_url_fopen in php.ini is set to what?
Gordon
Yes, allow_url_fopen is on.
James Simpson
That's odd. Can you do a GET on an HTTP and an HTTPS url to see if that works? without the stream context?
Gordon
GET gives the same error as POST (going to the URL in the browser works fine).
James Simpson
+2  A: 

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_dump($w);

the output should be something like

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}
VolkerK
thats a good idea
Gordon
That says there is no https wrapper.
James Simpson
But unfortunately it doesn't fit the error message `failed to open stream: No such file or directory`. A missing wrapper would raise `failed to open stream: Invalid argument` and `Unable to find the wrapper "https" - did you forget to enable it when you configured PHP?` Did it say `openssl: yes` or `openssl: no` ?
VolkerK
@volker That's why I asked for allow_url_fopen
Gordon
allow_url_fopen=Off would raise yet another message ;-) `Warning: file_get_contents(): http:// wrapper is disabled in the server configuration by allow_url_fopen=0` and `failed to open stream: no suitable wrapper could be found`
VolkerK
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.
James Simpson
phpinfo() tells you so in the configure-line or is there a whole section called "OpenSSL"?
VolkerK
Okay it is just in the configure-line, not a section for it. I guess that is the problem?
James Simpson
Yep, if it says something like --with-openssl=shared then the openssl extension has been built along with the core but it's still a module you have to load (at startup- or runtime). If you "find" that module (or compile/link it) you can simply add an `extension=nameofthemodule` line to your php.ini and the next time php starts it will load the module. If you try it on a test server first, it should only take seconds to restart the production server with the ssl extension. That was your main concern, wasn't it?
VolkerK
A: 

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.

GZipp