Fix #76342: file_get_contents waits twice specified timeout

This commit is contained in:
fancyweb 2019-07-30 00:33:13 +02:00 committed by Nikita Popov
parent 252ebce0d7
commit e691a98c1f
4 changed files with 76 additions and 8 deletions

4
NEWS
View File

@ -10,6 +10,10 @@ PHP NEWS
. Fixed bug #78442 ('Illegal component' on exif_read_data since PHP7)
(Kalle)
- Standard:
. Fixed bug #76342 (file_get_contents waits twice specified timeout).
(Thomas Calvet)
26 Sep 2019, PHP 7.2.23
- Core:

View File

@ -726,6 +726,11 @@ finish:
}
ZVAL_STRINGL(&http_response, tmp_line, tmp_line_len);
zend_hash_next_index_insert(Z_ARRVAL_P(response_header), &http_response);
} else {
php_stream_close(stream);
stream = NULL;
php_stream_wrapper_log_error(wrapper, options, "HTTP request failed!");
goto out;
}
} else {
php_stream_wrapper_log_error(wrapper, options, "HTTP request failed, unexpected end of socket!");

View File

@ -0,0 +1,33 @@
--TEST--
Bug #76342 (file_get_contents waits twice specified timeout)
--INI--
allow_url_fopen=1
--SKIPIF--
<?php require 'server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); ?>
--FILE--
<?php
require 'server.inc';
$options = [
'http' => [
'timeout' => '0.1',
],
];
$ctx = stream_context_create($options);
$pid = http_server_sleep('tcp://127.0.0.1:12342');
$start = microtime(true);
file_get_contents('http://127.0.0.1:12342/', false, $ctx);
if (microtime(true) - $start >= 0.2) {
echo 'FAIL';
}
http_server_kill($pid);
?>
DONE
--EXPECTF--
Warning: file_get_contents(http://127.0.0.1:12342/): failed to open stream: HTTP request failed! in %s on line %d
DONE

View File

@ -7,14 +7,7 @@ function http_server_skipif($socket_string) {
if (!stream_socket_server($socket_string)) die('skip stream_socket_server() failed');
}
/* Minimal HTTP server with predefined responses.
*
* $socket_string is the socket to create and listen on (e.g. tcp://127.0.0.1:1234)
* $files is an array of files containing N responses for N expected requests. Server dies after N requests.
* $output is a stream on which everything sent by clients is written to
*/
function http_server($socket_string, array $files, &$output = null) {
function http_server_init($socket_string, &$output = null) {
pcntl_alarm(60);
$server = stream_socket_server($socket_string, $errno, $errstr);
@ -36,6 +29,21 @@ function http_server($socket_string, array $files, &$output = null) {
return $pid;
}
return $server;
}
/* Minimal HTTP server with predefined responses.
*
* $socket_string is the socket to create and listen on (e.g. tcp://127.0.0.1:1234)
* $files is an array of files containing N responses for N expected requests. Server dies after N requests.
* $output is a stream on which everything sent by clients is written to
*/
function http_server($socket_string, array $files, &$output = null) {
if (!is_resource($server = http_server_init($socket_string, $output))) {
return $server;
}
foreach($files as $file) {
$sock = stream_socket_accept($server);
@ -84,6 +92,24 @@ function http_server($socket_string, array $files, &$output = null) {
exit(0);
}
function http_server_sleep($socket_string, $micro_seconds = 500000)
{
if (!is_resource($server = http_server_init($socket_string, $output))) {
return $server;
}
$sock = stream_socket_accept($server);
if (!$sock) {
exit(1);
}
usleep($micro_seconds);
fclose($sock);
exit(0);
}
function http_server_kill($pid) {
posix_kill($pid, SIGTERM);
pcntl_waitpid($pid, $status);