[php-src] Issue #10633: curl responses mixed up with pcnt_fork

From: Date: Mon, 20 Feb 2023 10:29:30 +0000
Subject: [php-src] Issue #10633: curl responses mixed up with pcnt_fork
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-243754@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/10633 Author: mrsuh ### Description Hi! I have a PHP daemon with two forks. Each fork makes an HTTP requests to a remote server. Sometimes(often) responses in forks are mixed up. ## How to reproduce ### Remote server ```bash php -v PHP 8.1.16 (cli) (built: Feb 14 2023 18:59:41) (NTS gcc x86_64) Copyright (c) The PHP Group Zend Engine v4.1.16, Copyright (c) Zend Technologies ``` server/index.php ```php <?php switch ($_SERVER['REQUEST_URI']) { case '/200': http_response_code(200); break; case '/404': http_response_code(404); break; default: http_response_code(500); } ``` ```bash symfony serve --no-tls --port=9999 --dir=server [OK] Web server listening The Web server is using PHP CGI 8.1.16 http://127.0.0.1:9999 [Web Server ] Feb 15 15:02:25 |DEBUG | PHP Reloading PHP versions [Web Server ] Feb 15 15:02:25 |DEBUG | PHP Using PHP version 8.1.16 (from default version in $PATH) [Web Server ] Feb 15 15:02:25 |INFO | PHP listening path="/usr/bin/php-cgi" php="8.1.16" port=11238 [Web Server ] Feb 15 15:02:28 |INFO | SERVER GET (200) /200 ip="" [Web Server ] Feb 15 15:02:28 |INFO | SERVER GET (200) /200 [Web Server ] Feb 15 15:02:28 |WARN | SERVER GET (404) /404 [Web Server ] Feb 15 15:02:29 |INFO | SERVER GET (200) /200 [Web Server ] Feb 15 15:02:29 |WARN | SERVER GET (404) /404 [Web Server ] Feb 15 15:02:30 |WARN | SERVER GET (404) /404 [Web Server ] Feb 15 15:02:30 |INFO | SERVER GET (200) /200 [Web Server ] Feb 15 15:02:31 |WARN | SERVER GET (404) /404 [Web Server ] Feb 15 15:02:31 |INFO | SERVER GET (200) /200 ``` ```bash curl 'http://{remote_server}:9999/200' -I HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 X-Powered-By: PHP/8.1.16 curl 'http://{remote_server}:9999/404' -I HTTP/1.1 404 Not Found Content-Type: text/html; charset=UTF-8 X-Powered-By: PHP/8.1.16 ``` ### Local server ```bash php -v PHP 8.1.0 (cli) (built: Dec 2 2021 12:37:35) (ZTS) Copyright (c) The PHP Group Zend Engine v4.1.0, Copyright (c) Zend Technologies ``` client/test.php ``` <?php $url200 = 'http://{remote_server}:9999/200'; $url404 = 'http://{remote_server}:9999/404'; function request(\CurlMultiHandle $multi, string $url): int { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_multi_add_handle($multi, $ch); do { $status = curl_multi_exec($multi, $active); if ($active) { curl_multi_select($multi); } } while ($active && $status === CURLM_OK); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_multi_remove_handle($multi, $ch); return (int)$httpCode; } $multi = curl_multi_init(); request($multi, $url200);// the request before pcntl_fork is important to reproduce error $pid = pcntl_fork(); if ($pid === -1) { exit(1); } if ($pid) { $status = 0; while (pcntl_wait($status, WNOHANG | WUNTRACED) === 0) { $httpCode = request($multi, $url200); if ($httpCode !== 200) { printf("GET /200 - %d\n", $httpCode); break; } sleep(1); } posix_kill($pid, SIGKILL); } else { while (true) { $httpCode = request($multi, $url404); if ($httpCode !== 404) { printf("GET /404 - %d\n", $httpCode); break; } sleep(1); } } ``` Resulted in this output: ```bash GET /404 - 200 GET /200 - 0 //timeout ``` But I expected this output instead: ```bash GET /404 - 404 GET /200 - 200 ``` Error only reproduces with a remote(not local) server. I tested it with two different remote servers. ### PHP Version 8.1.0 ### Operating System macOs BigSur 11.7.4

« previous php.bugs (#243754) next »