1<?php declare(strict_types=1); 2 3function curl_cli_server_start() { 4 if(getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { 5 return getenv('PHP_CURL_HTTP_REMOTE_SERVER'); 6 } 7 8 $php_executable = getenv('TEST_PHP_EXECUTABLE'); 9 $doc_root = __DIR__; 10 $router = "responder/get.inc"; 11 $cmd = [$php_executable, '-t', $doc_root, '-n', '-S', 'localhost:0', $router]; 12 $descriptorspec = array( 13 0 => STDIN, 14 1 => STDOUT, 15 2 => ['pipe', 'w'], 16 ); 17 $handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root, null, array("suppress_errors" => true)); 18 19 // First, wait for the dev server to declare itself ready. 20 $bound = null; 21 stream_set_blocking($pipes[2], false); 22 for ($i = 0; $i < 60; $i++) { 23 usleep(50000); // 50ms per try 24 $status = proc_get_status($handle); 25 if (empty($status['running'])) { 26 echo "Server is not running\n"; 27 proc_terminate($handle); 28 exit(1); 29 } 30 31 while (($line = fgets($pipes[2])) !== false) { 32 if (preg_match('@PHP \S* Development Server \(https?://(.*?:\d+)\) started@', $line, $matches)) { 33 $bound = $matches[1]; 34 // Now that we've identified the listen address, close STDERR. 35 // Otherwise the pipe may clog up with unread log messages. 36 fclose($pipes[2]); 37 break 2; 38 } 39 } 40 } 41 if ($bound === null) { 42 echo "Server did not output startup message"; 43 proc_terminate($handle); 44 exit(1); 45 } 46 47 // Now wait for a connection to succeed. 48 // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.' 49 // it might not be listening yet...need to wait until fsockopen() call returns 50 $error = "Unable to connect to server\n"; 51 for ($i=0; $i < 60; $i++) { 52 usleep(50000); // 50ms per try 53 $status = proc_get_status($handle); 54 $fp = @fsockopen("tcp://$bound"); 55 // Failure, the server is no longer running 56 if (!($status && $status['running'])) { 57 $error = "Server is not running\n"; 58 break; 59 } 60 // Success, Connected to servers 61 if ($fp) { 62 $error = ''; 63 break; 64 } 65 } 66 67 if ($fp) { 68 fclose($fp); 69 } 70 71 if ($error) { 72 echo $error; 73 proc_terminate($handle); 74 exit(1); 75 } 76 77 register_shutdown_function( 78 function($handle) use($router) { 79 proc_terminate($handle); 80 /* Wait for server to shutdown */ 81 for ($i = 0; $i < 60; $i++) { 82 $status = proc_get_status($handle); 83 if (!($status && $status['running'])) { 84 break; 85 } 86 usleep(50000); 87 } 88 }, 89 $handle 90 ); 91 92 return $bound; 93} 94