Skip to content

Commit 681d7e1

Browse files
committed
Merge pull request #26 from zelgerj/master
added examples and output php_info as html
2 parents 98b8b0c + b038c1c commit 681d7e1

File tree

4 files changed

+281
-0
lines changed

4 files changed

+281
-0
lines changed

src/appserver.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ static void php_appserver_shutdown_globals (zend_appserver_globals *appserver_gl
171171

172172
static void php_appserver_init_globals(zend_appserver_globals *appserver_globals)
173173
{
174+
/* Reset phpinfo output to be non text */
175+
sapi_module.phpinfo_as_text = 0;
176+
174177
/* Override header generation in SAPI */
175178
if (sapi_module.header_handler != appserver_header_handler) {
176179
appserver_orig_header_handler = sapi_module.header_handler;
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
/**
4+
* Class ThreadWorker
5+
*/
6+
class ThreadWorker extends Thread
7+
{
8+
/**
9+
* @param $serverSocketResource The server socket resource
10+
*/
11+
public function __construct($serverSocketResource)
12+
{
13+
$this->maxConnections = 16;
14+
$this->serverSocketResource = $serverSocketResource;
15+
}
16+
17+
/**
18+
* thread routine
19+
*/
20+
public function run()
21+
{
22+
$this->done = false;
23+
$connectionCount = 0;
24+
25+
$dummyData = array();
26+
27+
do {
28+
if ($clientSocketResource = @stream_socket_accept($this->serverSocketResource)) {
29+
++$connectionCount;
30+
$dummyData[] = md5(time() . rand(0, PHP_INT_MAX) . time());
31+
// dummy read request
32+
$request = fread($clientSocketResource, 1);
33+
// build up response
34+
ob_start();
35+
phpinfo();
36+
$responseBody = ob_get_clean();
37+
$responseHeaders =
38+
"HTTP/1.1 200 OK" . "\r\n" .
39+
"Server: {{server}}" . "\r\n" .
40+
"Date: {{date}}" . "\r\n" .
41+
"Content-Type: text/html" . "\r\n" .
42+
"Content-Length: {{content-length}}" . "\r\n" .
43+
"Connection: close" . "\r\n";
44+
$responseHeaders = str_replace(
45+
array('{{server}}', '{{date}}', '{{content-length}}'),
46+
array(SERVER_NAME, gmdate('D, d M Y H:i:s T'), strlen($responseBody)),
47+
$responseHeaders
48+
);
49+
fwrite($clientSocketResource, $responseHeaders . "\r\n" . $responseBody);
50+
fclose($clientSocketResource);
51+
}
52+
} while (1);// ($connectionCount < $this->maxConnections);
53+
54+
$this->done = true;
55+
}
56+
}
57+
58+
/**
59+
* Class MultithreadedServer
60+
*/
61+
class MultithreadedServer extends Thread
62+
{
63+
public function __construct($localSocket, $workerCount, $serverName)
64+
{
65+
define('SERVER_NAME', $serverName);
66+
67+
$flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
68+
// set socket backlog to 1024 for perform many concurrent connections
69+
$opts = array(
70+
'socket' => array(
71+
'backlog' => 1024,
72+
)
73+
);
74+
// init stream context for server connection
75+
$streamContext = stream_context_create($opts);
76+
$serverStreamSocketResource = stream_socket_server($localSocket, $errno, $errstr, $flags, $streamContext);
77+
$serverSocketResource = socket_import_stream($serverStreamSocketResource);
78+
79+
// set socket options
80+
//socket_set_option($serverSocketResource, getprotobyname("tcp"), TCP_NODELAY, 1);
81+
82+
$this->workerCount = $workerCount;
83+
$this->serverStreamSocketResource = $serverStreamSocketResource;
84+
}
85+
86+
public function run()
87+
{
88+
$workers = [];
89+
while (count($workers) < $this->workerCount) {
90+
$worker = new ThreadWorker($this->serverStreamSocketResource);
91+
$worker->start();
92+
$workers[] = $worker;
93+
}
94+
95+
while (true) {
96+
for ($i = 0; $i < count($workers); $i++) {
97+
if ($workers[$i]->done === true) {
98+
echo "Kill ThreadId: " . $workers[$i]->getThreadId() . PHP_EOL;
99+
$worker = new ThreadWorker($this->serverStreamSocketResource);
100+
$worker->start();
101+
$workers[] = $worker;
102+
$workers[$i]->kill();
103+
}
104+
}
105+
usleep(100000);
106+
}
107+
}
108+
}
109+
110+
$server = new MultithreadedServer('127.0.0.1:8999', 8, 'BenchmarkSimpleHttpServer/1.0');
111+
$server->start();
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
/**
4+
* Class ThreadWorker
5+
*/
6+
class ThreadWorker extends Thread
7+
{
8+
/**
9+
* @param $serverSocketResource The server socket resource
10+
*/
11+
public function __construct($serverSocketResource)
12+
{
13+
$this->serverSocketResource = $serverSocketResource;
14+
}
15+
16+
/**
17+
* thread routine
18+
*/
19+
public function run()
20+
{
21+
while ($clientSocketResource = socket_accept($this->serverSocketResource)) {
22+
$request = socket_read($clientSocketResource, 2048);
23+
24+
// build up response
25+
$responseBody = "<html>" . "\r\n" .
26+
"<head>" . "\r\n" .
27+
"<title>Welcome to {{server}}!</title>" . "\r\n" .
28+
"</head>" . "\r\n" .
29+
"<body bgcolor=\"white\" text=\"black\">" . "\r\n" .
30+
"<center><h1>Welcome to {{server}}!</h1></center>" . "\r\n" .
31+
"</body>" . "\r\n" .
32+
"</html>" . "\r\n";
33+
$responseBody = str_replace(
34+
'{{server}}', SERVER_NAME, $responseBody
35+
);
36+
$responseHeaders =
37+
"HTTP/1.1 200 OK" . "\r\n" .
38+
"Server: {{server}}" . "\r\n" .
39+
"Date: {{date}}" . "\r\n" .
40+
"Content-Type: text/html" . "\r\n" .
41+
"Content-Length: {{content-length}}" . "\r\n" .
42+
"Connection: close" . "\r\n";
43+
$responseHeaders = str_replace(
44+
array('{{server}}','{{date}}','{{content-length}}'),
45+
array(SERVER_NAME, gmdate('D, d M Y H:i:s T'), strlen($responseBody)),
46+
$responseHeaders
47+
);
48+
$response = $responseHeaders . "\r\n" . $responseBody . "\r\n";
49+
socket_write($clientSocketResource, $response, strlen($response));
50+
socket_close($clientSocketResource);
51+
}
52+
}
53+
}
54+
55+
/**
56+
* Class MultithreadedServer
57+
*/
58+
class MultithreadedServer extends Thread
59+
{
60+
public function __construct($localSocket, $workerCount, $serverName)
61+
{
62+
define('SERVER_NAME', $serverName);
63+
64+
$flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
65+
// set socket backlog to 1024 for perform many concurrent connections
66+
$opts = array(
67+
'socket' => array(
68+
'tcp_nodelay' => true,
69+
'backlog' => 1024,
70+
)
71+
);
72+
// init socket
73+
$serverSocketResource = socket_create(AF_INET, SOCK_STREAM, 0);
74+
// bind the socket to an address/port
75+
socket_set_option($serverSocketResource, SOL_SOCKET, SO_REUSEADDR, 1);
76+
socket_bind($serverSocketResource, '127.0.0.1', '8999');
77+
// start listening for connections
78+
socket_listen($serverSocketResource, 65000);
79+
// set socket options
80+
socket_set_block($serverSocketResource);
81+
82+
$this->workerCount = $workerCount;
83+
$this->serverSocketResource = $serverSocketResource;
84+
}
85+
86+
public function run()
87+
{
88+
$workers = [];
89+
while (count($workers) < $this->workerCount) {
90+
$worker = new ThreadWorker($this->serverSocketResource);
91+
$worker->start();
92+
$workers[] = $worker;
93+
}
94+
}
95+
}
96+
97+
$server = new MultithreadedServer('127.0.0.1:8999', 64, 'BenchmarkSimpleHttpServer/1.0');
98+
$server->start();

src/examples/PoolingHttpServer.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
class WebWorker extends Worker {
3+
public function __construct($requestHandler) {
4+
$this->requestHandler = $requestHandler;
5+
}
6+
protected $requestHandler;
7+
}
8+
9+
class WebWork extends Collectable {
10+
public function __construct($client) {
11+
$this->client = $client;
12+
}
13+
public function run() {
14+
$client = $this->client;
15+
$this->worker->requestHandler->handle($client);
16+
$this->setGarbage();
17+
}
18+
}
19+
20+
class RequestHandler extends Threaded {
21+
22+
protected function handle($client) {
23+
// dummy read request
24+
$request = fread($client, 1024);
25+
// build up response
26+
$responseBody = "<html>" . "\r\n" .
27+
"<head>" . "\r\n" .
28+
"<title>Welcome!</title>" . "\r\n" .
29+
"</head>" . "\r\n" .
30+
"<body bgcolor=\"white\" text=\"black\">" . "\r\n" .
31+
"<center><h1>Welcome!</h1></center>" . "\r\n" .
32+
"</body>" . "\r\n" .
33+
"</html>" . "\r\n";
34+
$responseBody = str_replace(
35+
'{{server}}', SERVER_NAME, $responseBody
36+
);
37+
$responseHeaders =
38+
"HTTP/1.1 200 OK" . "\r\n" .
39+
"Server: {{server}}" . "\r\n" .
40+
"Date: {{date}}" . "\r\n" .
41+
"Content-Type: text/html" . "\r\n" .
42+
"Content-Length: {{content-length}}" . "\r\n" .
43+
"Connection: close" . "\r\n";
44+
$responseHeaders = str_replace(
45+
array('{{server}}', '{{date}}', '{{content-length}}'),
46+
array('Pooling/1.0', gmdate('D, d M Y H:i:s T'), strlen($responseBody)),
47+
$responseHeaders
48+
);
49+
fwrite($client, $responseHeaders . "\r\n" . $responseBody);
50+
fclose($client);
51+
}
52+
53+
}
54+
55+
$serverStreamSocketResource = stream_socket_server('tcp://127.0.0.1:8777',
56+
$errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
57+
stream_context_create(array('socket' => array('backlog' => 1024)))
58+
);
59+
60+
$pool = new Pool(8, 'WebWorker', [new RequestHandler()]);
61+
62+
63+
while (1) {
64+
if ($client = @stream_socket_accept($serverStreamSocketResource)) {
65+
$pool->submit(new WebWork($client));
66+
}
67+
}
68+
69+
?>

0 commit comments

Comments
 (0)