Created
December 23, 2015 13:06
-
-
Save jm42/d4b3638343cfa34fb86b to your computer and use it in GitHub Desktop.
HTTP Server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class Request { | |
| public $get; | |
| public $post; | |
| public $server; | |
| function __construct($server, $get, $post) { | |
| $this->get = $get; | |
| $this->post = $post; | |
| $this->server = $server; | |
| } | |
| } | |
| class Response { | |
| public $headers = []; | |
| public $body; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| require_once __DIR__ . '/http.php'; | |
| require_once __DIR__ . '/server.php'; | |
| class App { | |
| function __invoke(Request $req) { | |
| $req = new Response(); | |
| $req->body = "\n\n\nHello World\n\n\n"; | |
| return $req; | |
| } | |
| } | |
| $app = new App(); | |
| if (PHP_SAPI === 'cli') { | |
| $server = new HTTPServer($app); | |
| $server->listen('0.0.0.0', 5400); | |
| $server->start(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class HTTPServer { | |
| private $handler; | |
| private $queue; | |
| function __construct(callable $handler) { | |
| if (!extension_loaded('pcntl')) { | |
| throw new \RuntimeException('pcntl extension required'); | |
| } | |
| $queue = '/tmp/aix-queue'; | |
| if (file_exists($queue)) { | |
| unlink($queue); | |
| } | |
| touch($queue); | |
| $this->handler = $handler; | |
| $this->queue = msg_get_queue(ftok($queue, 'R'), 0777); | |
| } | |
| function listen($address, $port) { | |
| $pid = pcntl_fork(); | |
| sleep(0.001); | |
| if ($pid === -1) { | |
| throw new \RuntimeException('unable to fork'); | |
| } | |
| if ($pid > 0) { | |
| return; | |
| } | |
| $lock = '/tmp/aix-' . $address . '-' . $port . '.lock'; | |
| if (file_exists($lock)) { | |
| unlink($lock); | |
| } | |
| $cmd = PHP_BINARY . ' -S ' . $address . ':' . $port . ' ' | |
| . __DIR__ . DIRECTORY_SEPARATOR . 'server_router.php'; | |
| $handler = popen($cmd, 'r'); | |
| if ($handler === false) { | |
| throw new \RuntimeException('unable to run PHP cli server'); | |
| } | |
| print("Web server listing at http://$address:$port\n"); | |
| touch($lock); | |
| while (true) { | |
| if (!file_exists($lock)) { | |
| pclose($handler); | |
| print("Web server closed\n"); | |
| exit(); | |
| } | |
| sleep(1); | |
| } | |
| } | |
| function start() { | |
| for ($i = 0; $i < 3; $i++) { | |
| $this->runThread(100 + $i); | |
| } | |
| } | |
| function stop() { | |
| for ($i = 0; $i < 3; $i++) { | |
| msg_send($this->queue, 100 + $i, 'exit'); | |
| } | |
| } | |
| private function runThread($msgid, $lifetime=10) { | |
| $pid = pcntl_fork(); | |
| sleep(0.001); | |
| if ($pid !== 0) { | |
| return; | |
| } | |
| set_time_limit($lifetime); | |
| while (true) { | |
| msg_receive($this->queue, $msgid, $msgtype, 1024*1024, $msg, true); | |
| if ($msg === 'exit') { | |
| exit(); | |
| } | |
| list($reqid, $data) = $msg; | |
| $req = new Request($data['server'], $data['get'], $data['post']); | |
| $res = call_user_func($this->handler, $req); | |
| msg_send($this->queue, $reqid, [$res->headers, $res->body], true, true); | |
| unset($msgtype, $msg); | |
| unset($reqid, $data); | |
| unset($req, $res); | |
| gc_collect_cycles(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| session_start(); | |
| if (!isset($_SESSION['__msgid'])) { | |
| $_SESSION['__msgid'] = 100 + rand(0, 2); | |
| } | |
| $data = array( | |
| 'session_id' => session_id(), | |
| 'get' => $_GET, | |
| 'post' => $_POST, | |
| 'server' => array_merge($_SERVER, $_ENV), | |
| ); | |
| session_write_close(); | |
| $queue = msg_get_queue(ftok('/tmp/aix-queue', 'R'), 0777); | |
| msg_send($queue, $_SESSION['__msgid'], [$id = rand(), $data], true, false); | |
| msg_receive($queue, $id, $msgtype, 1024*1024, $msg, true); | |
| list($headers, $body) = $msg; | |
| foreach ($headers as $header) { | |
| header($header); | |
| } | |
| print($body); | |
| error_log(sprintf('[%d] %s', http_response_code(), $_SERVER['REQUEST_URI']), 4); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment