]> granicus.if.org Git - php/commitdiff
Fix #76342: file_get_contents waits twice specified timeout
authorfancyweb <calvet.thomas@gmail.com>
Mon, 29 Jul 2019 22:33:13 +0000 (00:33 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Sep 2019 13:42:29 +0000 (15:42 +0200)
NEWS
ext/standard/http_fopen_wrapper.c
ext/standard/tests/http/bug76342.phpt [new file with mode: 0644]
ext/standard/tests/http/server.inc

diff --git a/NEWS b/NEWS
index fff6f1fb1ad25fd4950f60d6fe55c34781f15679..5bb40ac41a0752e745be7df7ffa57ebbaf001ee3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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:
index b80f982fe7b047c6120b34e2510a7b75a5d81274..be23679d2d80ce69a174dca237e910e394570b78 100644 (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!");
diff --git a/ext/standard/tests/http/bug76342.phpt b/ext/standard/tests/http/bug76342.phpt
new file mode 100644 (file)
index 0000000..1791270
--- /dev/null
@@ -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
index db66c3dd1373f0c76693b5a6a7a50b4a6d460f51..e58067492891e35cd3987d4788e4b844257daa35 100644 (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);