Overview

Packages

  • None
  • Rpc

Classes

  • Horde_Rpc
  • Horde_Rpc_ActiveSync
  • Horde_Rpc_Exception
  • Horde_Rpc_Phpgw
  • Horde_Rpc_Soap
  • Horde_Rpc_Syncml
  • Horde_Rpc_Syncml_Wbxml
  • Horde_Rpc_Translation
  • Horde_Rpc_Webdav
  • Horde_Rpc_Webdav2
  • Horde_Rpc_Xmlrpc
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The Horde_Rpc:: class provides a set of server and client methods for
  4:  * RPC communication.
  5:  *
  6:  * TODO:
  7:  * - Introspection documentation and method signatures.
  8:  *
  9:  * EXAMPLE:
 10:  * <code>
 11:  * $response = Horde_Rpc::request('xmlrpc',
 12:  *                                'http://localhost:80/horde/rpc.php',
 13:  *                                'contacts.search',
 14:  *                                $transport_client,
 15:  *                                array(array('jan'), array('localsql'),
 16:  *                                      array('name', 'email')));
 17:  * </code>
 18:  *
 19:  * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
 20:  *
 21:  * See the enclosed file COPYING for license information (LGPL). If you
 22:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 23:  *
 24:  * @author  Jan Schneider <jan@horde.org>
 25:  * @package Rpc
 26:  */
 27: class Horde_Rpc
 28: {
 29:     /**
 30:      * All driver-specific parameters.
 31:      *
 32:      * @var array
 33:      */
 34:     var $_params = array();
 35: 
 36:     /**
 37:      * Do we need an authenticated user?
 38:      *
 39:      * @var boolean
 40:      */
 41:     var $_requireAuthorization = true;
 42: 
 43:     /**
 44:      * Whether we should exit if auth fails instead of requesting
 45:      * authorization credentials.
 46:      *
 47:      * @var boolean
 48:      */
 49:     var $_requestMissingAuthorization = true;
 50: 
 51:     /**
 52:      * Request variables, cookies etc...
 53:      *
 54:      * @var Horde_Controller_Request_Http
 55:      */
 56:     protected $_request;
 57: 
 58:     /**
 59:      * Logging
 60:      *
 61:      * @var Horde_Log_Logger
 62:      */
 63:     protected $_logger;
 64: 
 65:     /**
 66:      * RPC server constructor.
 67:      *
 68:      * @param Horde_Controller_Request_Http  The request object
 69:      *
 70:      * @param array $params  A hash containing any additional configuration or
 71:      *                       connection parameters a subclass might need.
 72:      *
 73:      * @return Horde_Rpc  An RPC server instance.
 74:      */
 75:     public function __construct($request, $params = array())
 76:     {
 77:         // Create a stub if we don't have a useable logger.
 78:         if (isset($params['logger'])
 79:             && is_callable(array($params['logger'], 'log'))) {
 80:             $this->_logger = $params['logger'];
 81:             unset($params['logger']);
 82:         } else {
 83:             $this->_logger = new Horde_Support_Stub;
 84:         }
 85: 
 86:         $this->_params = $params;
 87:         $this->_request = $request;
 88: 
 89:         if (isset($params['requireAuthorization'])) {
 90:             $this->_requireAuthorization = $params['requireAuthorization'];
 91:         }
 92:         if (isset($params['requestMissingAuthorization'])) {
 93:             $this->_requestMissingAuthorization = $params['requestMissingAuthorization'];
 94:         }
 95: 
 96:         $this->_logger->debug('Horde_Rpc::__construct complete');
 97:     }
 98: 
 99:     /**
100:      * Check authentication. Different backends may handle
101:      * authentication in different ways. The base class implementation
102:      * checks for HTTP Authentication against the Horde auth setup.
103:      *
104:      * @return boolean  Returns true if authentication is successful.
105:      *                  Should send appropriate "not authorized" headers
106:      *                  or other response codes/body if auth fails,
107:      *                  and take care of exiting.
108:      */
109:     function authorize()
110:     {
111:         $this->_logger->debug('Horde_Rpc::authorize() starting');
112:         if (!$this->_requireAuthorization) {
113:             return true;
114:         }
115: 
116:         // @TODO: inject this
117:         $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create();
118:         $serverVars = $this->_request->getServerVars();
119:         if (!empty($serverVars['PHP_AUTH_USER'])) {
120:             $user = $serverVars['PHP_AUTH_USER'];
121:             $pass = $serverVars['PHP_AUTH_PW'];
122:         } elseif (!empty($serverVars['Authorization'])) {
123:             $hash = str_replace('Basic ', '', $serverVars['Authorization']);
124:             $hash = base64_decode($hash);
125:             if (strpos($hash, ':') !== false) {
126:                 list($user, $pass) = explode(':', $hash, 2);
127:             }
128:         }
129: 
130:         if (!isset($user)
131:             || !$auth->authenticate($user, array('password' => $pass))) {
132:             if ($this->_requestMissingAuthorization) {
133:                 header('WWW-Authenticate: Basic realm="Horde RPC"');
134:             }
135:             header('HTTP/1.0 401 Unauthorized');
136:             echo '401 Unauthorized';
137:             exit;
138:         }
139: 
140:         $this->_logger->debug('Horde_Rpc::authorize() exiting');
141:         return true;
142:     }
143: 
144:     /**
145:      * Get the request body input. Different RPC backends can override
146:      * this to return an open stream to php://stdin, for instance -
147:      * whatever is easiest to handle in the getResponse() method.
148:      *
149:      * The base class implementation looks for $HTTP_RAW_POST_DATA and
150:      * returns that if it's available; otherwise, it returns the
151:      * contents of php://stdin.
152:      *
153:      * @return mixed  The input - a string (default), a filehandle, etc.
154:      */
155:     function getInput()
156:     {
157:         if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
158:             return $GLOBALS['HTTP_RAW_POST_DATA'];
159:         } else {
160:             return implode("\r\n", file('php://input'));
161:         }
162:     }
163: 
164:     /**
165:      * Sends an RPC request to the server and returns the result.
166:      *
167:      * @param string  The raw request string.
168:      *
169:      * @return string  The XML encoded response from the server.
170:      */
171:     function getResponse($request)
172:     {
173:         return 'not implemented';
174:     }
175: 
176:     /**
177:      * Returns the Content-Type of the response.
178:      *
179:      * @return string  The MIME Content-Type of the RPC response.
180:      */
181:     function getResponseContentType()
182:     {
183:         return 'text/xml';
184:     }
185: 
186:     /**
187:      * Send the output back to the client
188:      *
189:      * @param string $output  The output to send back to the client. Can be
190:      *                        overridden in classes if needed.
191:      *
192:      * @return void
193:      */
194:     function sendOutput($output)
195:     {
196:         header('Content-Type: ' . $this->getResponseContentType());
197:         header('Content-length: ' . strlen($output));
198:         header('Accept-Charset: UTF-8');
199:         echo $output;
200:     }
201: 
202:     /**
203:      * Builds an RPC request and sends it to the RPC server.
204:      *
205:      * This statically called method is actually the RPC client.
206:      *
207:      * @param string $driver         The protocol driver to use. Currently
208:      *                               'soap', 'xmlrpc' and 'jsonrpc' are
209:      *                               available.
210:      * @param string|Horde_Url $url  The path to the RPC server on the called
211:      *                               host.
212:      * @param string $method         The method to call.
213:      * @param mixed $client          An appropriate request client for the type
214:      *                               of request. (Horde_Http_Request, SoapClient
215:      *                               etc..)
216:      * @param array $params          A hash containing any necessary parameters
217:      *                               for the method call.
218:      *
219:      * @return mixed  The returned result from the method
220:      * @throws Horde_Rpc_Exception
221:      */
222:     public static function request($driver, $url, $method, $client, $params = null)
223:     {
224:         $driver = Horde_String::ucfirst(basename($driver));
225:         $class = 'Horde_Rpc_' . $driver;
226:         if (class_exists($class)) {
227:             return call_user_func(array($class, 'request'), $url, $method, $client, $params);
228:         } else {
229:             throw new Horde_Rpc_Exception('Class definition of ' . $class . ' not found.');
230:         }
231:     }
232: 
233:     /**
234:      * Attempts to return a concrete RPC server instance based on
235:      * $driver.
236:      *
237:      * @param mixed $driver  The type of concrete Horde_Rpc subclass to return.
238:      * @param array $params  A hash containing any additional configuration or
239:      *                       connection parameters a subclass might need.
240:      *
241:      * @return Horde_Rpc  The newly created concrete Horde_Rpc server instance,
242:      *                    or an exception if there is an error.
243:      */
244:     public static function factory($driver, $request, $params = null)
245:     {
246:         $driver = basename($driver);
247:         $class = 'Horde_Rpc_' . $driver;
248:         if (class_exists($class)) {
249:             return new $class($request, $params);
250:         } else {
251:             throw new Horde_Rpc_Exception('Class definition of ' . $class . ' not found.');
252:         }
253:     }
254: 
255: }
256: 
API documentation generated by ApiGen