summaryrefslogtreecommitdiff
path: root/framework/Web/Services/TRpcService.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Web/Services/TRpcService.php')
-rw-r--r--framework/Web/Services/TRpcService.php548
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