diff options
Diffstat (limited to 'framework/Web/Services/TRpcService.php')
-rw-r--r-- | framework/Web/Services/TRpcService.php | 548 |
1 files changed, 2 insertions, 546 deletions
diff --git a/framework/Web/Services/TRpcService.php b/framework/Web/Services/TRpcService.php index a4ed3d7c..26e7471d 100644 --- a/framework/Web/Services/TRpcService.php +++ b/framework/Web/Services/TRpcService.php @@ -1,5 +1,4 @@ <?php - /** * @author Robin J. Rogge <rrogge@bigpoint.net> * @link http://www.pradosoft.com/ @@ -10,6 +9,7 @@ * @package System.Web.Services */ + /** * TRpcService class * @@ -175,548 +175,4 @@ class TRpcService extends TService $_response->write($_result); } } -} - -/** - * TRpcServer class - * - * TRpcServer is a class - * - * TRpcServer is the base class used to creare a server to be used in conjunction with - * {@link TRpcService}. - * The role of TRpcServer is to be an intermediate, moving data between the service and - * the provider. This base class should suit the most common needs, but can be sublassed for - * logging and debugging purposes, or to filter and modify the request/response on the fly. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - **/ -class TRpcServer extends TModule -{ - /** - * @var TRpcProtocol instance - */ - protected $handler; - - /** - * Constructor - * @param TRpcProtocol $protocolHandler instance - */ - public function __construct(TRpcProtocol $protocolHandler) - { - $this->handler = $protocolHandler; - } - - /** - * Registers the method in the protocol handler - * @param string $methodName - * @param array $methodDetails - */ - public function addRpcMethod($methodName, $methodDetails) - { - $this->handler->addMethod($methodName, $methodDetails); - } - - /** - * Retrieves the request payload - * @return string request payload - */ - public function getPayload() - { - return file_get_contents('php://input'); - } - - /** - * Passes the request payload to the protocol handler and returns the result - * @return string rpc response - */ - public function processRequest() - { - try - { - return $this->handler->callMethod($this->getPayload()); - } - catch(TRpcException $e) - { - return $this->handler->createErrorResponse($e); - } - } -} - -/** - * TRpcException class - * - * A TRpcException represents a RPC fault i.e. an error that is caused by the input data - * sent from the client. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - */ -class TRpcException extends TException -{ - public function __construct($message, $errorCode = -1) - { - $this->setErrorCode($errorCode); - - parent::__construct($message); - } -} - -/** - * TRpcApiProvider class - * - * TRpcApiProvider is an abstract class the can be subclasses in order to implement an - * api for a {@link TRpcService}. A subclass of TRpcApiProvider must implement the - * {@link registerMethods} method in order to declare the available methods, their - * names and the associated callback. - * - * <code> - * public function registerMethods() - * { - * return array( - * 'apiMethodName1' => array('method' => array($this, 'objectMethodName1')), - * 'apiMethodName2' => array('method' => array('ClassName', 'staticMethodName')), - * ); - * } - * </code> - * - * In this example, two api method have been defined. The first refers to an object - * method that must be implemented in the same class, the second to a static method - * implemented in a 'ClassName' class. - * In both cases, the method implementation will receive the request parameters as its - * method parameters. Since the number of received parameters depends on - * external-supplied data, it's adviced to use php's func_get_args() funtion to - * validate them. - * - * Providers must be registered in the service configuration in order to be available, - * as explained in {@link TRpcService}'s documentation. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - */ -abstract class TRpcApiProvider extends TModule -{ - /** - * @var TRpcServer instance - */ - protected $rpcServer; - - /** - * Must return an array of the available methods - * @abstract - */ - abstract public function registerMethods(); - - /** - * Constructor: informs the rpc server of the registered methods - */ - public function __construct(TRpcServer $rpcServer) - { - $this->rpcServer = $rpcServer; - - foreach($this->registerMethods() as $_methodName => $_methodDetails) - $this->rpcServer->addRpcMethod($_methodName, $_methodDetails); - } - - /** - * Processes the request using the server - * @return processed request - */ - public function processRequest() - { - return $this->rpcServer->processRequest(); - } - - /** - * @return rpc server instance - */ - public function getRpcServer() - { - return $this->rpcServer; - } -} - -/** - * TRpcProtocol class - * - * TRpcProtocol is the base class used to implement a protocol in a {@link TRpcService}. - * Prado already implements two protocols: {@link TXmlRpcProtocol} for Xml-Rpc request - * and {@link TJsonRpcProtocol} for JSON-Rpc requests. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - **/ -abstract class TRpcProtocol -{ - /** - * @var array containing the mapping from RPC method names to the actual handlers - */ - protected $rpcMethods = array(); - - // abstracts - - /** - * @param string request payload - * Processed the request ans returns the response, if any - * @return processed response - * @abstract - */ - abstract public function callMethod($requestPayload); - /** - * @param TRpcException the exception with error details - * Creates a proper response for an error condition - * @return a response representing the error - * @abstract - */ - abstract public function createErrorResponse(TRpcException $exception); - /** - * @param response - * Sets the needed headers for the response (eg: content-type, charset) - * @abstract - */ - abstract public function createResponseHeaders($response); - /** - * Encodes the response - * @param mixed reponse data - * @return string encoded response - * @abstract - */ - abstract public function encode($data); - /** - * Decodes the request payload - * @param string request payload - * @return mixed decoded request - * @abstract - */ - abstract public function decode($data); - - // methods - - /** - * Registers a new RPC method and handler details - * @param string $methodName - * @param array $handlerDetails containing the callback handler - */ - public function addMethod($methodName, $handlerDetails) - { - $this->rpcMethods[$methodName] = $handlerDetails; - } - - /** - * Calls the callback handler for the given method - * @param string $methodName of the RPC - * @param array $parameters for the callback handler as provided by the client - * @return mixed whatever the callback handler returns - */ - public function callApiMethod($methodName, $parameters) - { - if(!isset($this->rpcMethods[$methodName])) - throw new TRpcException('Method "'.$methodName.'" not found'); - - if($parameters === null) - $parameters = array(); - - if(!is_array($parameters)) - $parameters = array($parameters); - return call_user_func_array($this->rpcMethods[$methodName]['method'], $parameters); - } -} - -/** - * TJsonRpcProtocol class - * - * TJsonRpcProtocol is a class that implements JSON-Rpc protocol in {@link TRpcService}. - * Both version 1.0 and 2.0 of the specification are implemented, and the server will try - * to answer using the same version of the protocol used by the requesting client. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @author Fabio Bas <ctrlaltca@gmail.com> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - */ -class TJsonRpcProtocol extends TRpcProtocol -{ - protected $_id=null; - protected $_specificationVersion=1.0; - - /** - * Handles the RPC request - * @param string $requestPayload - * @return string JSON RPC response - */ - public function callMethod($requestPayload) - { - try - { - $_request = $this->decode($requestPayload); - - if(isset($_request['jsonrpc'])) - { - $this->_specificationVersion=$_request['jsonrpc']; - if($this->_specificationVersion > 2.0) - throw new TRpcException('Unsupported specification version', '-32600'); - } - - if(isset($_request['id'])) - $this->_id=$_request['id']; - - if(!isset($_request['method'])) - throw new TRpcException('Missing request method', '-32600'); - - if(!isset($_request['params'])) - $parameters = array(); - else - $parameters = $_request['params']; - - if(!is_array($parameters)) - $parameters = array($parameters); - - // a request without an id is a notification that doesn't need a response - if($this->_id !== null) - { - if($this->_specificationVersion==2.0) - { - return $this->encode(array( - 'jsonrpc' => '2.0', - 'id' => $this->_id, - 'result' => $this->callApiMethod($_request['method'], $parameters), - )); - } else { - return $this->encode(array( - 'id' => $this->_id, - 'result' => $this->callApiMethod($_request['method'], $_request['params']), - 'error' => null - )); - } - } - } - catch(TRpcException $e) - { - return $this->createErrorResponse($e); - } - catch(THttpException $e) - { - throw $e; - } - catch(Exception $e) - { - return $this->createErrorResponse(new TRpcException('An internal error occured', '-32603')); - } - } - - /** - * Turns the given exception into an JSON RPC fault - * @param TRpcException $exception - * @return string JSON RPC fault - */ - public function createErrorResponse(TRpcException $exception) - { - if($this->_specificationVersion==2.0) - { - return $this->encode(array( - 'id' => $this->_id, - 'result' => null, - 'error'=> array( - 'code' => $exception->getCode(), - 'message'=> $exception->getMessage(), - 'data' => null, - ) - )); - } else { - return $this->encode(array( - 'id' => $this->_id, - 'error'=> array( - 'code' => $exception->getCode(), - 'message'=> $exception->getMessage(), - 'data' => null, - ) - )); - } - } - - /** - * Sets the correct response headers - * @param THttpResponse $response - */ - public function createResponseHeaders($response) - { - $response->setContentType('application/json'); - $response->setCharset('UTF-8'); - } - - /** - * Decodes JSON encoded data into PHP data - * @param string $data in JSON format - * @return array PHP data - */ - public function decode($data) - { - $s = json_decode($data, true); - self::checkJsonError(); - return $s; - } - - /** - * Encodes PHP data into JSON data - * @param mixed PHP data - * @return string JSON encoded PHP data - */ - public function encode($data) - { - $s = json_encode($data); - self::checkJsonError(); - return $s; - } - - private static function checkJsonError() - { - $errnum = json_last_error(); - if($errnum != JSON_ERROR_NONE) - throw new Exception("JSON error: $msg", $err); - } - - /** - * Calls the callback handler for the given method - * Overrides parent implementation to correctly handle error codes - * @param string $methodName of the RPC - * @param array $parameters for the callback handler as provided by the client - * @return mixed whatever the callback handler returns - */ - public function callApiMethod($methodName, $parameters) - { - if(!isset($this->rpcMethods[$methodName])) - throw new TRpcException('Method "'.$methodName.'" not found', '-32601'); - - return call_user_func_array($this->rpcMethods[$methodName]['method'], $parameters); - } -} - -/** - * TXmlRpcProtocol class - * - * TXmlRpcProtocol is a class that implements XML-Rpc protocol in {@link TRpcService}. - * It's basically a wrapper to the xmlrpc_server_* family of php methods. - * - * @author Robin J. Rogge <rrogge@bigpoint.net> - * @version $Id$ - * @package System.Web.Services - * @since 3.2 - */ -class TXmlRpcProtocol extends TRpcProtocol -{ - /** - * @var XML RPC server resource - */ - private $_xmlrpcServer; - - // magics - - /** - * Constructor - */ - public function __construct() - { - $this->_xmlrpcServer = xmlrpc_server_create(); - } - - /** - * Destructor - */ - public function __destruct() - { - xmlrpc_server_destroy($this->_xmlrpcServer); - } - - // methods - - /** - * Registers a new RPC method and handler details - * @param string $methodName - * @param array $handlerDetails containing the callback handler - */ - public function addMethod($methodName, $methodDetails) - { - parent::addMethod($methodName, $methodDetails); - - xmlrpc_server_register_method($this->_xmlrpcServer, $methodName, array($this, 'callApiMethod')); - } - - // methods - - /** - * Handles the RPC request - * @param string $requestPayload - * @return string XML RPC response - */ - public function callMethod($requestPayload) - { - try - { - return xmlrpc_server_call_method($this->_xmlrpcServer, $requestPayload, null); - } - catch(TRpcException $e) - { - return $this->createErrorResponse($e); - } - catch(THttpException $e) - { - throw $e; - } - catch(Exception $e) - { - return $this->createErrorResponse(new TRpcException('An internal error occured')); - } - } - - /** - * Turns the given exception into an XML RPC fault - * @param TRpcException $exception - * @return string XML RPC fault - */ - public function createErrorResponse(TRpcException $exception) - { - return $this->encode(array( - 'faultCode' => $exception->getCode(), - 'faultString' => $exception->getMessage() - )); - } - - /** - * Sets the correct response headers - * @param THttpResponse $response - */ - public function createResponseHeaders($response) - { - $response->setContentType('text/xml'); - $response->setCharset('UTF-8'); - } - - /** - * Decodes XML encoded data into PHP data - * @param string $data in XML format - * @return array PHP data - */ - public function decode($data) - { - return xmlrpc_decode($data); - } - - /** - * Encodes PHP data into XML data - * @param mixed PHP data - * @return string XML encoded PHP data - */ - public function encode($data) - { - return xmlrpc_encode($data); - } -} +}
\ No newline at end of file |