payload_server.inc 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <?php
  2. function run_server(string $payloadFile): string {
  3. $cmd = [getenv("TEST_PHP_EXECUTABLE"), "-n", __DIR__ . "/payload_server.php", $payloadFile];
  4. $descriptorspec = array(
  5. 0 => STDIN,
  6. 1 => STDOUT,
  7. 2 => ['pipe', 'w'],
  8. );
  9. $proc = proc_open($cmd, $descriptorspec, $pipes);
  10. // First, wait for the payload server to declare itself ready.
  11. $bound = null;
  12. stream_set_blocking($pipes[2], false);
  13. for ($i = 0; $i < 60; $i++) {
  14. usleep(50000); // 50ms per try
  15. $status = proc_get_status($proc);
  16. if (empty($status['running'])) {
  17. echo "Server is not running\n";
  18. proc_terminate($proc);
  19. exit(1);
  20. }
  21. while (($line = fgets($pipes[2])) !== false) {
  22. if (preg_match('/FB payload server listening on (.+)/', $line, $matches)) {
  23. $bound = $matches[1];
  24. // Now that we've identified the listen address, close STDERR.
  25. // Otherwise the pipe may clog up with unread log messages.
  26. fclose($pipes[2]);
  27. break 2;
  28. }
  29. }
  30. }
  31. if ($bound === null) {
  32. echo "Server did not output startup message";
  33. proc_terminate($proc);
  34. exit(1);
  35. }
  36. // Now wait for a connection to succeed.
  37. // note: even when server prints 'FB payload server listening on localhost:12345'
  38. // it might not be listening yet...need to wait until fsockopen() call returns
  39. $error = "Unable to connect to server\n";
  40. for ($i=0; $i < 60; $i++) {
  41. usleep(50000); // 50ms per try
  42. $status = proc_get_status($proc);
  43. $fp = fsockopen("tcp://$bound");
  44. // Failure, the server is no longer running
  45. if (!($status && $status['running'])) {
  46. $error = "Server is not running\n";
  47. break;
  48. }
  49. // Success, Connected to servers
  50. if ($fp) {
  51. $error = '';
  52. break;
  53. }
  54. }
  55. if ($fp) {
  56. fclose($fp);
  57. }
  58. if ($error) {
  59. echo $error;
  60. proc_terminate($proc);
  61. exit(1);
  62. }
  63. register_shutdown_function(
  64. function($proc) {
  65. proc_terminate($proc);
  66. /* Wait for server to shutdown */
  67. for ($i = 0; $i < 60; $i++) {
  68. $status = proc_get_status($proc);
  69. if (!($status && $status['running'])) {
  70. break;
  71. }
  72. usleep(50000);
  73. }
  74. },
  75. $proc
  76. );
  77. return $bound;
  78. }