php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51330 file_get_contents for url hangs
Submitted: 2010-03-19 10:35 UTC Modified: 2010-03-23 10:31 UTC
Votes:5
Avg. Score:4.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:0 (0.0%)
Same OS:3 (75.0%)
From: liren dot chen at gmail dot com Assigned:
Status: Wont fix Package: HTTP related
PHP Version: 5.2.13 OS: win and linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2010-03-19 10:35 UTC] liren dot chen at gmail dot com
Description:
------------
file_get_contents("http://english.aljazeera.net/")

hangs until timeout.

I did a debug and found that file_get_contents doesn't check the "content-length" header.

If you do this way:

file_get_contents("http://english.aljazeera.net/", NULL, NULL, 0, 1);

then get "content-length" from the response header,

then 

file_get_contents("http://english.aljazeera.net/", NULL, NULL, 0, the-value-from-content-length);

then it works.

Apparently we should close the socket when we read content-length bytes from the socket and return.


Test script:
---------------
file_get_contents("http://english.aljazeera.net/")


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-03-23 10:31 UTC] aharvey@php.net
-Status: Open +Status: Wont fix
 [2010-03-23 10:31 UTC] aharvey@php.net
This looks like a problem with the Al-Jazeera Web serving infrastructure rather 
than a PHP issue. Basically, it's responding to a HTTP 1.0 request with no 
Connection header with a HTTP 1.1 response with a "Connection: keep-alive" 
header, which is counter to section 8.1.2.1 of RFC 2616, which states:

"Clients and servers SHOULD NOT assume that a persistent connection is 
maintained for HTTP versions less than 1.1 unless it is explicitly signaled. See 
section 19.6.2 for more information on backward compatibility with HTTP/1.0 
clients."

It's a SHOULD NOT, not a MUST NOT, but nevertheless it doesn't line up with 
normal HTTP server behaviour out there on the 'net, and there's no support for 
handling keep-alive connections within the HTTP wrapper. The problem can be 
worked around from within PHP by sending an explicit Connection request header 
like so:

<?php
$options = array(
    'http' => array(
        'header' => 'Connection: close'
    )
);
$ctx = stream_context_create($options);
$content = file_get_contents('http://english.aljazeera.net/', false, $ctx);
?>

Since php_stream_url_wrap_http_ex() downloads the entire response from the 
connection (and blocks until the socket is closed) before parsing the HTTP 
response (including headers), it would require a considerable amount of work to 
refactor the code to allow the Content-Length header to be examined.

This _might_ be something we could look at post-5.3, but I think this is best 
closed for now.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Feb 21 10:01:25 2019 UTC