private function saveFile(string $filePath, callable $callback) : \Generator { if (!isset($this->dataCache[$filePath])) { yield from $this->loadFile($filePath); } return (yield $this->lockMutexes[$filePath]->withLock(function () use($filePath, $callback) { $data = $callback($this->dataCache[$filePath]); if (!is_array($data)) { throw new \LogicException('JSON data files may only contain arrays as the root element'); } // make sure we can persist it before updating the store (yield put($filePath, json_try_encode($data))); return $this->dataCache[$filePath] = $data; })); }
private function doLoadKeyPair(string $path) : Generator { $privateExists = (yield exists("{$path}/private.pem")); $publicExists = (yield exists("{$path}/public.pem")); $lockExists = (yield exists("{$path}/key.lock")); if ($privateExists && $publicExists) { while ($lockExists) { (yield new Pause(500)); $lockExists = (yield exists("{$path}/key.lock")); } return new KeyPair((yield get("{$path}/private.pem")), (yield get("{$path}/public.pem"))); } $lock = new Lock("{$path}/key.lock"); try { $lock->acquire(); $gen = new OpenSSLKeyGenerator(); $keyPair = $gen->generate(4096); (yield put("{$path}/private.pem", $keyPair->getPrivate())); (yield put("{$path}/public.pem", $keyPair->getPublic())); return $keyPair; } catch (Exception $e) { do { (yield new Pause(500)); $lockExists = (yield exists("{$path}/key.lock")); } while ($lockExists); return new KeyPair((yield get("{$path}/private.pem")), (yield get("{$path}/public.pem"))); } finally { $lock->release(); unlink("{$path}/key.lock"); // do not yield in finally! } }
private function doProvideChallenge(string $dns, string $token, string $payload) { (yield put($this->configPath . "/challenges/{$dns}/.well-known/acme-challenge/{$token}", $payload)); }