php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38826 file_get_contents for a URL returns nothing when file > 255 bytes
Submitted: 2006-09-14 11:47 UTC Modified: 2006-09-15 11:28 UTC
From: mfp@php.net Assigned:
Status: Not a bug Package: Streams related
PHP Version: 5.1.6 OS: WinXP
Private report: No CVE-ID: None
 [2006-09-14 11:47 UTC] mfp@php.net
Description:
------------
I am using file_get_contents with a URL. If the file I want to get is 255 bytes I get it fine. If it is 256 bytes or more, up to some upper limit which is somewhere around 3.5K, I get an empty string. 

Although I have only illustrated it with file_get_contents(), from the circumstances in which I first noticed odd behaviour I think it also applies generally to files opened with fopen(). 

Incidentally, the right number of bytes are coming from the web server, as the apache access log shows it is delivering 256 bytes:

127.0.0.1 - - [14/Sep/2006:12:34:37 +0100] "GET /MyService/AddressBook/info.xsd HTTP/1.0" 200 256

Reproduce code:
---------------
echo file_get_contents('http://localhost/MyService/AddressBook/info.xsd');

where the target file info.xsd is 256 bytes long




Expected result:
----------------
the contents of the file

Actual result:
--------------
nothing - empty string

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-09-14 11:51 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2006-09-14 12:36 UTC] mfp@php.net
Errr... I am not sure how seriously to take the response "[14 Sep 11:51am UTC] tony2001@php.net", but here goes:

1. The reproduce code is:

<?php
echo file_get_contents('http://localhost/MyService/AddressBook/info.xsd');
?>


2. I do not know how to supply a test script that does not rely on external resources since this problem occurs reading a URL and almost by definition a URL is an external resource.
 [2006-09-14 12:48 UTC] tony2001@php.net
Please upload the file somewhere and put the link here.
Make sure you're looking into the source of the page or even better try it with CLI.
I cannot reproduce anything like that:
var_dump(file_get_contents("http://tony2001.phpclub.net/dev/tmp/info.xsd"));
works like a charm with any PHP version I have here (and I have a lot of them).
 [2006-09-14 12:49 UTC] tony2001@php.net
>I am not sure how seriously to take the response

Well, I'm not sure either how to take a report with "http://localhost" as a test data.
 [2006-09-14 17:02 UTC] mfp@php.net
Sorry, I didn't mean to be rude with "not sure how seriously" - it looked like a boilerplate text and I thought it might be an automated response. And because it was just the size of the file that mattered I didn't think to put a copy of it in the defect; but I should have made that clearer.

Anyway, I am baffled. When I use file_get_contents to go for your file remotely it works fine, but if I put your file on my machine and go for it with localhost it goes wrong. I am running Apache/2.0.59 (Win32) PHP/5.1.6, by the way. 

I have got two files, one with 255 a's and one with 256 - which is the file that you put up. CURL gets correct contents and byte counts, file_get_contents does not. The Apache access log claims it is returning 255 and 256 bytes each time, though.

I am running it with CLI.

Here is my test now, comparing CURL with file_get_contents:

<?php

$buf = file_get_contents('http://localhost/255as.file');
echo strlen($buf) . "\n";

$buf = file_get_contents('http://localhost/256as.file');
echo strlen($buf) . "\n";

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://localhost/255as.file');
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,true);
$buf = curl_exec($curl_handle);
curl_close($curl_handle);
echo strlen($buf) . "\n";

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'http://localhost/256as.file');
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,true);
$buf = curl_exec($curl_handle);
curl_close($curl_handle);
echo strlen($buf) . "\n";

?>

It relies on the two files 255as.file and 256as.file being in the local server's docroot.

The output I get is:

255
0
255
256

The Apache access log says:

