25

I am hesitated to ask this question because it looks weird. But anyway. Just in case someone had encountered the same problem already... filesystem functions (fopem, file, file_get_contents) behave very strange for http:// wrapper

  • it seemingly works. no errors raised. fopen() returns resource.
  • it returns no data for all certainly working urls (e.g. http://google.com/).
    file returns empty array, file_get_contents() returns empty string, fread returns false
  • for all intentionally wrong urls (e.g. http://goog973jd23le.com/) it behaves exactly the same, save for little [supposedly domain lookup] timeout, after which I get no error (while should!) but empty string.
  • url_fopen_wrapper is turned on
  • curl (both command line and php versions) works fine, all other utilities and applications works fine, local files opened fine

This error seems inapplicable because in my case it doesn't work for every url or host.

php-fpm 5.2.11 Linux version 2.6.35.6-48.fc14.i686 (mockbuild@x86-18.phx2.fedoraproject.org)

NikiC
  • 100,734
  • 37
  • 191
  • 225
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • Is there any reason why you don't want to use libcurl? Seems if that is working it could be an ideal replacement for you. – Treffynnon Nov 13 '10 at 14:11
  • 2
    @Treffynnon I am rewriting the code to curl usage right now, but still want to know whats wrong with file_get_contents() – Your Common Sense Nov 13 '10 at 14:19
  • For which specific URL does it not work? – mario Nov 13 '10 at 14:21
  • @Col. Shrapnel Yeah it is a curious one and I have never encountered it before. I look forward to seeing what is happening when you find out too. – Treffynnon Nov 13 '10 at 14:22
  • random guess: http://fedoraforum.org/forum/showthread.php?t=108874 – Gordon Nov 13 '10 at 14:23
  • Can you show output of a `var_dump` of `$http_response_headers` after the `file_get_contents` call? – netcoder Nov 13 '10 at 14:34
  • @battal I thought so, but it lets curl through – Your Common Sense Nov 13 '10 at 14:42
  • Is there something in `$http_response_header`or in httpd error logs? – Halil Özgür Nov 13 '10 at 15:14
  • @battal $http_response_header is NULL and there is no PHP errors for sure. I can get every other error, but file_get_contents() raises nothing. – Your Common Sense Nov 13 '10 at 15:33
  • Then the only thing I can think of is that it's something about request headers. Make requests to another server using both CURL and file_get_contents, and compare the request headers that both generate. Other than that, you can try to update/upgrade your PHP, if this is possible. – Halil Özgür Nov 13 '10 at 15:40
  • Can you use a network sniffer to verify that anything actually happens on `fopen('http://...')`? – nikc.org Nov 16 '10 at 06:23
  • 1
    I guess its because `http://google.com/` redirects to `http://www.google.com` Did you try any other URLs? – vinothkr Nov 22 '10 at 06:04
  • The error has something to do with Fedora 14, since I'm encountering this since I updated. file_get_contents works fine if you do a barebones PHP ./configure, so I'm working on figuring out which option causes it to try and track down which package the breaker. – Eric Caron Dec 09 '10 at 01:48

8 Answers8

23

I fixed this issue on my server (running PHP 5.3.3 on Fedora 14) by removing the --with-curlwrapper from the PHP configuration and rebuilding it.

Eric Caron
  • 6,181
  • 1
  • 24
  • 26
  • 1
    Tripped up by this again today, this time having default_socket_timeout set to 0 (which should mean limitless) was causing it to fail immediately. – Eric Caron Jul 09 '12 at 17:31
19

Sounds like a bug. But just for posterity, here are a few things you might want to debug.

  • allow_url_fopen: already tested
  • PHP under Apache might behave differently than PHP-CLI, and would hint at chroot/selinux/fastcgi/etc. security restrictions
  • local firewall: unlikely since curl works
  • user-agent blocking: this is quite common actually, websites block crawlers and unknown clients
  • transparent proxy from your ISP, which either mangles or blocks (PHP user-agent or non-user-agent could be interpreted as malware)
  • PHP stream wrapper problems

Anyway, first let's proof that PHPs stream handlers are functional:

<?php
     if (!file_get_contents("data:,ok")) {
          die("Houston, we have a stream wrapper problem.");
     }

Then try to see if PHP makes real HTTP requests at all. First open netcat on the console:

nc -l 80000

And debug with just:

<?php
    print file_get_contents("http://localhost:8000/hello");

And from here you can try to communicate with PHP, see if anything returns if you variate the response. Enter an invalid response first into netcat. If there's no error thrown, your PHP package is borked.

(You might also try communicating over a "tcp://.." handle then.)

Next up is experimenting with http stream wrapper parameters. Use http://example.com/ literally, which is known to work and never block user-agents.

$context = stream_context_create(array("http"=>array(
    "method" => "GET",
    "header" => "Accept: xml/*, text/*, */*\r\n",
    "ignore_errors" => false,
    "timeout" => 50,
));

print file_get_contents("http://www.example.com/", false, $context, 0, 1000);

I think ignore_errors is very relevant here. But check out http://www.php.net/manual/en/context.http.php and specifically try to set protocol_version to 1.1 (will get chunked and misinterpreted response, but at least we'll see if anything returns).

If even this remains unsuccessful, then try to hack the http wrapper.

<?php
    ini_set("user_agent" , "Mozilla/3.0\r\nAccept: */*\r\nX-Padding: Foo");

This will not only set the User-Agent, but inject extra headers. If there is a processing issue with construction the request within the http stream wrapper, then this could very eventually catch it.

Otherwise try to disable any Zend extensions, Suhosin, PHP xdebug, APC and other core modules. There could be interferences. Else this is potentiallyan issue specific to the Fedora package. Try a new version, see if it persists on your system.

mario
  • 144,265
  • 20
  • 237
  • 291
  • https://stackoverflow.com/questions/2226374/test-if-port-open-and-forwarded-using-php would complete this amazing guideline – Bheid Apr 03 '18 at 10:01
  • `allow_url_fopen` was off and causing the issue. – W.M. Nov 27 '18 at 17:22
5

When you use the http stream wrapper PHP creates an array for you called $http_response_header after file_get_contents() (or any of the other f family of functions) is called. This contains useful info on the state of the response. Could you do a var_dump() of this array and see if it gives you any more info on the response?

It's a really weird error that you're getting. The only thing I can think of is that something else on the server is blocking the http requests from PHP, but then I can't see why cURL would still be ok...

YakovL
  • 7,557
  • 12
  • 62
  • 102
Jeremy
  • 2,651
  • 1
  • 21
  • 28
2

Is http stream registered in your PHP installation? Look for "Registered PHP Streams" in your phpinfo() output. Mine says "https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, zip".

If there is no http, set allow_url_fopen to on in your php.ini.

Brane
  • 3,257
  • 2
  • 42
  • 53
Donatas Olsevičius
  • 1,350
  • 8
  • 13
1

My problem was solved dealing with the SSL:

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

$context = stream_context_create($arrContextOptions);
        
$jsonContent = file_get_contents("https://www.yoursite.com", false, $context);
Francisco Campos
  • 1,191
  • 8
  • 16
-1

I had the same issue in Windows after installing XAMPP 1.7.7. Eventually I managed to solve it by adding the following line to php.ini (while having allow_url_fopen = On):

extension=php_openssl.dll

Master Drools
  • 728
  • 6
  • 18
-1

What does a test with fsockopen tell you?

Is the test isolated from other code?

c0rnh0li0
  • 151
  • 1
  • 8
-3

Use http://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a2CompatFunctionfile_get_contents.php.html and rename it and test if the error occurs with this rewritten function.

powtac
  • 40,542
  • 28
  • 115
  • 170