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