127.0.0.1 - - [14/Sep/2006:17:43:31 +0100] "GET /MyService/AddressBook/255as.file HTTP/1.0" 200 255
127.0.0.1 - - [14/Sep/2006:17:43:31 +0100] "GET /MyService/AddressBook/256as.file HTTP/1.0" 200 256
127.0.0.1 - - [14/Sep/2006:17:43:32 +0100] "GET /MyService/AddressBook/255as.file HTTP/1.1" 200 255
127.0.0.1 - - [14/Sep/2006:17:43:32 +0100] "GET /MyService/AddressBook/256as.file HTTP/1.1" 200 256

If you were able to point me to the right routine in PHP I could add a bit of diagnostic code and rebuild...or if I can help in any other way. 

My colleague, who has a very similar set up (but running 5.1.4) sees the same thing on her machine, completely independent of mine, by the way.
 [2006-09-14 17:37 UTC] tony2001@php.net
Does this work for you:
var_dump(file_get_contents("http://tony2001.phpclub.net/dev/tmp/info.xsd"));

?

 [2006-09-14 21:53 UTC] mfp@php.net
Yes, the var_dump going to your file remotely does:
string(256) "aaaaaaaaaaaaa......
It is your fle that I copied to make my 256as.file. 

But when I copy your file under my Apache and do file_get_contents to it I get the empty string. 

So I can only suppose that it is somehow something to do with my local 5.1.6. PHP CLI talking to my local Apache with 5.1.6 underneath, on WinXP.
 [2006-09-14 22:01 UTC] tony2001@php.net
And the URL "http://localhost/256as.file" does work for you in a browser and using telnet, right?
 [2006-09-15 10:12 UTC] mfp@php.net
Ah that was a good idea of yours, using telnet. I had not thought of that. That took PHP out of picture and shows that the issue is entirely to do with Apache:

telnet localhost 80
GET /255as.file HTTP/1.0

gets:

HTTP/1.1 200 OK
Date: Fri, 15 Sep 2006 09:49:02 GMT
Server: Apache/2.0.59 (Win32) PHP/5.1.6
Last-Modified: Thu, 14 Sep 2006 14:17:59 GMT
ETag: "345e9-ff-9324eca6"
Accept-Ranges: bytes
Content-Length: 255
Connection: close
Content-Type: text/plain
X-Pad: avoid browser bug

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaa


Connection to host lost.

C:\Documents and Settings\Administrator>

whereas:

telnet localhost 80
GET /256as.file HTTP/1.0

gets:

HTTP/1.1 200 OK
Date: Fri, 15 Sep 2006 09:50:14 GMT
Server: Apache/2.0.59 (Win32) PHP/5.1.6
Last-Modified: Thu, 14 Sep 2006 14:15:35 GMT
ETag: "345ea-100-8a8e1f11"
Accept-Ranges: bytes
Content-Length: 256
Connection: close
Content-Type: text/plain
X-Pad: avoid browser bug



Connection to host lost.

C:\Documents and Settings\Administrator>

This now explains why the results using curl are different - that is using HTTP/1.1 on its GETs. Likewise Firefox. 

So, sorry to have troubled you, this is purely an Apache bug. The thing that confused me was the access.log showing the GET as successful. I will remember for the future how useful telnet is for debugging this. 

I will close this bug and either hunt down an Apache fix or work around using curl. Thanks for your help.
 [2006-09-15 10:23 UTC] mfp@php.net
Actually, 10 minutes later, I think I was a bit hasty in closing it. It was when I realised that curl is optional and might not be there, so the workaround does not come for free. 

What are the chances of getting file_get_contents to send an HTTP/1.1 request instead of HTTP/1.0?
 [2006-09-15 10:43 UTC] tony2001@php.net
It's still not PHP problem, even if http:// wrapper works with HTTP/1.0 (which is apparently expected).
I don't think it's worth rewriting a part of streams API because of an apache/win32 issue..
 [2006-09-15 11:28 UTC] mfp@php.net
Fair enough.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 10:01:30 2024 UTC