<?php declare (strict_types=1); namespace Amplify\Cli; use Aerys\Host; use function Aerys\root; require_once __DIR__ . '/../bootstrap.php'; (new Host())->name('localhost')->expose('*', 8081)->use($router)->use(root(__DIR__ . '/../public'));
private function doEncrypt(string $acmeServer, array $contact) : Generator { $domain = strtok(str_replace("https://", "", $acmeServer), "/"); $info = $this->host->export(); $dns = $info["name"]; $this->mkdirs($this->path . "/accounts/{$domain}", $this->path . "/keys/{$dns}", $this->path . "/live", $this->path . "/challenges/{$dns}/.well-known/acme-challenge"); $this->host->use(root($this->path . "/challenges/{$dns}")); $this->host->use($this); $accountKeyPair = (yield $this->loadKeyPair($this->path . "/accounts/{$domain}")); $domainKeyPair = (yield $this->loadKeyPair($this->path . "/keys/{$dns}")); $certificateService = new AcmeService(new AcmeClient($acmeServer, $accountKeyPair), $accountKeyPair, new AcmeAdapter($this->path)); list($selfSigned, $lifetime) = (yield $certificateService->getCertificateData($dns)); if ($lifetime > 30 * 24 * 60 * 60 && !$selfSigned) { // valid for more than 30 days and not self signed $this->host->encrypt($this->path . "/live/{$dns}.pem"); // TODO Add timer to renew certificate! return; } try { (yield put($this->path . "/live/{$dns}.lock", $dns)); } catch (FilesystemException $e) { } $lock = new Lock($this->path . "/live/{$dns}.lock"); try { $lock->acquire(); if ($lifetime < 1 || $selfSigned) { // don't touch valid certificate here if still in place. $privateKey = openssl_pkey_get_private($domainKeyPair->getPrivate()); $csr = openssl_csr_new(["commonName" => $dns, "organizationName" => "kelunik/aerys-acme"], $privateKey, ["digest_alg" => "sha256"]); if (!$csr) { throw new AcmeException("CSR couldn't be generated!"); } $privateCertificate = openssl_csr_sign($csr, null, $privateKey, 90, ["digest_alg" => "sha256"], random_int(0, PHP_INT_MAX)); openssl_x509_export($privateCertificate, $cert); file_put_contents($this->path . "/live/{$dns}.pem", implode("\n", [$domainKeyPair->getPrivate(), $cert])); } $this->host->encrypt($this->path . "/live/{$dns}.pem"); $this->onBoot = function (Server $server) use($certificateService, $dns, $contact, $lock) { $certificateService->issueCertificate($dns, $contact, $this->agreement)->when(function (Throwable $error = null) use($server, $lock, $dns) { $lock->release(); unlink($this->path . "/live/{$dns}.lock"); if ($error) { $this->logger->emergency($error); // $server->stop(); } }); }; } catch (LockException $e) { do { (yield new Pause(500)); } while (!(yield exists($this->path . "/live/{$dns}.pem"))); $this->host->encrypt($this->path . "/live/{$dns}.pem"); } }
<?php use Aerys\Host; use Aerys\Router; use Kelunik\Demo\Chat; use function Aerys\root; use function Aerys\websocket; // route /ws to the websocket endpoint // you can add more routes to this router $router = (new Router())->route("GET", "ws", websocket(new Chat())); // add document root $root = root(__DIR__ . "/public"); // create virtual host localhost:1337 // requests will first be routed, if no route matches, the server tries to find a file in the document root // you can add more responders or even multiple document roots to a single host (new Host())->name("localhost")->expose("*", 1337)->use($router)->use($root); // $logger is the default Aerys logger which we can just use here to print a note $logger->info("Open your browser and point it to http://localhost:1337/");
$injector->share(new SubscribeClient(config("redis.protocol") . "://" . config("redis.host") . ":" . config("redis.port"))); $injector->share(new MySQL(sprintf("host=%s;user=%s;pass=%s;db=%s", config("database.host"), config("database.user"), config("database.pass"), config("database.name")))); $auth = $injector->make("Kelunik\\ChatMain\\Auth"); /** @var TemplateService $templateService */ $templateService = $injector->make("Kelunik\\Template\\TemplateService"); /** @var Chat $chat */ $chat = $injector->make("Kelunik\\Chat\\Chat"); $router = router()->get("", function (Request $req, Response $resp) use($templateService) { $session = (yield (new Session($req))->read()); if (!$session->get("login")) { $template = $templateService->load("main.php"); $resp->send($template->render()); } })->get("login", [$auth, "logIn"])->post("login/{provider:github|stack-exchange}", [$auth, "doLogInRedirect"])->get("login/{provider:github|stack-exchange}", [$auth, "doLogIn"])->get("join", [$auth, "join"])->post("join", [$auth, "doJoin"])->post("logout", [$auth, "doLogOut"]); $router->get("ws", Aerys\websocket($injector->make("Kelunik\\ChatMain\\WebSocketChat"))); $root = root(realpath(__DIR__ . "/../public"), ["indexes" => []]); $host = (new Aerys\Host())->expose("*", config("app.port"))->name(config("app.host"))->use($router)->use($root)->use(function (Request $request, Response $response) use($chat, $templateService) { $session = (yield (new Session($request))->read()); $user = new User($session->get("login") ?? 0, $session->get("login:name") ?? "", $session->get("login:avatar") ?? ""); $apiRequest = new StandardRequest("me/rooms", new stdClass(), null); $apiResponse = (yield $chat->process($apiRequest, $user)); if ($apiResponse->getStatus() !== 200) { $response->setStatus(503); $response->send("service currently not available"); return; } $template = $templateService->load("app.php"); $template->set("user", ["id" => $user->id, "name" => $user->name, "avatar" => $user->avatar]); $template->set("rooms", $apiResponse->getData()); $response->send($template->render()); });