Edit report at https://bugs.php.net/bug.php?id=80931&edit=1
ID: 80931
Comment by: danack@php.net
Reported by: gilperon at gmail dot com
Summary: file_get_contents() hangs on PHP 8
Status: Verified
Type: Bug
Package: Streams related
Operating System: any
PHP Version: 8.0.3
Block user comment: N
Private report: N
New Comment:
Somewhat astoundingly, the difference appears to be come from the remote server.
PHP7
recvfrom(3, "HTTP/1.1 200 OK\r\ncache-control: private\r\ncontent-type: text/xml;
charset=iso-8859-1\r\nexpires: Wed, 07 Apr 2021 16:38:47 GMT\r\nserver:
Microsoft-IIS/10.0\r\nx-aspnet-version: 4.0.30319\r\nset-cookie:
ASP.NET_SessionId=1et22nqgou4jk0ecrns5opu3; path=/; HttpOnly; SameSite=Lax\r\nx-powered-by:
ASP.NET\r\ndate: Wed, 07 Apr 2021 16:38:46 GMT\r\ncontent-length: 464\r\nconnection:
close\r\n\r\n<?xml version=\"1.0\" encoding=\"ISO-8859-1\"
?>\n<Servicos><cServico>
PHP8
recvfrom(3, "HTTP/1.1 200 OK\r\ncache-control: private\r\ncontent-type: text/xml;
charset=iso-8859-1\r\nexpires: Wed, 07 Apr 2021 16:40:02 GMT\r\nserver:
Microsoft-IIS/10.0\r\nx-aspnet-version: 4.0.30319\r\nset-cookie:
ASP.NET_SessionId=4wf1fkvdhyzzz1czsdoqdd01; path=/; HttpOnly; SameSite=Lax\r\nx-powered-by:
ASP.NET\r\ndate: Wed, 07 Apr 2021 16:40:02 GMT\r\ncontent-length: 464\r\n\r\n<?xml
version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n<Servicos><cServico>
The response under PHP 7 includes a 'connection: close", the response under PHP 8
doesn't.
I can't currently see any difference in the way the connection is being made that would cause
that difference.
Previous Comments:
------------------------------------------------------------------------
[2021-04-07 15:37:25] cmb@php.net
I can confirm the reported behavior. The request is sent, the
response headers are read, but for some reason select(2) times out
under PHP 8.0, but not under PHP 7.4. After a few timeouts, the
response body is finally read, though.
------------------------------------------------------------------------
[2021-04-07 13:16:18] gilperon at gmail dot com
@carusogabriel@php.net the value of my default_socket_timeout is 60. I changed it to 5
seconds, restarted my server, and then I executed your code below:
<?php
$context = stream_context_create();
echo file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?StrRetorno=xml",
0, $context);
?>
It always echoes nothing (blank string) after 5 seconds. However, the URL used above should return:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<Servicos></Servicos>
So setting default_socket_timeout to a smaller value does not work because the script
still lasts all the time configured in default_socket_timeout and returns nothing.
------------------------------------------------------------------------
[2021-04-07 02:39:31] carusogabriel@php.net
Actually, a smaller script "fixes" it not working in PHP 8.0:
```
<?php
$context = stream_context_create();
echo file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?StrRetorno=xml",
0, $context);
```
@gilperon What is the value of your default_socket_timeout php.ini entry? That might
explain why it is taking forever, because if the default of 60, I waited and the
scripted executed locally :)
------------------------------------------------------------------------
[2021-04-07 02:27:09] carusogabriel@php.net
This bug is reproducible in macOS (v10.15.7) as well. And we can test it with a smaller script:
```
<?php
$context = stream_context_create(['http' => ['timeout' => 2]]);
echo file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?StrRetorno=xml",
0, $context);
```
------------------------------------------------------------------------
[2021-04-03 14:08:26] gilperon at gmail dot com
Description:
------------
In any version of PHP (previous to 8) this bug didnt happen (I've been using it since 2010) but
on PHP 8, the code below hangs indefinately. Tested on Windows 7, Windows 10, Centos 8 and Centos 7.
The code below just tries to access an external API and, so far, I just managed to get this bug to
happen on this specific URL below (from the API).
<?php
$response = file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=11661690&sCepDestino=88070-480&nVlPeso=1&nCdFormato=1&nVlComprimento=25&nVlAltura=3&nVlLargura=25&sCdMaoPropria=N&nVlValorDeclarado=0&sCdAvisoRecebimento=N&nCdServico=04014&nVlDiametro=0&StrRetorno=xml");
echo $response;
?>
BUT if I add a timeout, the code above works just fine:
<?php
$context = stream_context_create(array(
"http" => array(
"timeout" => 2
)
));
$response = file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=11661690&sCepDestino=88070-480&nVlPeso=1&nCdFormato=1&nVlComprimento=25&nVlAltura=3&nVlLargura=25&sCdMaoPropria=N&nVlValorDeclarado=0&sCdAvisoRecebimento=N&nCdServico=04014&nVlDiametro=0&StrRetorno=xml",0,$context);
echo $response;
?>
I must say that using CURL works just fine, without any timeout, on any version of PHP. So this is a
file_get_contents problem and the only way I am finding to solve this problem in the
short term is using CURL.
Test script:
---------------
<?php
$response = file_get_contents("http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=11661690&sCepDestino=88070-480&nVlPeso=1&nCdFormato=1&nVlComprimento=25&nVlAltura=3&nVlLargura=25&sCdMaoPropria=N&nVlValorDeclarado=0&sCdAvisoRecebimento=N&nCdServico=04014&nVlDiametro=0&StrRetorno=xml");
echo $response;
?>
Expected result:
----------------
Response should be printed.
Actual result:
--------------
The code hangs.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=80931&edit=1