server.inc 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. function http_server_skipif($socket_string) {
  3. if (!function_exists('pcntl_fork')) die('skip pcntl_fork() not available');
  4. if (!function_exists('posix_kill')) die('skip posix_kill() not available');
  5. if (!stream_socket_server($socket_string)) die('skip stream_socket_server() failed');
  6. }
  7. function http_server_init($socket_string, &$output = null) {
  8. pcntl_alarm(60);
  9. $server = stream_socket_server($socket_string, $errno, $errstr);
  10. if (!$server) {
  11. return false;
  12. }
  13. if ($output === null) {
  14. $output = tmpfile();
  15. if ($output === false) {
  16. return false;
  17. }
  18. }
  19. $pid = pcntl_fork();
  20. if ($pid == -1) {
  21. die('could not fork');
  22. } else if ($pid) {
  23. return $pid;
  24. }
  25. return $server;
  26. }
  27. /* Minimal HTTP server with predefined responses.
  28. *
  29. * $socket_string is the socket to create and listen on (e.g. tcp://127.0.0.1:1234)
  30. * $files is an array of files containing N responses for N expected requests. Server dies after N requests.
  31. * $output is a stream on which everything sent by clients is written to
  32. */
  33. function http_server($socket_string, array $files, &$output = null) {
  34. if (!is_resource($server = http_server_init($socket_string, $output))) {
  35. return $server;
  36. }
  37. foreach($files as $file) {
  38. $sock = stream_socket_accept($server);
  39. if (!$sock) {
  40. exit(1);
  41. }
  42. // read headers
  43. $content_length = 0;
  44. stream_set_blocking($sock, 0);
  45. while (!feof($sock)) {
  46. list($r, $w, $e) = array(array($sock), null, null);
  47. if (!stream_select($r, $w, $e, 1)) continue;
  48. $line = stream_get_line($sock, 8192, "\r\n");
  49. if ($line === '') {
  50. fwrite($output, "\r\n");
  51. break;
  52. } else if ($line !== false) {
  53. fwrite($output, "$line\r\n");
  54. if (preg_match('#^Content-Length\s*:\s*([[:digit:]]+)\s*$#i', $line, $matches)) {
  55. $content_length = (int) $matches[1];
  56. }
  57. }
  58. }
  59. stream_set_blocking($sock, 1);
  60. // read content
  61. if ($content_length > 0) {
  62. stream_copy_to_stream($sock, $output, $content_length);
  63. }
  64. // send response
  65. $fd = fopen($file, 'rb');
  66. stream_copy_to_stream($fd, $sock);
  67. fclose($sock);
  68. }
  69. exit(0);
  70. }
  71. function http_server_sleep($socket_string, $micro_seconds = 500000)
  72. {
  73. if (!is_resource($server = http_server_init($socket_string, $output))) {
  74. return $server;
  75. }
  76. $sock = stream_socket_accept($server);
  77. if (!$sock) {
  78. exit(1);
  79. }
  80. usleep($micro_seconds);
  81. fclose($sock);
  82. exit(0);
  83. }
  84. function http_server_kill($pid) {
  85. posix_kill($pid, SIGTERM);
  86. pcntl_waitpid($pid, $status);
  87. }
  88. ?>