Completed
Push — master ( f6e5d2...6de545 )
by Nazar
05:16
created

Controller::index_run_pool()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   Http server
4
 * @category  modules
5
 * @author    Nazar Mokrynskyi <[email protected]>
6
 * @copyright Copyright (c) 2015-2016, Nazar Mokrynskyi
7
 * @license   MIT License, see license.txt
8
 */
9
namespace cs\modules\Http_server\cli;
10
use
11
	React,
12
	cs\ExitException,
13
	cs\modules\Http_server\Request;
14
15
class Controller {
16
	public static function index_help () {
17
		return <<<HELP
18
%yHttp server module%n
19
20
%yMethods:%n
21
  %grun_server%n Prints all cli paths and methods available for specified path
22
  %grun_pool%n   Displays help for module or path (should be provided by developer, otherwise will fallback to %gcli%n)
23
24
%yArguments:%n
25
  %gport%n  Required for %grun_server%n, specifies port on which server will be running
26
  %gports%n Required for %grun_pool%n, specifies ports on which server will be running (coma-separated list of ports or ports ranged separated by -)
27
28
%yExamples:%n
29
  Run HTTP server on port 8080:
30
    %g./cli run_server:Http_server port=8080%n
31
  Run pool of HTTP servers on ports 8080, 8081 and range of ports 8082-8087:
32
    %g./cli run_pool:Http_server ports=8080,8081,8082-8087%n
33
34
HELP;
35
	}
36
	/**
37
	 * @param \cs\Request $Request
38
	 *
39
	 * @throws ExitException
40
	 */
41
	public static function index_run_server ($Request) {
42
		$port = $Request->query('port');
43
		if (!$port) {
44
			throw new ExitException('Port is required', 400);
45
		}
46
47
		$loop   = React\EventLoop\Factory::create();
48
		$socket = new React\Socket\Server($loop);
49
		$http   = new React\Http\Server($socket);
50
		$http->on(
51
			'request',
52
			function (React\Http\Request $request, React\Http\Response $response) {
53
				$request->on(
54
					'data',
55
					function ($data) use ($request, $response) {
56
						Request::process($request, $response, microtime(true), $data);
57
					}
58
				);
59
			}
60
		);
61
		$socket->listen($port);
62
		$loop->run();
63
	}
64
	/**
65
	 * @param \cs\Request $Request
66
	 *
67
	 * @throws ExitException
68
	 */
69
	public static function index_run_pool ($Request) {
70
		$ports = $Request->query('ports');
71
		if (!$ports) {
72
			throw new ExitException('Ports are required', 400);
73
		}
74
		$ports = static::prepare_ports($ports);
75
		foreach ($ports as $p) {
76
			static::cross_platform_server_in_background($p);
77
		}
78
		echo "Pool of Http servers started!\n";
79
	}
80
	/**
81
	 * @param string $posts
82
	 *
83
	 * @return int[]
84
	 */
85
	protected static function prepare_ports ($posts) {
86
		$result_ports = [];
87
		foreach (explode(',', $posts) as $p) {
88
			if (strpos($p, '-') !== false) {
89
				$result_ports = array_merge($posts, range(...explode('-', $p)));
90
			} else {
91
				$result_ports[] = $p;
92
			}
93
		}
94
		sort($result_ports);
95
		return $result_ports;
96
	}
97
	/**
98
	 * Running Http server in background on any platform
99
	 *
100
	 * @param int $port
101
	 */
102
	protected static function cross_platform_server_in_background ($port) {
103
		$dir        = realpath(__DIR__.'/..');
104
		$supervisor = "php $dir/supervisor.php";
105
		$cmd        = escapeshellarg(PHP_BINARY.' '.DIR."/cli run_server:Http_server port=$port");
106
		if (strpos(PHP_OS, 'WIN') === false) {
107
			exec("$supervisor $cmd > /dev/null &");
108
		} else {
109
			pclose(popen("start /B $supervisor $cmd", 'r'));
110
		}
111
	}
112
}
113