From 158d477bd9ea2871a05ad2f5f36af27135859815 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 14 Dec 2021 21:10:15 -0800 Subject: [PATCH] Civi::pipe - Extract class JsonRpc --- Civi/Pipe/JsonRpc.php | 120 +++++++++++++++++++++++++++++++++++ Civi/Pipe/JsonRpcSession.php | 65 +++---------------- 2 files changed, 128 insertions(+), 57 deletions(-) create mode 100644 Civi/Pipe/JsonRpc.php diff --git a/Civi/Pipe/JsonRpc.php b/Civi/Pipe/JsonRpc.php new file mode 100644 index 0000000000..0712dea0d4 --- /dev/null +++ b/Civi/Pipe/JsonRpc.php @@ -0,0 +1,120 @@ + $request['id']] : []; + return [ + 'jsonrpc' => '2.0', + 'result' => $result, + ] + $id; + } + + /** + * Create a response object (unsuccessful). + * + * @link https://www.jsonrpc.org/specification#response_object + * @param array{jsonrpc: string, method: string, params: array, id: ?mixed} $request + * @param \Throwable $t + * The exception which caused the request to fail. + * @return array{jsonrpc: string, error: array, id: ?mixed} + */ + public static function createResponseError(array $request, \Throwable $t): array { + $isJsonErrorCode = $t->getCode() >= -32999 && $t->getCode() <= -32000; + $errorData = \CRM_Core_Config::singleton()->debug + ? ['class' => get_class($t), 'trace' => $t->getTraceAsString()] + : NULL; + $id = array_key_exists('id', $request) ? ['id' => $request['id']] : []; + return [ + 'jsonrpc' => $request['jsonrpc'] ?? '2.0', + 'error' => [ + 'code' => $isJsonErrorCode ? $t->getCode() : -32099, + 'message' => $t->getMessage(), + 'data' => $errorData, + ], + ] + $id; + } + +} diff --git a/Civi/Pipe/JsonRpcSession.php b/Civi/Pipe/JsonRpcSession.php index 15c665e731..681c8cfa2e 100644 --- a/Civi/Pipe/JsonRpcSession.php +++ b/Civi/Pipe/JsonRpcSession.php @@ -37,75 +37,26 @@ class JsonRpcSession { * @inheritDoc */ protected function onRequest(string $requestLine): ?string { - $request = \json_decode($requestLine, TRUE); - - if ($request === NULL) { - throw new \InvalidArgumentException('Parse error', -32700); - } - - if (!is_array($request)) { - throw new \InvalidArgumentException('Invalid Request', -32600); - } - - if (isset($request[0])) { - $response = array_map([$this, 'handleRequest'], $request); - } - else { - $response = $this->handleRequest($request); - } - - return \json_encode($response); - } - - protected function handleRequest($request): array { - try { - if ($request === NULL) { - throw new \InvalidArgumentException('Parse error', -32700); - } - if (($request['jsonrpc'] ?? '') !== '2.0') { - throw new \InvalidArgumentException('Invalid Request', -32600); - } - - $method = str_replace('.', '_', mb_strtolower($request['method'])); - if (!is_string($method) || !preg_match(self::METHOD_REGEX, $method)) { - throw new \InvalidArgumentException('Invalid Request', -32600); + return JsonRpc::run($requestLine, function($method, $params) { + $method = str_replace('.', '_', $method); + if (!preg_match(self::METHOD_REGEX, $method)) { + throw new \InvalidArgumentException('Method not found', -32601); } if (!is_callable([$this->methods, $method])) { throw new \InvalidArgumentException('Method not found', -32601); } - $result = call_user_func([$this->methods, $method], $this, $request['params'] ?? []); - $id = array_key_exists('id', $request) ? ['id' => $request['id']] : []; - return [ - 'jsonrpc' => '2.0', - 'result' => $result, - ] + $id; - } - catch (\Throwable $t) { - return $this->createJsonError($request, $t); - } + return call_user_func([$this->methods, $method], $this, $params); + }); } /** * @inheritDoc */ protected function onException(string $requestLine, \Throwable $t): ?string { - return \json_encode($this->createJsonError(['jsonrpc' => '2.0'], $t)); - } - - protected function createJsonError(array $request, \Throwable $t): array { - $isJsonErrorCode = $t->getCode() >= -32999 && $t->getCode() <= -32000; - $errorData = \CRM_Core_Config::singleton()->debug - ? ['class' => get_class($t), 'trace' => $t->getTraceAsString()] - : NULL; - return \CRM_Utils_Array::subset($request, ['jsonrpc', 'id']) + [ - 'error' => [ - 'code' => $isJsonErrorCode ? $t->getCode() : -32099, - 'message' => $t->getMessage(), - 'data' => $errorData, - ], - ]; + $error = JsonRpc::createResponseError([], $t); + return \json_encode($error); } } -- 2.25.1